Receiving Messages¶
In this section we'll learn how a bot can handle incoming messages and attachments.
Message events and the notifications loop¶
In order to receive the messages sent in the chats where the bot is a member, we need to register for some events provided by the SDK.
Additionally, we must instruct the Connection object that we want to
start receiving notifications from the backend through the
start_notifications() method.
from teamwire_api import Connection, Events
def message_handler(event_type, message):
# the chat we received message from
chat = message.chat
# print the thread id of the chat
print(f'New message received in chat id: {chat.tid}')
# print the name of the user who sent the message
print(f'> From: {message.from_user.full_name()}')
if message.msg:
# print the body of the message
print(f'> Body: {message.msg}')
if message.attachments:
# print the number of attachments received
print(f'> Attachments: {len(message.attachments)}')
with Connection() as connection:
# register handler for NEW_MESSAGE events
connection.set_handler([Events.NEW_MESSAGE], message_handler)
# start the notifications listening loop
connection.start_notifications()
In the above snippet, we first register a handler for NEW_MESSAGE events. When
a new message is received, the handler is invoked with a Message object that
contains all the required information.
In particular, it contains a reference to the parent Chat object, as well
as the sender User object, the message body and attachments.
The event handler can be either a normal function or an asyncio coroutine.
Please note that when we invoke connection.start_notifications(), the SDK starts an infinite
loop, waiting for incoming notifications from the backend, so the bot will
not exit until CTRL-C is pressed.
For additional details on the structures involved in this brief example, please
check out the Message and Chat
classes.
Handling attachments¶
As we have seen in the previous section, a received message can contain either
a text body, attachments, or both. To access the attachments
included with the message, we can use the attachments list provided by the
Message object.
Teamwire supports a wide range of attachments, e.g. locations, calendar events and attachments containing binary assets such as images, audio and video.
In this example we'll explore how we can save a received image to disk.
from teamwire_api import Connection, Events, AttachmentType
from datetime import datetime
async def message_handler(event_type, message):
if not message.attachments:
print('received message without attachments')
return
# iterate over the attachments list
for att in message.attachments:
# if the current attachment is not an image, ignore it
if att.type != AttachmentType.GALLERY:
print(f'received attachment: {att}')
continue
# store the image attachment to disk as png file
filename = f'{datetime.now()}_{message.from_user.full_name()}.png'
print(f'received image attachment, storing to {filename}')
await att.store(filename)
with Connection() as connection:
connection.set_handler([Events.NEW_MESSAGE], message_handler)
connection.start_notifications()
In particular, each attachment has a type
property, which we can use to distinguish between them.
Attachments containing assets (i.e. subclasses of the
AssetAttachment class)
like those containing images and videos provide load and
store coroutines to respectively extract the
content of the attachment, returning it as binary data, and to directly store
the data to a file.
Please note that since we are now using coroutines, the message_handler
function should be a coroutine itself.