vk_api
vk_api copied to clipboard
Замена event'a из longpoll на более удобный, который можно получить через вызов метода
Для удобства использую следующий класс:
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":
Я думаю это лучше оставить библиотекам направленным на удобство написания кода для ботов. Скорее всего философия vk_api немного другая. Посмотрите на библиотеку предназначенную для написания ботов, такую как vk_maria, автором которой являюсь я.