Skip to content

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.