python273 / vk_api

Модуль для создания скриптов для ВКонтакте | vk.com API wrapper
https://pypi.org/project/vk-api/
Apache License 2.0
1.33k stars 321 forks source link

Замена event'a из longpoll на более удобный, который можно получить через вызов метода #366

Open Raportuy opened 4 years ago

Raportuy commented 4 years ago

Для удобства использую следующий класс:

class DotDict(dict):
    __setattr__ = dict.__setitem__
    __getattr__ = dict.__getitem__
    __delattr__ = dict.__delitem__

Обычный longpoll (страничный)

print(DotDict(event.__dict__))
{
    "raw":
    [
        4,
        2499476,
        2629633,
        2000000078,
        1594302923,
        "123",
        {
            "from": "174353919",
            "mentions": [86245063],
            "marked_users": [[1, [86245063]]]
        },
        {
            "reply": "{'conversation_message_id':619466}",
            "fwd": "0_0"
        }, 0
    ],
    "from_user": false,
    "from_chat": true,
    "from_group": false,
    "from_me": false,
    "to_me": true,
    "attachments":
    {
        "reply": "{'conversation_message_id':619466}",
        "fwd": "0_0"
    },
    "message_data": "None",
    "message_id": 2499476,
    "timestamp": 1594302923,
    "peer_id": 2000000078,
    "flags": 2629633,
    "extra": "None",
    "extra_values":
    {
        "from": "174353919",
        "mentions": [86245063],
        "marked_users": [[1, [86245063]]]
    },
    "type_id": "None",
    "type": "<VkEventType.MESSAGE_NEW: 4>",
    "text": "123",
    "random_id": 0,
    "from": "174353919",
    "mentions": [86245063],
    "marked_users": [[1, [86245063]]],
    "chat_id": 78,
    "user_id": 174353919,
    "message_flags": {"<VkMessageFlag.UNREAD: 1>"},
    "message": "облако хуйня для меня",
    "datetime": "datetime.datetime(2020, 7, 9, 13, 55, 23)"
}

botlongpoll

print(DotDict(event.obj.message))
{
    "date": 1594303243,
    "from_id": 499950380,
    "id": 0,
    "out": 0,
    "peer_id": 2000000001,
    "text": "123",
    "conversation_message_id": 12778,
    "fwd_messages": [],
    "important": false,
    "random_id": 0,
    "attachments": [],
    "is_hidden": false
}

Как можно увидеть страничный longpoll совсем неудобный и несёт в себе кучу ненужного, кроме того, если прилетает какое-нибудь вложение будь то фотография например:

{
    "attach1_type": "photo",
    "attach1": "574410456_457239048"
}

с этим совсем ничего нельзя сделать, даже получить доп информацию этой фотографии через метод photos.getById, ибо кидает ошибку доступа. Но если вызвать метод messages.getById

vk_session = vk_api.VkApi(login="", password="", app_id=2685278)
long_poll = VkLongPoll(vk_session)
vk_client = vk_session.get_api()
for event in long_poll.listen():
    if event.type == VkEventType.MESSAGE_NEW:
        event = DotDict(vk_client.messages.getById(message_ids=event.message_id)["items"][0])
        print(event)

Вывод будет как у группы, удобный вывод.

{
    "date": 1594303331,
    "from_id": 86245063,
    "id": 2499545,
    "out": 0,
    "peer_id": 2000000078,
    "text": "каждые выходные",
    "conversation_message_id": 619531,
    "fwd_messages": [],
    "important": false,
    "random_id": 0,
    "attachments": [],
    "is_hidden": false
}

Предлагаю заменить event тот что прилетает от вконтакте на тот что получаем через вызов метода. После замены можно делать вот так:

# если личное сообщение (не беседа) - пропускаем
if event.from_id == event.peer_id:

или

# если есть прикреплённые файлы/документ и т.д.
if event.attachments:
    # подсчёт нескольких `attachments`
    for attachment in event.attachments:
    # если передано сообщение с фото
    if attachment["type"] == "photo":

или

# если было совершено действие пользователя
if event.get("action"):
    # пользователь вышел из беседы
    if event["action"]["type"] == "chat_kick_user":
lxstvayne commented 2 years ago

Я думаю это лучше оставить библиотекам направленным на удобство написания кода для ботов. Скорее всего философия vk_api немного другая. Посмотрите на библиотеку предназначенную для написания ботов, такую как vk_maria, автором которой являюсь я.