-
Notifications
You must be signed in to change notification settings - Fork 2
Plugin Authoring (2.4 and above)
Bot framework 2.4 (and above) supports 2 kinds of plugin patterns - the function-based modern pattern, and decorator-based modern-alternate pattern.
The modern-alternate pattern is fully compatible with command and handler code from the original hangupsbot.
There is a [separate article on porting/converting pre-2.4 plugins] (Migrating-Pre-2.4-Plugins).
This section addresses things you can do in a modern pattern plugin:
- Perform initialisation tasks during plugin startup
- Register admin and non-admin commands (i.e.
/bot command
) - [ ver >= 2.7 ] Optionally register [access control tags] (https://github.com/hangoutsbot/hangoutsbot/wiki/Access-Control-with-Tags) for commands
- Register handlers to respond to external user actions and bot events
- Share plugin functionality with other plugins
Items 1, 2 and 4 are demonstrated in the [example plugin pattern] (https://gist.github.com/endofline/03a6318aef18160c2420#file-example_modern-py)
Items 3 and 5 are considered advanced functionality and are rarely used in most plugins.
The function _initialise()
(or its alternate spelling _initialize
) is called when a plugin is loaded.
A reference to the hangupsbot object will be passed allowing for additional actions to be performed using
bot functionality, such as reading and writing config.json
and memory.json
.
import plugins
plugins.register_user_command(list[str])
plugins.register_admin_command(list[str])
e.g.
import plugins
def _initialise(bot):
plugins.register_user_command(["helloworld", "goodbyeworld"])
def helloworld(bot, event, *args):
print("hello world!")
def goodbyeworld(bot, event, *args):
print("goodbye world!")
Command prototype: custom_command(bot, event, *args)
- as shown above
A command registered with both functions will always default to an admin-only command.
[ ver >= 2.7 ] The optional tags
parameter is available for both register_user_command
and register_admin_command
:
plugins.register_user_command([commandlist], tags=[tagslist])
plugins.register_admin_command([commandlist], tags=[tagslist])
Adding tagging support to a plugin gives bot administrators additional control over which user can access and execute commands. For more information, please see the separate article on Access Control with Tags.
Note: You can use named presets for the tagslist
in the same way that [plugins.tags.auto-register
]
(https://github.com/hangoutsbot/hangoutsbot/wiki/Customising-Access-Control#pluginstagsauto-register)
uses them to dynamically generate different tags for each command.
import plugins
plugins.register_handler(function, type="message", priority=50)
e.g.
import plugins
def _initialise(bot):
plugins.register_handler(_got_a_message, type="message", priority=50)
def _got_a_message(bot, event, command):
print("something happened")
-
message
- fires on a message received in chat (except for bot's own messages)- default handler if
type
not specified - handler prototype:
on_receive(bot, event, command)
- default handler if
-
rename
- fires on chat rename event- handler prototype:
on_rename(bot, event, command)
- handler prototype:
-
membership
- fires when users join or leave the chat- handler prototype:
on_membership(bot, event, command)
- handler prototype:
-
sending
- modification of bot messages prior to being sent- handler prototype:
on_send(bot, broadcast_list, context)
-
broadcast_list
is a tuple consisting of(conversation_id, chat_segments)
- LOW-LEVEL: The functionality provided by this handler is only used by complex plugins.
- handler prototype:
-
allmessages
- fires on all messages (including bot's own)- handler prototype:
on_receive(bot, event, command)
- LOW-LEVEL: The functionality provided by this handler is only used by complex plugins.
- WARNING: Misuse of this handler can result in an infinite message loop in the scenario of a bot continuously responding to its own sent messages.
- handler prototype:
-
typing
- fires on all typing notification (including bot's own)- handler prototype:
on_typing(bot, event, command)
-
event.from_bot
will beTrue
if the bot fired this event -
event.conv_event
has a different data structure, seetyping_notification
in the [state_update
reference] (hangups-state_update-dumps#typing)
- handler prototype:
-
watermark
- fires on all watermark updates (including bot's own)- handler prototype:
on_watermark(bot, event, command)
-
event.from_bot
will beTrue
if the bot fired this event -
event.conv_event
has a different data structure, seewatermark_notification
in the [state_update
reference] (hangups-state_update-dumps#watermark)
- handler prototype:
-
call
- fires on video/voice call starting or ending (including bot's own)- handler prototype:
on_call(bot, event, command)
-
event.from_bot
will beTrue
if the bot fired this event -
event.conv_event
is similar to standard message events, with extra data inhangout_event
as indicated in the [state_update
reference] (hangups-state_update-dumps#video-hangout)
- handler prototype:
Handler priority
determines the evaluation sequence of each handler per event. The recommended range
is 1 to 100 - with 1 being highest priority (evaluated first) and 100 the lowest priority
(evaluated last).
bot.register_shared("<id>", object, forgiving=False)
bot.call_shared("<id>", object)
bot.call_shared("<id>", object, <optional parameter list>)
e.g.
Plugin A: Register callable
def _initialise(bot):
bot.register_shared("plugin_a._send_alert", _send_alert)
def _send_alert(bot, alert_text)
print(alert_text)
Plugin B: Call shared function
def function(bot, event, *args):
bot.call_shared("plugin_a._send_alert", bot, "Hello World")
Registers an object (usually a shared function) for usage by other plugins. It does not matter what the
name of <id>
is so long as another plugin is not registering another object with the same <id>
. If
<id>
already exists and forgiving=False
(default), the bot will raise a RuntimeError
exception
during registration.
To call/retrieve the shared object, use bot.call_shared("<id>")
. This will raise a KeyError
exception
if <id>
does not exist. As a plugin developer, the possibility that the shared function does
not exist must be handled.
If the shared object is callable (is a function, class, or similar), call_shared
will pass additional
supplied parameters (after <id>
) as part of the call.
This pattern is derived from the way commands and handlers are implemented in the [original hangupsbot] (https://github.com/xmikos/hangupsbot).
Note: Although possible, it is not recommended to mix the two plugin patterns together in a single plugin.
from commands import command
@command.register(admin=True)
@command.register(admin=False)
@command.register
e.g.
from commands import command
@command.register(admin=False)
function helloworld(bot, event, *args):
print("hello world!")
Command prototype: custom_command(bot, event, *args)
Identical in functionality to plugins.register_user_command
and plugins.register_admin_command
[ ver >= 2.7 ] The decorators support the optional tags
parameter:
@command.register(admin=True, tags=[tagslist])
@command.register(admin=False, tags=[tagslist])
Adding tagging support to a plugin gives bot administrators additional control over which user can access and execute commands. For more information, please see the separate article on Access Control with Tags.
Note: You can use named presets for the tagslist
in the same way that [plugins.tags.auto-register
]
(https://github.com/hangoutsbot/hangoutsbot/wiki/Customising-Access-Control#pluginstagsauto-register)
uses them to dynamically generate different tags for each command.
import hangups
from handlers import handler
@handler.register(priority=5, event=hangups.ChatMessageEvent)
e.g.
import hangups
from handlers import handler
@handler.register(priority=5, event=hangups.ChatMessageEvent)
def _got_a_message(bot, event):
print("something happened")
Registers a function to handle an event
:
- hangups.ChatMessageEvent
- hangups.RenameEvent
- hangups.MembershipChangeEvent
- any string-based
type
supported by [plugins.register_handler
] (https://github.com/hangoutsbot/hangoutsbot/wiki/Plugin-Authoring-(2.4-and-above)#supported-eventshandlers)
The handler function must be of the form function(bot, event)
- the 2-parameter signature differs from
the 3-parameter signature of functions registered by plugins.register_handler
.
Handler priority
is handled in the same way as plugins.register_handler
except the expected range of
the decorator priority
is 1-10. For compatibility reasons, the supplied value is multiplied by 10 to
scale it up to the internal range of 1-100.
Plugin List | Developer Reference: [ Intro | Plugins | Sinks | In-built Functionality | [Configuration] (Configuration) ]