shellbot.listener module

class shellbot.listener.Listener(engine=None, filter=None)[source]

Bases: multiprocessing.process.Process

Handles messages received from chat space

DEFER_DURATION = 2.0
EMPTY_DELAY = 0.005
FRESH_DURATION = 0.5
idle()[source]

Finds something smart to do

on_inbound(received)[source]

Another event has been received

Parameters:received (Event or derivative) – the event received

Received information is transmitted to registered callbacks on the inbound at the engine level.

on_join(received)[source]

A person, or the bot, has joined a space

Parameters:received (Join) – the event received

Received information is transmitted to registered callbacks on the join at the engine level.

In the special case where the bot itself is joining a channel by invitation, then the event enter is dispatched instead.

on_leave(received)[source]

A person, or the bot, has left a space

Parameters:received (Leave) – the event received

Received information is transmitted to registered callbacks on the leave at the engine level.

In the special case where the bot itself has been kicked off from a channel, then the event exit is dispatched instead.

on_message(received)[source]

A message has been received

Parameters:received (Message) – the message received

Received information is transmitted to registered callbacks on the message event at the engine level.

When a message is directed to the bot it is submitted directly to the shell. This is handled as a command, that can be executed immediately, or pushed to the inbox and processed by the worker when possible.

All other input is thrown away, except if there is some downwards listeners. In that situation the input is pushed to a queue so that some process can pick it up and process it.

The protocol for downwards listeners works like this:

  • Check the bot.fan queue frequently
  • On each check, update the string fan.<channel_id> in the context with the value of time.time(). This will say that you are around.

The value of fan.<channel_id> is checked on every message that is not for the bot itself. If this is fresh enough, then data is put to the bot.fan queue. Else message is just thrown away.

process(item)[source]

Processes items received from the chat space

Parameters:item (dict or json-encoded string) – the item received

This function dispatches items based on their type. The type is a key of the provided dict.

Following types are handled:

  • message – This is a textual message, maybe with a file attached. The message is given to the on_message() function.
  • join – This is when a person or the bot joins a space. The function on_join() is called, providing details on the person or the bot who joined
  • leave – This is when a person or the bot leaves a space. The function on_leave() is called with details on the leaving person or bot.
  • load_bot – This is a special event to load the cache in the process that is running the listener. The identifier of the channel to load is provided as well.
  • on any other case, the function on_inbound() is called.
run()[source]

Continuously receives updates

This function is looping on items received from the queue, and is handling them one by one in the background.

Processing should be handled in a separate background process, like in the following example:

listener = Listener(engine=my_engine)
process = listener.start()

The recommended way for stopping the process is to change the parameter general.switch in the context. For example:

engine.set('general.switch', 'off')

Alternatively, the loop is also broken when a poison pill is pushed to the queue. For example:

engine.ears.put(None)