Included hooks¶
Access¶
Path: immp.hook.access.ChannelAccessHook
Channel join control, extended by other hooks.
Config
- hooks ((str, str list) dict):
Mapping of access-aware hooks to a list of channels they manage. If a list is
None
, the included hook will just manage channels it declares ownership of.- exclude ((str, str list) dict):
Mapping of plugs to user IDs who should be ignored during checks.
- joins (bool):
True
to check each join as it happens.- startup (bool):
True
to run a full check of all named channels on load.- passive (bool):
True
to log violations without actually following through with removals.- default (bool):
True
(default) to implicitly grant access if no predicates provide a decision, orFalse
to treat all abstains as an implicit deny.
This hook implements its own protocol for test purposes, by rejecting all joins and members of a channel. To make full use of it, other hooks with support for channel access can determine if a user satisfies membership of an external group or application.
Alerts¶
Path: immp.hook.alerts.MentionsHook
(mentions),
immp.hook.alerts.SubscriptionsHook
(highlights)
Fallback mention and word highlight support for plugs via private channels.
Mentions¶
Config
- plugs (str list):
List of plug names to enable mention alerts for.
- usernames (bool):
Whether to match network usernames (
True
by default).- real-names (bool):
Whether to match user’s display names (
False
by default).- ambiguous (bool):
Whether to notify multiple potential users of an ambiguous mention (
False
by default).
For networks that don’t provide native user mentions, this plug can send users a private message when mentioned by their username or real name.
A mention is matched from each @
sign until whitespace is encountered. For real names, spaces
and special characters are ignored, so that e.g. @fredbloggs
will match Fred Bloggs.
Partial mentions are supported, failing any exact matches, by basic prefix search on real names.
For example, @fred
will match Frederick, and @fredb
will match Fred Bloggs.
Subscriptions¶
Dependencies
Config
- plugs (str list):
List of plug names to enable subscription alerts for.
Commands
- sub-add <text>:
Add a subscription to your trigger list.
- sub-remove <text>:
Remove a subscription from your trigger list.
- sub-exclude <text>:
Don’t trigger a specific subscription in the current public channel.
- sub-list:
Show all active subscriptions.
Allows users to opt in to private message notifications when chosen highlight words are used in a group conversation.
Auto-responder¶
Path: immp.hook.autorespond.AutoRespondHook
Basic text request/response handler.
Config
- groups (str list):
List of groups to process responses in.
- responses ((str, str) dict):
Mapping from match regex to response text.
Commands
- ar-add <match> <response>:
Add a new trigger / response pair.
- ar-remove <match>:
Remove an existing trigger.
This hook will listen for messages in all given channels, for text content that matches any of the
defined regular expressions. On a match, it will answer with the corresponding response. You can
include capture groups in the expression, which are available using positional formatting syntax
({0}
for a specific group, or {}
for each one in turn).
Because all responses are defined in the config, you’ll need to ensure it’s saved when making changes via the add/remove commands.
Commands¶
Path: immp.hook.command.CommandHook
Backbone for other hooks to process commands contained in channel messages.
Config
- prefix (str):
Characters at the start of a message to denote commands. Use a single character to make commands top-level (e.g.
"?"
would allow commands like?help
), or a string followed by a space for subcommands (e.g."!bot "
for!bot help
).- return-errors (bool):
True
to send unhandled exceptions raised by commands back to the source channel (False
by default).- sets ((str, str list) dict):
Subsets of hook commands by name, to restrict certain features.
- mapping ((str, dict) dict):
Named config groups to enable commands in selected channels.
- groups (str list):
List of groups (plugs and channels) to process public commands in.
- hooks (str list):
List of hooks to enable commands for.
- identify ((str, str list) dict):
Mapping of identity providers and roles, used to restrict command access.
If non-empty, users must be identified to at least one of the given providers. The value in the mapping can be a list of roles, of which the user must hold at least one. With no roles given, any user identified by the provider will be accepted.
- sets (str list):
List of command sets to enable.
The binding works by making commands exposed by all listed hooks available to all listed channels, and to the private channels of all listed plugs. Note that the channels need not belong to any hook-specific config – you can, for example, bind some commands to an admin-only channel elsewhere. Multiple groups can be used for fine-grained control.
Database¶
Path: immp.hook.database.AsyncDatabaseHook
immp.hook.database.DatabaseHook
(legacy)
Provider of database access to other hooks. All first-party hooks with database support will require the asynchronous database provider to be present.
Asynchronous¶
Requirements
Extra name: db
Any database-specific libraries (e.g. asyncpg for PostgreSQL)
Config
- url (str):
Database connection string, as defined by Tortoise’s DB_URL.
Synchronous¶
Deprecated since version 0.10.0: Use the asynchronous variant instead.
Requirements
Any database-specific libraries (e.g. Psycopg2 for PostgreSQL)
Config
- url (str):
Database connection string, as defined by Peewee’s Database URL.
Warning
Database requests will block all other running tasks; notably, all plugs will be unable to make any progress whilst long-running queries are executing.
Discord roles¶
Path: immp.hook.discordrole.DiscordRoleHook
Self-serve Discord roles for users.
Dependencies
Config
- roles ((str, int) dict):
Mapping from user-facing role names to Discord role IDs.
Commands
- role <name>:
Claim a role of this name.
- unrole <name>:
Drop the role of this name.
Hangouts locks¶
Path: immp.hook.hangoutslock.HangoutsLockHook
Identity lookup¶
Path: immp.hook.identity.WhoIsHook
Identity protocol backbone, and a generic user lookup command.
Config
- identities (str list):
List of identity provider names from which to allow lookups.
- public (bool):
True
to allow anyone with access to thewho
command to do a lookup, without necessarily being identified themselves (defaults toFalse
).
Commands
- who <name>:
Recall a known identity and all of its links.
This module defines a subclass for all hooks providing identity services – no hook is needed from
here if using an identity hook elsewhere. The WhoIsHook
provides a command for users to
query basic identity information.
Local identity¶
Path: immp.hook.identitylocal.LocalIdentityHook
Basic identity management for users in different networks.
Dependencies
Config
- instance (int):
Unique instance code.
- plugs (str list):
List of plug names to accept identities for.
- multiple (bool):
True
(default) to allow linking multiple accounts from the same network.- admins ((str, str list) dict):
Mapping from plug names to user identifiers that can use the
id-role
command.
Commands
- id-add <name> <pwd>:
Create a new identity, or link to an existing one from a second user.
- id-rename <name>:
Rename the current identity.
- id-password <pwd>:
Update the password for the current identity.
- id-reset:
Delete the current identity and all linked users.
- id-role <name> [role]:
List roles assigned to an identity, or add/remove a given role.
This is a local implementation of the identity protocol, providing self-serve identity linking to users where a user management backend doesn’t otherwise exist.
In order to support multiple copies of this hook with overlapping plugs (e.g. including a private network in some groups), each hook has an instance code. If a code isn’t defined in the config, a new one will be assigned at startup. If multiple hooks are in use, it’s important to define these yourself, so that identities remained assigned to the correct instance.
Notes¶
Path: immp.hook.notes.NotesHook
Recallable per-channel lists of text items.
Dependencies
Commands
- note-add <text>:
Add a new note for this channel.
- note-edit <num> <text>:
Update an existing note from this channel with new text.
- note-remove <num>:
Delete an existing note from this channel by its position.
- note-show <num>:
Recall a single note in this channel.
- note-list:
Recall all notes for this channel.
Shell¶
Path: immp.hook.shell.AsyncShellHook
,
immp.hook.shell.ShellHook
(legacy)
Interact with and debug a running app in the console.
Asynchronous¶
Requirements
Extra name: console
Config
- bind (int or str):
TCP port or UNIX socket path to bind the console on. See aioconsole’s docs for more info.
- buffer (int):
Number of received messages to keep cached for later inspection. If unset (default), no buffer will be available. Otherwise, when a new message comes in and the queue is full, the oldest message will be discarded. Set to
0
for an unlimited buffer, not recommended on production deployments.
At startup, a console will be launched on the given port or socket. You can connect to it from a separate terminal, for example with netcat for TCP:
$ rlwrap nc localhost $PORT
Or socat for sockets:
$ rlwrap socat $PATH -
Tip
Use of rlwrap
provides you with readline-style keybinds, such as ↑ and ↓ to navigate
through previous commands, and Ctrl-R to search the command history.
The variables shell
and host
are defined, refering to the shell hook and the
running Host
respectively. This hook also maintains a cache of messages as they’re
received, accessible via AsyncShellHook.buffer
.
Warning
The console will be accessible on a locally bound port without authentication. Do not use on shared or untrusted systems, as the host and all connected plugs are exposed.
Synchronous¶
Deprecated since version 0.10.0: Use the asynchronous shell with a buffer in order to interact with incoming messages.
Requirements
- ptpython:
Can be used with
console: ptpython
as described below.
Config
- all (bool):
True
to process any message,False
(default) to restrict to defined channels.- console (str):
Use a different embedded console. By default,
code.interact()
is used, but set this toptpython
for a more functional shell.
When a new message is received, a console will launch in the terminal where your app is running.
The variables channel
and msg
are defined in the local scope, whilst self
refers to the shell hook itself.
Warning
The console will block all other running tasks; notably, all plugs will be unable to make any progress whilst the console is open.
Sync¶
Path: immp.hook.sync.SyncHook
Bridge multiple channels into a single unified conversation, or relay messages from one channel to one or more others.
Sync¶
Requirements
Extra name: sync
Dependencies
AsyncDatabaseHook
:If present, synced message IDs will be persisted to the database, allowing referenced messages (replies, forwards, attachments) to be handled correctly across restarts.
Config
- channels ((str, str list) dict):
Mapping from virtual channel names to lists of channel names to bridge.
- plugs ((str, dict) dict):
Mapping from plug names to plug-specific config. This allows overriding the following top-level config values: joins, renames, reset-author, name-format, strip-name-emoji
- plug (str):
Name of a virtual plug to register for this sync.
- edits (bool):
Whether to sync updates to, and deletions of, messages across the bridge.
- joins (bool):
Whether to sync join and part messages across the bridge.
- renames (bool):
Whether to sync channel title changes across the bridge.
- identities (str):
Name of a registered
IdentityProvider
to provide unified names across networks.If enabled, this will rewrite mentions for users identified in both the source and any sync target channels, to use their platform-native identity.
- reset-author (bool):
True
to create and attach a new user with just a name,False
(default) to clone and modify the existing user (thus keeping username, avatar etc.).- name-format (str):
Template to use for replacing real names on synced messages, parsed by
jinja2
. If not set but the user is identified, it defaults to<real name> (<identity name>)
.- Context variables:
- user (.User):
Message author, may be
None
for system messages or whenreset-author
is set.- identity (.IdentityGroup):
Connected identity, or
None
if no link oridentities
isn’t set.- title (str):
Channel title.
- strip-name-emoji (bool):
True
to remove emoji characters from message authors’ real names.- titles ((str, str) dict):
Mapping from virtual channel names to display names.
Commands
- sync-members:
List all members of the current conversation, across all channels.
- sync-list:
List all channels connected to this conversation.
When a message is received from any of the listed channels, a copy is pushed to all other channels participating in the bridge.
If plug
is specified, a virtual plug is registered under that name, with a channel for each
defined bridge. Other hooks may reference these channels, to work with all channels in that sync
as one. This allows them to listen to a unified stream of messages, or push new messages to all
synced channels.
Forward¶
Requirements
Extra name: sync
Config
- channels ((str, str list) dict):
Mapping from source channel names to lists of channel names to forward to.
- plugs ((str, dict) dict):
Mapping from plug names to plug-specific config. This allows overriding the following top-level config values: joins, renames, reset-author, name-format, strip-name-emoji
- users (str list):
Whitelist of user IDs to accept source messages from. If set, messages from anyone else in the source channel will be ignored.
- joins (bool):
Whether to forward join and part messages.
- renames (bool):
Whether to forward channel title changes.
- identities (str):
Name of a registered
IdentityProvider
to provide unified names across networks.If enabled, this will rewrite mentions for users identified in both the source and any sync target channels, to use their platform-native identity.
- reset-author (bool):
True
to create and attach a new user with just a name,False
(default) to clone and modify the existing user (thus keeping username, avatar etc.).- name-format (str):
Template to use for replacing real names on synced messages, parsed by
jinja2
. If not set but the user is identified, it defaults to<real name> (<identity name>)
.- Context variables:
- user (.User):
Message author, may be
None
for system messages or whenreset-author
is set.- identity (.IdentityGroup):
Connected identity, or
None
if no link oridentities
isn’t set.- title (str):
Channel title.
- strip-name-emoji (bool):
True
to remove emoji characters from message authors’ real names.
When a message is received in a configured source channel, a copy is pushed to all downstream channels. Unlike a sync, this is a one-direction copy, useful for announcements or alerts.
Text commands¶
Path: immp.hook.textcommand.TextCommandHook
Simple custom commands to send preconfigured text messages to channels.
Config
- commands ((str, str) dict):
Mapping from command name to rich response text.
Web¶
Path: immp.hook.web.WebHook
Run a webserver for other plugs or hooks to accept incoming HTTP requests.
Requirements
Extra name: web
- aiohttp_jinja2:
Required for page templating.
Config
- host (str):
Hostname or IP address to bind to.
- port (int):
Port number to bind to.
As the server is unauthenticated, you will typically want to bind it to localhost
, and proxy it
behind a full web server like nginx to separate out routes, lock down access and so on.
Web UI¶
Path: immp.hook.webui.WebUIHook
Web-based management UI for a host instance.
Dependencies
WebHook
with templating
Extra name: webui
- Docutils:
Used to render module documentation if available.
Config
- route (str):
Path to expose the UI pages under.
This is a simple control panel to add or update plugs and hooks in a running system.
Warning
The UI provides no authentication, and exposes all internals of the system (including any secret keys, as well as remote code execution via loading new plugs/hooks). You should only run this hook on a trusted system, and bind it to localhost to avoid external access.
If remotely accessible configuration is desired, use SSH with port forwarding to securely connect to your server. Failing that, you could proxy via a webserver like nginx and enable HTTP authentication, or use a service layer like oauth2_proxy.