예제 #1
0
 def process_updates(self, upd_eval):
     cond = True
     while cond:
         updates = self._get_updates()
         logger.info("Updates: %d", len(updates))
         TelegramApi.process_updates_list(updates, upd_eval)
         cond = len(updates) > 0
예제 #2
0
    def save_to_database(self):
        if not super().save_to_database():
            logger.error("Error saving to database.")
            return False

        C = WordMatchResponse

        cols = [C.COL_ID]
        cols.extend(C.COLS)

        s = Database.insert_str(C.TABLE, cols, [self.Id, int(self.Mode)])

        for word in self.Matchwords:
            logger.info(word)
            s += '; ' + Database.insert_str(C.WORDS_TABLE, C.WORD_COLS,
                                            [word, self.Id])

        for resp in self.Responses:
            s += '; ' + Database.insert_str(
                C.RESPONSES_TABLE, C.RESP_COLS,
                [resp['response'], self.Id, resp['type']])

        logger.info(s)
        success = Database.query_bool(s)
        if not success:
            logger.error("Error saving to database.")
            return False

        return True
예제 #3
0
    def _get_updates(self):
        req = self.url + 'getUpdates' + (
            ('?offset=' + str(self._offset)) if self._offset != 0 else '')

        response = requests.get(req).json()

        ok = bool(response.get('ok', True))

        updates = []

        if not ok:
            logger.error("Cannot get updates: %s",
                         response.get('description', 'No reason'))
            return updates

        updates_json = response.get('result')

        updates = self._parse_updates(
            updates_json)  # type: list[TelegramApi.Update]

        for upd in updates:
            if upd.Id >= self._offset:
                self._offset = upd.Id + 1
        logger.info("Current offset: {}\n".format(self._offset))
        return updates
예제 #4
0
    def increment_match_counter(self):
        self.MatchCounter += 1
        q = "UPDATE  " + Command.TABLE + " SET " + Command.COL_MATCH_COUNT + " = " + Command.COL_MATCH_COUNT \
            + " + 1 WHERE " + Command.COL_ID + " = " + str(self.Id)

        logger.info("Increment query: " + q)
        if not Database.query_bool(q):
            logger.error("Error incrementing match counter.")
예제 #5
0
    def set_webhook(self):
        url = 'https://' + self.app_name + '.herokuapp.com/' + self.api_key

        logger.info('Setting webhook: ' + url)

        params = {'url': url}
        response = requests.post(self.url + 'setWebhook', data=params)

        logger.info("Webhook reponse: %s", response.text)
예제 #6
0
 def send_message(self, chat, text, reply_to_id=0):
     params = {'chat_id': chat, 'text': text}
     if reply_to_id != 0:
         params['reply_to_message_id'] = reply_to_id
     response = requests.post(self.url + 'sendMessage', data=params)
     logger.info('Send_mess response: %s', response.text)
     if response.status_code != requests.codes.ok:
         logger.info('Status code: %s', response.status_code)
     return response
예제 #7
0
def webhook():
    logger.info('Received webhook')
    if request.method == 'POST' and request.is_json:
        j = request.get_json(silent=True)

        if j is None:
            logger.error('request.get_json() returned None')
            return '', 400

        telegram.process_update_json(j, evaluate_update)
        return '', 200
    else:
        logger.warning('Received non-json request: ' + request.data)
        return '', 400
예제 #8
0
    def send_media(self, chat, type: str, file_id: str, reply_to_id=0):
        params = {'chat_id': chat, type: file_id}
        if reply_to_id != 0:
            params['reply_to_message_id'] = reply_to_id

        if type == "sticker":
            cmd = "sendSticker"
        elif type == "photo":
            cmd = "sendPhoto"
        elif type == "animation":
            cmd = "sendAnimation"
        else:
            logger.error("send_media: Unknown media type:", type)
            return

        response = requests.post(self.url + cmd, data=params)
        logger.info('Send_media response: %s', response.text)
        if response.status_code != requests.codes.ok:
            logger.info('Status code: %s', response.status_code)
        return response
예제 #9
0
def handle_command_str(msg: TelegramApi.Message, telegram: TelegramApi):
    sender_id = get_user_chat_id(msg)
    if sender_id in active_commands:
        active_commands[sender_id]['func'](msg, telegram)
        return True
    elif is_command(msg):
        txt = msg.Text.lstrip()
        logger.info("Handling command: " + txt)

        for cmd in commands:
            m = cmd['cmdregex'].match(txt)
            if m is not None:
                txt = txt[m.end('cmd'):]
                logger.debug("Command identified: " + cmd['cmdname'])
                cmd['exec_func'](cmd['cmdname'],
                                 cmd['parse_func'](txt.splitlines()), msg,
                                 telegram)
                return True

    return False
예제 #10
0
    def save_to_database(self):
        if not super().save_to_database():
            return False

        C = WordMatchResponse

        cols = [C.COL_ID]
        cols.extend(C.COLS)

        s = Database.insert_str(C.TABLE, cols, [self.Id, int(self.Mode)])

        for word in self.Matchwords:
            s += '; ' + Database.insert_str(C.WORDS_TABLE, C.WORD_COLS,
                                            [word, self.Id])

        for resp in self.Responses:
            s += '; ' + Database.insert_str(C.RESPONSES_TABLE, C.RESP_COLS,
                                            [resp, self.Id])

        logger.info(s)
        return Database.query_bool(s)
예제 #11
0
 def query(q: str):
     params = {
         Constants.KEY_SQL_PSK: Constants.API_KEY,
         Constants.KEY_SQL_QUERY: q
     }
     logger.info("Querying data from database...")
     logger.debug("Query: " + q)
     r = requests.post(dburl, json=params)
     try:
         js = r.json()
         if Constants.KEY_SQL_SUCCESS not in js:
             logger.error('SQL query didn\'t return correct json')
             return {Constants.KEY_SQL_SUCCESS: False}
         else:
             logger.info("Done.")
             logger.debug(str(js))
             return js
     except ValueError:
         logger.error("Error reading response from server. Response: " +
                      r.text)
         return {Constants.KEY_SQL_SUCCESS: False}
예제 #12
0
def evaluate(telegram: TelegramApi, update: TelegramApi.Update):
    if not update.has_message():
        logger.warning('Eval: Update with no message')
        return

    msg = update.Message

    chat_found = False
    for chat in chats:
        if chat.Id == msg.Chat.Id:
            chat_found = True
            break

    if not chat_found:
        c = Chat.from_message(msg)
        chats.append(c)
        c.save_to_database()

    logger.info("Received message: " + msg.Text)
    text = msg.Text.replace('\n', ' ').replace('\r', '')  # type: str
    cmd = parse_command(text)

    if cmd.Found:
        if cmd.Op.Result:
            logger.info('Received command:' + text)

            if exec_command(cmd, msg, telegram):
                return

        else:
            logger.info('Command contains errors:' + text + " -- " + cmd.Op.Text + "(" + str(cmd.Op.Index) + ")")
            telegram.send_message(msg.Chat.Id, "Errore: " + cmd.Op.Text + ". Posizione: " + str(cmd.Op.Index))
            return

    if msg.Chat.Id == my_chat_id and echo_to_id != 0:
        telegram.send_message(echo_to_id, msg.Text)
    else:
        logger.debug("Iterating answers (%d):", len(WordMatchResponse.List))
        for response in WordMatchResponse.List:
            if response.matches(msg.Text):
                logger.debug('Matched: %s', response.Matchwords[0])
                response.reply(msg, telegram)
예제 #13
0
        chats.append(c)
        c.save_to_database()

    handled = handle_command_str(msg, telegram)

    if not handled:
        logger.debug("Not a command: " + msg.Text)
        # send eventual messages
        for response in WordMatchResponse.List:  # type: WordMatchResponse
            if response.matches(msg.Text):
                notify_new_match(response.Id, msg.Chat.Id)
                response.reply(msg, telegram)
                response.increment_match_counter()


print("Running")
WordMatchResponse.load_list_from_database()
logger.info("Data loaded from database.")

# Start the web app (only if on remote server)
if __name__ == "__main__":
    telegram.set_webhook()

    print("Binding to port")
    port = int(os.environ.get('PORT', 5000))
    app.run(host='0.0.0.0', port=port)




예제 #14
0
    def load_list_from_database():
        C = WordMatchResponse
        C.List = []

        # Load commands
        cols = [Command.COL_ID]
        cols.extend(Command.COLS)
        cols.extend(C.COLS)
        cols.extend(User.COLS)
        cols.extend(Chat.COLS)

        tables = [C.TABLE, Command.TABLE, User.TABLE, Chat.TABLE]
        equals = [(C.COL_ID, Command.COL_ID),
                  (User.COL_ID, Command.COL_USER_ID),
                  (Chat.COL_ID, Command.COL_CHAT_ID),
                  (Command.COL_BOT_NAME, '\'' + Constants.APP_NAME + '\'')]

        query = Database.select_str(cols, tables, equals)

        # Load match words
        cols = C.WORD_COLS

        tables = [C.WORDS_TABLE, Command.TABLE]
        equals = [(C.WORDS_COL_CMD_ID, Command.COL_ID),
                  (Command.COL_BOT_NAME, '\'' + Constants.APP_NAME + '\'')]

        query += ";" + Database.select_str(cols, tables, equals)

        # Load Responses
        cols = C.RESP_COLS

        tables = [C.RESPONSES_TABLE, Command.TABLE]
        equals = [(C.RESPONSES_COL_CMD_ID, Command.COL_ID),
                  (Command.COL_BOT_NAME, '\'' + Constants.APP_NAME + '\'')]

        query += ";" + Database.select_str(cols, tables, equals)

        query_result = Database.query(query)  #type: dict

        s1, rows_cmds = Database.get_rows(query_result, 0)
        s2, rows_words = Database.get_rows(query_result, 1)
        s3, rows_resps = Database.get_rows(query_result, 2)

        if not (s1 and s2 and s3):
            logger.error("Error loading data from database:")
            logger.error(str(query_result))
            return False
        cnt = 0
        for cmd in rows_cmds:
            cmdid = cmd[Command.COL_ID]
            words = [w for w in rows_words if w[C.WORDS_COL_CMD_ID] == cmdid]
            resps = [
                r for r in rows_resps if r[C.RESPONSES_COL_CMD_ID] == cmdid
            ]

            command = WordMatchResponse.from_database(cmd, words, resps)
            if command is not None:
                C.List.append(command)
                cnt += 1

        logger.info("Loaded {} commands from database.".format(cnt))
        return True