mmpy_bot Framework

repository·main·Indexed 43 days ago

https://github.com/attzonko/mmpy_bot

A Python-based chat bot framework for Mattermost using the WebSocket API (V4.0.0). It features a plugin-based architecture with support for concurrency, asyncio execution, job scheduling, and an integrated webhook server. Compatible with Mattermost 4.0+ and Python 3.8+ (for v2.x).

Tokens
4.9K
Snippets
18
Records
22
Agent score
55%

What's inside mmpy_bot

  1. Overview of mmpy_bot features

    main

    mmpy_bot is a Python-based framework for Mattermost bots using the WebSocket API (V4.0.0).

    Core Features:

    • Simple plugin mechanism
    • Concurrent message handling
    • Attachment support
    • Automatic reconnection after connection loss

    v2.x Specific Features:

    • Multi-threading and asyncio execution
    • Integrated webhook server
    • Support for click functions
    • Job scheduling
  2. Schedule periodic and one-time jobs

    main

    mmpy_bot integrates the schedule library to provide in-process job scheduling.

    Periodic Jobs

    Use schedule.every(...).seconds.do(...) (or other schedule methods) to create recurring tasks. These tasks are added to a waiting queue.

    One-time Jobs

    While schedule is primarily for periodic tasks, mmpy_bot includes monkey-patching to support one-time jobs via the schedule.once(datetime_object) method. Note that schedule.once requires a datetime object as an argument.

    import schedule
    import re
    
    # Example: Scheduling a periodic job via a command
    @listen_to("^schedule every ([0-9]+)$", re.IGNORECASE, needs_mention=True)
    def schedule_every(self, message: Message, seconds: int):
        schedule.every(int(seconds)).seconds.do(
            self.driver.reply_to, message, f"Scheduled message every {seconds} seconds!"
        )
    
    # Example: Cancelling all jobs
    @listen_to('cancel jobs', re.IGNORECASE)
    def cancel_jobs(self, message):
        schedule.clear()
        self.driver.reply_to(message, 'All jobs cancelled.')
  3. Run mmpy_bot using a Container

    main

    You can run mmpy_bot using a container image (e.g., Podman or Docker). You must provide the Mattermost connection details via environment variables.

    $ podman pull docker.io/jneeven/mmpy_bot
    
    $ podman run -d --name=mmpy_bot --network=host \
        -e MATTERMOST_URL=<mattermost_server_url> \
        -e MATTERMOST_PORT=<mattermost_server_port> \
        -e BOT_TOKEN=<bot_token> \
        docker.io/jneeven/mmpy_bot
  4. Register a Bot Account in Mattermost

    main

    To use mmpy_bot, you must create a bot account on your Mattermost server.

    1. Ensure Enable Bot Account Creation is enabled in your Mattermost System Console.
    2. Log in as an Administrator.
    3. Navigate to Integrations -> Bot Accounts -> Add Bot Account.
    4. Configure the account and save the generated Access Token.

    Permissions Note: Most functions work with a Member role, but certain features (like ephemeral message replies) require the bot to be in the System Admin group.

  5. Install mmpy_bot

    main

    Install the latest version (v2.x) of mmpy-bot using pip.

    Note: mmpy-bot v2.x requires Python 3.8 or higher. If you are using an older Python version, pip may automatically install the legacy v1.x branch. To force the legacy version for Python < 3.8, specify version 1.3.9.

    # Install latest v2.x
    pip install mmpy-bot
    
    # Force legacy v1.3.9 for Python < 3.8
    pip install mmpy-bot==1.3.9
  6. Enable and use the WebHookServer

    main

    To interact with your bot via web requests (e.g., for Mattermost interactive dialogs), enable the built-in WebHookServer.

    1. Configure Settings: In your Settings, set WEBHOOK_HOST_ENABLED=True and provide values for WEBHOOK_HOST_URL and WEBHOOK_HOST_PORT.
    2. Implement Listeners: Use the @listen_webhook(path) decorator on an async function within your Plugin. The function receives a WebHookEvent object.
    3. Handle Events: You can access the request body via event.body and the unique webhook ID via event.webhook_id.
    from mmpy_bot import listen_webhook
    
    @listen_webhook("ping")
    async def ping_listener(self, event: WebHookEvent):
        # Accessing event data
        channel_id = event.body["channel_id"]
        webhook_id = event.webhook_id
        
        self.driver.create_post(channel_id, f"Webhook {webhook_id} triggered!")
  7. Configure and run the bot

    main

    To start the bot, create an entrypoint Python file that initializes the Bot class with Settings and a list of plugins. You can define settings directly in the Settings object or via environment variables.

    Required settings include MATTERMOST_URL, MATTERMOST_PORT, BOT_TOKEN, and BOT_TEAM.

    #!/usr/bin/env python
    
    from mmpy_bot import Bot, Settings
    from my_plugin import MyPlugin
    
    bot = Bot(
        settings=Settings(
            MATTERMOST_URL = "http://chat.example.com",
            MATTERMOST_PORT = 443,
            BOT_TOKEN = "a69155mvlsobcnqpfdceqihaa",
            BOT_TEAM = "test",
            SSL_VERIFY = True,
        ),  # Either specify your settings here or as environment variables.
        plugins=[MyPlugin()],  # Add your own plugins here.
    )
    bot.run()
  8. Write your first plugin

    main

    To create a plugin for mmpy_bot, subclass the Plugin class. Use the @listen_to decorator on methods within your class to define how the bot responds to specific messages. Each decorated method should accept a Message object. To run the bot, instantiate the Bot class, provide a Settings object (containing Mattermost connection details), and pass a list of your plugin instances to the plugins argument.

    from mmpy_bot import Plugin, listen_to, Message, Bot, Settings
    
    class MyPlugin(Plugin):
        @listen_to("wake up")
        async def wake_up(self, message: Message):
            self.driver.reply_to(message, "I'm awake!")
    
    bot = Bot(
        settings=Settings(
            MATTERMOST_URL = "http://127.0.0.1",
            MATTERMOST_PORT = 8065,
            BOT_TOKEN = "<your_bot_token>",
            BOT_TEAM = "<team_name>",
            SSL_VERIFY = False,
        ),
        plugins=[MyPlugin()],
    )
    bot.run()
  9. Run the bot using an entrypoint script

    main

    To run the bot, create an entrypoint.py file. You must instantiate a Bot object with a Settings object containing your Mattermost credentials and a list of plugins to be activated. Finally, call bot.run().

    #!/usr/bin/env python
    
    from mmpy_bot import Bot, Settings, ExamplePlugin, WebHookExample
    # from my_plugin import MyPlugin
    
    bot = Bot(
        settings=Settings(
            MATTERMOST_URL = "http://<mattermost_server_url>",
            MATTERMOST_PORT = 443,
            BOT_TOKEN = "<your_bot_token>",
            BOT_TEAM = "<team_name>",
            SSL_VERIFY = True,
        ),
        plugins=[ExamplePlugin(), WebHookExample()],
    )
    bot.run()
  10. Run mmpy_bot locally with Mattermost on the host machine

    main

    If your Mattermost server is running on the host machine (not inside a Docker container), you must configure the Docker Compose service to access the host's network. This typically requires setting network_mode: host and adding extra_hosts to map dockerhost to the local loopback address.

    services:
      app:
        container_name: "mmpy_bot"
        build: .
        network_mode: host
        extra_hosts:
          - "dockerhost:127.0.0.1"