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 frome 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, so when a new message is received, the same is invoked with the message as a Message object as an argument, which 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. In order to access the attachments eventually included with the message we can use the attachments list provided by the Message object.

Teamwire supports a wide range of attachments, e.g. location, calendar event, and attachments containing binary assets, like images, audio, video, etc.

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 discriminate between them.

Attachments containing assets (i.e. subclasses of the AssetAttachment class) like those containing images, videos, etc. provide a load and a 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.