Overview

ChatOps

“ChatOps is an operational paradigm where work that is already happening in the background today is brought into a common chatroom. By doing this, you are unifying the communication about what work should get done with actual history of the work being done.” - StackStorm

In this new frontier of DevOps, it is becoming more and more popular to interact with your automation tools via an instant messenger. Opsdroid is a framework to make creating and extending your ChatOps workflows powerful but simple.

Event Flow

Opsdroid is an event-driven framework powered by asyncio. The event flow is broken down into four main steps which use different modules within opsdroid:

  • Events start and end their lives in Connectors which connect to external services. The most common example of a connector would be a chat connector which interfaces with the chat service of your choosing and triggers events whenever people send messages to your bot. There are also other connectors which can be triggered on non-chat events such as cron timings for scheduled events or webhooks. For more information see the connectors documentation.

  • Next events are parsed by Parser modules which take an event and run it through various services to add more information and context to the event. This could be as simple as testing a chat message against various regular expressions to see if any match, to running text or images through third-party AI inferencing services to perform Natural Language Understanding or object recognition tasks.

  • Matching is next where opsdroid compares the event with all of the skills which have been configured. The most suitable skill (if any) is run to handle the event based on various criteria. For more information see the matchers documentation.

  • Skills are then run to process the event in whatever way you like. You define these as Python functions which take an event object and run any arbitrary code you like. This may be to respond to a chat message with another chat message or to take some more advanced course of action such as deploying an application, restarting a server or anything you can do in Python. You can learn more about writing skills in this section of the documentation.

Opsdroid Event Flow

Modules

To handle functionality and allow maximum flexibility opsdroid is broken up into various modules. Some of these modules are shipped with opsdroid by default but all have pluggable interfaces so users can write their own.

  • Connectors are modules for connecting opsdroid to your specific chat service or event source.

  • Skills are modules that define what actions opsdroid should perform based on different chat messages.

  • Databases are modules that connect opsdroid to your chosen database and allow skills to store information between messages.

Also, opsdroid has core functionality for managing modules and events. While these are not pluggable with third-party modules we strongly encourage contribution to the opsdroid codebase.

  • Parsers add additional information to events via natural language services or other AI services.

  • Matchers rank skills against events to decide which skills to run and when.

Configuration

The configuration of opsdroid is done in a YAML file called configuration.yaml. When you run opsdroid it will look for the file in the following places in order:

  • Local ./configuration.yaml

  • The default user data location:

    • Mac: ~/Library/Application Support/opsdroid

    • Linux: ~/.local/share/opsdroid

    • Windows: C:\Documents and Settings\<User>\Application Data\Local Settings\opsdroid\opsdroid or C:\Documents and Settings\<User>\Application Data\opsdroid\opsdroid

  • System /etc/opsdroid/configuration.yaml (*nix only)

Note: if no configuration file is found then opsdroid will use an example_configuration.yaml and place it in one of the default locations.`

Make sure to read the configuration reference documentation for further information about configuring opsdroid.

Using a single YAML file for every configuration of opsdroid ensures we have a single reference for how we expect our bot to behave.

example

## Skill modules
skills:

  ## Hello world (https://github.com/opsdroid/skill-hello)
  - name: hello

  ## Last seen (https://github.com/opsdroid/skill-seen)
  - name: seen

  ## Dance (https://github.com/opsdroid/skill-dance)
  - name: dance

  ## Loud noises (https://github.com/opsdroid/skill-loudnoises)
  - name: loudnoises

Asyncio

As opsdroid is an event-driven framework it has been designed around the asyncio event loop. This means that all modules must use coroutines and follow the async/await syntax for events to be processed concurrently.

from opsdroid.connector import Connector

class ConnectorExample(Connector):

  """... simplified connector."""

  async def listen(self):
    while True:
      message = await self.api.get_message()
      await opsdroid.parse(message)

In the above example connector, we have an infinite loop which is repeatedly checking for new messages and passing them to opsdroid to be parsed. In a typical application, this loop would block forever and nothing else would be able to happen. For example, we may have another infinite loop somewhere checking the time every second and running cron scheduled tasks.

But with asyncio every time we hit an await statement the event loop adds the function call to a queue, and it may not be at the top of the queue. So it might then switch it’s attention to a different function call that has been waiting. This enables multiple code paths to execute concurrently and take it in turns to have the Python interpreters attention.

Warning

Everything you write for opsdroid should respect asyncio, use async/await and not block the thread.