Пример #1
0
def _remove_subscriber(id):

    '''
    Performs the write operation for removing a subscriber.
    TODO: add error handling for when user is not in the list of subscribers

    @param id: stringified unique user id as provided by telegram
    '''

    subscribers = commons.get_data("subscribers")
    commons.log(LOG_TAG, "removing subscriber: " + subscribers[id] + "[" + id + "]")
    del subscribers[id]
    commons.set_data("subscribers", subscribers)
Пример #2
0
def _new_subscriber(id, name):

    '''
    Performs the write operation for adding a subscriber.

    @param id: stringified unique user id as provided by telegram
    @param name: string to identify the user; can be first name, username or
        group chat name
    '''

    subscribers = commons.get_data("subscribers")
    subscribers[id] = name
    commons.set_data("subscribers", subscribers)
    commons.log(LOG_TAG, "new subscriber: " + name + "[" + id + "]")
Пример #3
0
    async def on_chat_message(self, message):

        '''
        Async method to delegate command calls to their respective methods.
        Ignores messages that do not start with '/'. Sends non-admins a blocking
        'maintenance mode' message when maintenance mode is on.

        @param message: dictionary containing information about the message
            received from user; see https://core.telegram.org/bots/api#message
            for more information
        '''

        if("text" not in message): return
        command, _, payload = message['text'][1:].partition(" ")
        command = command.split("@")[0]

        chat = await self.administrator.getChat()
        self._log("chat: " + message['text'], chat)
        is_admin = chat['id'] in commons.get_data("admins")

        maintenance_mode = commons.get_data("status") == "maintenance"
        if maintenance_mode and not is_admin:
            await self.sender.sendMessage(MAINTENANCE_MODE_MESSAGE)
        elif message['text'].startswith("/"):

            try:
                command_call = getattr(self, "_" + command)
                await command_call(is_admin, payload)

                # increment command stats count
                stats = commons.get_data("stats")
                stats[command] = (0 if command not in stats else int(stats[command])) + 1
                commons.set_data("stats", stats)

            except Exception as e:
                print(e)
                await self.sender.sendMessage(INVALID_COMMAND_MESSAGE)
Пример #4
0
    async def _broadcast(self, is_admin, payload):

        '''
        Async method to handle /broadcast calls from administrators. Sends a
        broadcasted message to all subscribers.

        @param is_admin: boolean to determine if user is admin
        @param payload: required string that follows the user's command
        '''

        if payload and is_admin:
            for subscriber_id in commons.get_data("subscribers").keys():
                await self.bot.sendMessage(int(subscriber_id), payload)
        else:
            raise ValueError("unauthorised")
Пример #5
0
async def on_tweet(data):
    '''
    Function to be called when a new tweet is sent.

    @param data: a dictionary containing information about the tweet; see
        https://dev.twitter.com/overview/api/tweets for more information
    '''

    # increment tweet stat count
    stats = commons.get_data("stats")
    stats["tweets"] = (0
                       if "tweets" not in stats else int(stats["tweets"])) + 1
    commons.set_data("stats", stats)

    # send tweet to all subscribers
    tweet_message = "<b>" + data['user']['screen_name'] + "</b>: " + data[
        'text']
    subscribers = commons.get_data("subscribers")
    commons.log(LOG_TAG,
                "sending tweet to " + str(len(subscribers)) + " subscribers")
    for subscriber_id in subscribers.keys():
        await bot_delegator.sendMessage(int(subscriber_id),
                                        tweet_message,
                                        parse_mode='HTML')
Пример #6
0
    async def _start(self, is_admin, payload = None):

        '''
        Async method to handle /start calls. Sends the current status of the
        bot if user is an admin, otherwise, sends the normal welcome message
        unless the admin passes the payload 'force'

        @param is_admin: boolean to determine if user is admin
        @param payload: optional string that follows the user's command
        '''

        if is_admin and payload != "force":
            await self.sender.sendMessage("Hi Admin!\nCurrent Status: " + commons.get_data("status"))
        else:
            await self.sender.sendMessage(START_MESSAGE, parse_mode = 'HTML', disable_web_page_preview = True)
            await self._subscribe(is_admin)
Пример #7
0
    async def _subscribers(self, is_admin, payload = None):

        '''
        Async method to handle /subscribers calls from administrators. Returns
        list of subscribers by their either their first name, username or group
        chat name.

        @param is_admin: boolean to determine if user is admin
        @param payload: optional string that follows the user's command
        '''

        if is_admin:
            subscribers = commons.get_data("subscribers")
            message = "NTU_CampusBot Subscribers:\n" + ("=" * 25) + "\n\n"
            message += "\n".join(subscribers.values())
            await self.sender.sendMessage(message)
        else:
            raise ValueError("unauthorised")
Пример #8
0
    async def _stats(self, is_admin, payload = None):

        '''
        Async method to handle /stats calls from administrators. Sends a
        statistical count of the number of times commands were called and the
        number of times tweets were sent.

        @param is_admin: boolean to determine if user is admin
        @param payload: optional string that follows the user's command
        '''

        if is_admin:
            statistics = commons.get_data("stats")
            message = "NTU_CampusBot Statistics:\n" + ("=" * 25) + "\n\n"
            message += "\n".join([key + ": " + str(statistics[key]) for key in statistics.keys()])
            await self.sender.sendMessage(message)
        else:
            raise ValueError("unauthorised")
Пример #9
0
    async def _unsubscribe(self, is_admin, payload = None):

        '''
        Async method to handle /unsubscribe calls. Removes user from list of
        subscribers. Returns a success message if user successfully unregisters
        and an error message if user fails to unsubscribe, that is, when user is
        not even subscribed.

        @param is_admin: boolean to determine if user is admin
        @param payload: optional string that follows the user's command
        '''

        chat = await self.administrator.getChat()
        chat_id = str(chat['id'])

        if chat_id in commons.get_data("subscribers"):
            _remove_subscriber(chat_id)
            await self.sender.sendMessage(SUCCESSFULLY_UNSUBSCRIBED)
        else:
            await self.sender.sendMessage(NOT_SUBSCRIBED_MESSAGE)
Пример #10
0
    async def _subscribe(self, is_admin, payload = None):

        '''
        Async method to handle /subscribe calls. Adds user to list of
        subscribers. Returns a success message if user successfully registers
        and an error message if user fails to subscribe, that is, when user is
        already subscribed.

        @param is_admin: boolean to determine if user is admin
        @param payload: optional string that follows the user's command
        '''

        chat = await self.administrator.getChat()
        chat_id = str(chat['id'])

        if chat_id not in commons.get_data("subscribers"):
            sender = chat['title' if 'title' in chat else ('username' if 'username' in chat else 'first_name')]
            _new_subscriber(chat_id, sender)
            await self.sender.sendMessage(SUCCESSFULLY_SUBSCRIBED)
        else:
            await self.sender.sendMessage(ALREADY_SUBSCRIBED_MESSAGE)
Пример #11
0
    async def _maintenance(self, is_admin, payload = None):

        '''
        Async method to handle /maintenance calls from administrators. Toggles
        maintenance mode on/off. Toggling it on disables standard users from
        using the bot. Passing 'on'/'off' as payload specifies the mode to be
        switched into.

        @param is_admin: boolean to determine if user is admin
        @param payload: optional string that follows the user's command
        '''

        if is_admin and ((payload.lower() in ["on", "off"]) if payload else True):

            flip_current = "maintenance" if commons.get_data("status") == "running" else "running"
            new_status = "maintenance" if payload == "on" else ("off" if payload == "off" else flip_current)
            commons.set_data("status", new_status)

            message = "Maintenance Mode: " + ("on" if new_status == "maintenance" else "off")
            await self.sender.sendMessage(message)

        else:
            raise ValueError("unauthorised")