Как стать автором
Обновить

Комментарии 3

def take_position(id_user):
    connection = get_connection()
    try:
        with connection.cursor() as cursor:
            sql = "SELECT position FROM user WHERE iduser = %s"
            cursor.execute(sql, (id_user))
            line = cursor.fetchone()
            if line is None:
                return_count = 0
            else:
                return_count = line["position"]
    finally:
        connection.close()
    return return_count

Тут есть одна проблема. Что если достать данные не получится? Тогда return_count будет не объявлен, на последней строчке код ляжет.

Также if line is None: ... else: ... можно заменить на return_count = line.get("position", 0)

Честно говоря, не понятен выбор в сторону threads, ведь есть асинхронность.

Функция processing_message сильно перегружена. И как быть, если функционал (количество состояний) будет расти? К тому же в таком коде легко будет допустить ошибку (как минимум, из-за того, что состояние выражается через числа).

Ещё мне не понять, почему часть данных находятся в коде (цитаты), а keyboard layout в отдельном файле? К тому же что будет, если вдруг ошибиться в имени файла? (опять ошибка в рантайме)

Желательно бы вообще вынести все credentials (данные от БД, VK API token...) в константы, а ещё лучше вообще вынести их из кода.

Также есть вопрос по поводу обработки сообщений. Почему мы обрабатываем текст таким образом: if message_text == "Цитаты Дурова":, хотя есть payload для клавиатур? И что если вдруг текст на кнопках будет одинаков?

А что если вашим ботом будут пользоваться много людей, придётся очень часто отправлять сообщения, но надо помнить, что у VK API есть лимиты на отправку сообщений (борьба со спамом). Также могут произойти всякие проблемы в сети, надо сделать повторную отправку сообщения. Но её нет. (Кстати, вы сначала обновляете состояние, а только потом отправляете сообщение. Что если сообщение не отправится, но состояние обновится?)

Верные замечания, НО здесь базовый код, я не хотел его перегружать проверками.
Я хотел написать статью по максимально простому пути, чтобы был понятен именно принцип.
По поводу асинхронности и longpoll - если только aiovk, но даже если объяснять её - то нужно будет объяснить принцип асинхронности изначально. Я не делал такие проекты с этой библиотекой.
Credentials я не вынес только чтобы не создавать отдельный файл ради трех строк. Так, естественно, правильное замечание.
По поводу сообщений - в статье я упростил код, но в моих проектах всё стоит в цикле. Я стоплю на полсекунды отправку после ошибки и потом повторяю опять:

def send_message(id_user, id_keyboard, message_text):
    for i in range(0, 3):
        try:
            vk.messages.send(
                user_id=id_user,
                random_id=get_random_id(),
                keyboard=open(id_keyboard, 'r', encoding='UTF-8').read(),
                message=message_text)
        except:
            print("Ошибка отправки сообщения у id" + str(id_user))
            time.sleep(0.5)
            continue
        break

Если текст на кнопках будет одинаков, то позиция будет разная.
А про обновление состояния - даже если сообщение не сработает, то повторное сообщение выведет "Непонятная команда" и выведет правильную клавиатуру.
Ах да, я сделал это с мыслью что если пользователь успеет кликнуть на сообщение на новой клавиатуре, а позиция ещё не обновится к этому моменту - будет ошибка.

P.S. Все статьи, которые я читал на хабре с этой темой - нигде так не штудировали код в комментах =)

Худшее решение, которое можно придумать. Зачем использовать vk_api и многопоточность, катода есть асинхронный vkbottle?

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории