Application services are passive and can only observe events from
homeserver. They can inject events into rooms they are participating in.
They cannot prevent events from being sent, nor can they modify the
content of the event being sent. In order to observe events from a
homeserver, the homeserver needs to be configured to pass certain types
of traffic to the application service. This is achieved by manually
configuring the homeserver with information about the application
service.
### Registration
Note
Previously, application services could register with a homeserver via
HTTP APIs. This was removed as it was seen as a security risk. A
compromised application service could re-register for a global `*` regex
and sniff *all* traffic on the homeserver. To protect against this,
application services now have to register via configuration files which
are linked to the homeserver configuration file. The addition of
configuration files allows homeserver admins to sanity check the
registration for suspicious regex strings.
Application services register "namespaces" of user IDs, room aliases and
room IDs. These namespaces are represented as regular expressions. An
application service is said to be "interested" in a given event if one
of the IDs in the event match the regular expression provided by the
application service, such as the room having an alias or ID in the
relevant namespaces. Similarly, the application service is said to be
interested in a given event if one of the application service's
namespaced users is the target of the event, or is a joined member of
the room where the event occurred.
An application service can also state whether they should be the only
ones who can manage a specified namespace. This is referred to as an
"exclusive" namespace. An exclusive namespace prevents humans and other
application services from creating/deleting entities in that namespace.
Typically, exclusive namespaces are used when the rooms represent real
rooms on another service (e.g. IRC). Non-exclusive namespaces are used
when the application service is merely augmenting the room itself (e.g.
providing logging or searching facilities). Namespaces are represented
by POSIX extended regular expressions and look like:
users:
- exclusive: true
regex: "@_irc_bridge_.*"
Application services may define the following namespaces (with none
being explicitly required):
<table>
<colgroup>
<colstyle="width: 24%"/>
<colstyle="width: 75%"/>
</colgroup>
<thead>
<trclass="header">
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<trclass="odd">
<td>users</td>
<td>Events which are sent from certain users.</td>
</tr>
<trclass="even">
<td>aliases</td>
<td>Events which are sent in rooms with certain room aliases.</td>
</tr>
<trclass="odd">
<td>rooms</td>
<td>Events which are sent in rooms with certain room IDs.</td>
</tr>
</tbody>
</table>
Each individual namespace MUST declare the following fields:
<table>
<colgroup>
<colstyle="width: 12%"/>
<colstyle="width: 87%"/>
</colgroup>
<thead>
<trclass="header">
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<trclass="odd">
<td>exclusive</td>
<td><strong>Required</strong> A true or false value stating whether this application service has exclusive access to events within this namespace.</td>
</tr>
<trclass="even">
<td>regex</td>
<td><strong>Required</strong> A regular expression defining which values this namespace includes.</td>
</tr>
</tbody>
</table>
Exclusive user and alias namespaces should begin with an underscore
after the sigil to avoid collisions with other users on the homeserver.
Application services should additionally attempt to identify the service
they represent in the reserved namespace. For example, `@_irc_.*` would
be a good namespace to register for an application service which deals
with IRC.
The registration is represented by a series of key-value pairs, which
this specification will present as YAML. See below for the possible
options along with their explanation:
<table>
<colgroup>
<colstyle="width: 11%"/>
<colstyle="width: 88%"/>
</colgroup>
<thead>
<trclass="header">
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<trclass="odd">
<td>id</td>
<td><strong>Required.</strong> A unique, user-defined ID of the application service which will never change.</td>
</tr>
<trclass="even">
<td>url</td>
<td><strong>Required.</strong> The URL for the application service. May include a path after the domain name. Optionally set to <code>null</code> if no traffic is required.</td>
</tr>
<trclass="odd">
<td>as_token</td>
<td><strong>Required.</strong> A unique token for application services to use to authenticate requests to Homeservers.</td>
</tr>
<trclass="even">
<td>hs_token</td>
<td><strong>Required.</strong> A unique token for Homeservers to use to authenticate requests to application services.</td>
</tr>
<trclass="odd">
<td>sender_localpart</td>
<td><strong>Required.</strong> The localpart of the user associated with the application service.</td>
</tr>
<trclass="even">
<td>namespaces</td>
<td><strong>Required.</strong> A list of <code>users</code>, <code>aliases</code> and <code>rooms</code> namespaces that the application service controls.</td>
</tr>
<trclass="odd">
<td>rate_limited</td>
<td>Whether requests from masqueraded users are rate-limited. The sender is excluded.</td>
</tr>
<trclass="even">
<td>protocols</td>
<td>The external protocols which the application service provides (e.g. IRC).</td>
</tr>
</tbody>
</table>
An example registration file for an IRC-bridging application service is