-
Notifications
You must be signed in to change notification settings - Fork 2
Plugin Authoring (2.3.4 and below)
Innocent Bystander edited this page Aug 10, 2015
·
3 revisions
THIS DOCUMENTATION IS DEPRECATED AND NO LONGER RECOMMENDED FOR DEVELOPERS - PLEASE SEE THE PLUGIN DEVELOPMENT GUIDE FOR 2.4 AND ABOVE
def simple_command(bot, event, *args):
print("something happened!")
This pattern simply implements a new /bot
command that can be called with /bot simple_command
import asyncio
def _initialise(Handlers, bot=None):
"""
first, you can setup stuff, initialise variables and whatever else!
"""
Handlers.register_handler(_custom_handler)
Handlers.register_user_command(["custom_command"])
# above command is available to all users
# Handlers.register_admin_command() if command(s) only available to admins
return [] # always a blank list
@asyncio.coroutine
def _custom_handler(bot, event, command):
if "somethinghappened" in event.text
yield from command.run(bot, event, *["custom_command"])
def custom_command(bot, event, *args):
print("something happened!")
In the above pattern, custom_command
will be available as a /bot
command:
/bot custom_command
. It will also be executed every time somebody says
"somethinghappened" in the chat.
- If the bot's
plugin
key inconfig.json
isnull
, it will attempt to load all valid plugins inside theplugins/
directory. - A valid plugin should have a file name with the following specifications:
- must end with extension
.py
- does NOT start with an underscore (
_
) - does NOT start with a dot (
.
) - file name (excluding extension) must only contain standard
ASCII alphabets, numbers, and underscores (
_
)
- must end with extension
- Just a standard Python function with parameters
(bot, event, *args)
- Simply defining a function
custom_command
will implement new command/bot custom_command
regardless of anything else in the plugin file. - Can be directly called from events and custom triggers using syntax:
yield from command.run(bot, event, *["custom_command"])
- If more than one plugin defines the same command, the publicly available
/bot <command>
will be overwritten based on the order of plugins initialisation. This is not recommended, as it may confuse other developers - try and make your custom commands unique. - Function names starting with an underscore will not be added as a
/bot
command - this is by design, and allows "hidden" internal-only functions inside the plugin.
-
_initialise
/_initialize
is called automatically when the plugin is loaded - developers can use this specialised function to register commands and handlers
- when defined, this function should
return
something- legacy plugins return a list of
<command>
s that will be available as/bot <command>
e.g.return ["command_a", "command_b", "command_c"]
(NOT RECOMMENDED FOR NEW PLUGINS) - newer plugins which use the preferred method of registering commands
(
register_user_command
andregister_admin_command
) should alwaysreturn []
- returning
None
(or notreturn
-ing at all) will make all defined functions available as a/bot
command to all users EXCEPT:- the reserved function names:
_initialise
and_initialize
; and - function names beginning with an underscore.
- the reserved function names:
- legacy plugins return a list of
-
Handlers.register_user_command([LIST of command names])
publishes commands that can be accessed by all users e.g.Handlers.register_user_command(["public_command_a", "public_command_b"])
- Use
Handlers.register_admin_command([LIST of command names])
to add commands that can be only be used by bot admins e.g.Handlers.register_user_command(["dangerous_command_x", "dangerous_command_y"])
- You do not need to register the same command with both functions - if you do so, the duplicated command will only be available to bot admins.
- When using any of these two functions, ensure that your
_initialise
function returns a blank list withreturn []
- older plugins used to return a list of commands that can be accessed by all users - this is no longer necessary but supported for backward-compatibility.
-
register_handler(function, type="message")
called during plugin initialisation to register custom handlers for specific bot events:-
message
- fires on message received- default handler if
type
not specified - handler prototype:
def on_receive(bot, event, command)
- decorate with
@asyncio.coroutine
- default handler if
-
rename
- fires on chat rename event- handler prototype:
def on_rename(bot, event, command)
- decorate with
@asyncio.coroutine
- handler prototype:
-
membership
- fires when users join or leave the chat- handler prototype:
def on_membership(bot, event, command)
- decorate with
@asyncio.coroutine
- handler prototype:
-
sending
- low-level modification of bot messages- handler prototype:
def on_send(bot, broadcast_list, context)
- standard function i.e. not decorated with
@asyncio.coroutine
-
broadcast_list
is a tuple consisting of(conversation_id, chat_segments)
- handler prototype:
-
- Call
register_handler
last just beforereturn
-ing so that any exceptions in preceding code will ensure a handler won't be erroneously registered -
_custom_handler
(or whatever function name you desire) is only required when implementing something that does not use the syntax/bot <command>
e.g. responding to a specific keyword, or custom trigger/xyz
, etc. - To implement custom triggers e.g.
/abc
,/xyz <command> <parameters>
, etc with custom handlers, you must manually parse and splitevent.text
thenyield.from
appropriately to your desired function (as demonstrated in the "somethinghappened" implementation in the pattern above). Helpful Python(3) references: split, startswith- Pass extra arguments in the
yield.from
syntax with the following:yield from command.run(bot, event, *["custom_command", arg1, arg2, arg3, ... ])
- Pass extra arguments in the
-
Handlers.register_object("<id>", <objectref>)
can be called during plugin initialisation to register a reference to a shared function/object. - To call the function from another plugin, use
bot.call_shared("<id>", <argument list>)
- raises a
KeyError
if<id>
does not exist, handle accordingly
- raises a
-
<id>
can be any text string. It is recommended that you supply use the following format:<plugin name>.<function name>
. -
<objectref>
can be any reference - in most scenarios, it would be a function name. - Examples of shared plugin functionality can be found in the dnd plugin interaction
with the plugins: mentions and subscribe.
- The shared function registration (
register_object
) occurs in the [dnd plugin] (https://github.com/nylonee/hangupsbot/blob/staging/hangupsbot/plugins/dnd.py#L6) - The external call to the function via
call_shared
occurs in the [mentions plugin] (https://github.com/nylonee/hangupsbot/blob/staging/hangupsbot/plugins/mentions.py#L44) and [subscribe plugin] (https://github.com/nylonee/hangupsbot/blob/staging/hangupsbot/plugins/subscribe.py#L64).
- The shared function registration (
Please see: available bot
functions
- Only basic exception information output to console. The information amounts to
a single line starting with "
EXCEPTION
", with some basic information on the exception - either a line number or the name of the exception. - To get the full stack trace for the exception, you need to [see the bot log] (https://github.com/nylonee/hangupsbot#developers-debugging)
Plugin List | Developer Reference: [ Intro | Plugins | Sinks | In-built Functionality | [Configuration] (Configuration) ]