Notifications and Messaging

How to integrate a notifications with the Ferris Platform.

Ferris provides you access to over 40 notification services such as Slack, Email and Telegram.

Ferris FX uses the Apprise Python Libs as an engine for notifiation dispatch. The power of Apprise gives you access to over 40 notification services. A complete list is provided in a table and the end of the document.

In order to send notifications from your package you need is to create and emit a pre-defined event type.

How to send notifications from your package

In order to send notifications from your package you need to send a ‘ferris.notifications.apprise.notification’ event from your package

You can do it like so.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
from fx_ef import context

# Please note that the value for the url_template is the name used within the config 
# For a specifc URL template in configurations.
# Please see configurations sample on how to configure

data = {
"url_template": "slack_1",
"body": "This is the content",
"title": "This is the subject"
}

event_type = "ferris.notifications.apprise.notification"
context.events.send(event_type, data)

How does it Work?

There are 2 approaches to implementing the notifications support.

  • Implementation within a Ferris Service
  • Implementation in an Exit Gateway

The 2nd option is used in platforms which are behind a firewall and therefore require the gateway to be outside the firewall for accessing external services. In these cases the adapter runs as a separate container.

Irrespective of the infrastructure implementation the service internal API (as illustrated above) does not change.

The following documentation refers to Option 1.

Pre-Requisites

In order to send notifcations

  • The Apprise Libs must be present in the Executor Image.

  • You must have the Apprise Notifications Packages installed and running. You can find the code base further below in document.

  • You must upload a secrets.json file for the Apprise Notifications Package. Please note that you should maintain a separate copy of the configs since this will not be displayed in your configuration manager since it contains credentials.

  • A sample configuration file is provided below. Please use the table based on Apprise documentation to understand the URL Template structure.

  • Once the Apprise Notifications Package is installed along with the configurations you must link the package to be triggered by the ‘ferris.notifications.apprise.notification’ event.

The Ferris Apprise Package

The following is code for an Ferris executor package to send apprise based notifications.

To send a notification from within your python application, just do the following:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import apprise
from fx_ef import context

# Getting the incoming parameters
url_template_name = context.params.get('url_template')

# Create an Apprise instance
apobj = apprise.Apprise()

# Setting up the Apprise object with URLs
# The URL is retreived from the uploaded secrets.json
apobj.add(context.secrets.get(url_template_name))

try: 
  apobj.notify(
    body=get_param('body'),
    title=get_param('title'),
  )
except Exception as ex:
  print(ex)

Configuration

The following is a sample configuration which is uploaded as a secrets.json file for the Ferris Apprise Package.

The configuration consists of a set of named URL templates. With each url_template being based on the Apprise URL schema as shown in the sections further in document.

While you are free to name URL templates as you wish it is preferred to prefix them with an indication of the underlying service being used to send notifications.

1
2
3
4
5
6
7
8
{
  "slack_1": "slack://TokenA/TokenB/TokenC/",
  "slack_2": "slack://TokenA/TokenB/TokenC/Channel",
  "slack_3":"slack://botname@TokenA/TokenB/TokenC/Channel",
  "slack_4": "slack://user@TokenA/TokenB/TokenC/Channel1/Channel2/ChannelN",
  "telegram_1": "tgram://bottoken/ChatID",
  "telegram_2": "tgram://bottoken/ChatID1/ChatID2/ChatIDN"
}

The configurations must be added to a secrets.json file and uploaded as part of the apprise_package.

The apprise package must be configured to be triggered by the ‘ferris.notifications.apprise.notification’ event.

The table below identifies the services this tool supports and some example service urls you need to use in order to take advantage of it.

Click on any of the services listed below to get more details on how you can configure Apprise to access them.

Notification Service Service ID Default Port Example Syntax
Apprise API apprise:// or apprises:// (TCP) 80 or 443 apprise://hostname/Token
AWS SES ses:// (TCP) 443 ses://user@domain/AccessKeyID/AccessSecretKey/RegionName
ses://user@domain/AccessKeyID/AccessSecretKey/RegionName/email1/email2/emailN
Discord discord:// (TCP) 443 discord://webhook_id/webhook_token
discord://avatar@webhook_id/webhook_token
Emby emby:// or embys:// (TCP) 8096 emby://user@hostname/
emby://user:password@hostname
Enigma2 enigma2:// or enigma2s:// (TCP) 80 or 443 enigma2://hostname
Faast faast:// (TCP) 443 faast://authorizationtoken
FCM fcm:// (TCP) 443 fcm://project@apikey/DEVICE_ID
fcm://project@apikey/#TOPIC
fcm://project@apikey/DEVICE_ID1/#topic1/#topic2/DEVICE_ID2/
Flock flock:// (TCP) 443 flock://token
flock://botname@token
flock://app_token/u:userid
flock://app_token/g:channel_id
flock://app_token/u:userid/g:channel_id
Gitter gitter:// (TCP) 443 gitter://token/room
gitter://token/room1/room2/roomN
Google Chat gchat:// (TCP) 443 gchat://workspace/key/token
Gotify gotify:// or gotifys:// (TCP) 80 or 443 gotify://hostname/token
gotifys://hostname/token?priority=high
Growl growl:// (UDP) 23053 growl://hostname
growl://hostname:portno
growl://password@hostname
growl://password@hostname:port
Note: you can also use the get parameter version which can allow the growl request to behave using the older v1.x protocol. An example would look like: growl://hostname?version=1
Home Assistant hassio:// or hassios:// (TCP) 8123 or 443 hassio://hostname/accesstoken
hassio://user@hostname/accesstoken
hassio://user:password@hostname:port/accesstoken
hassio://hostname/optional/path/accesstoken
IFTTT ifttt:// (TCP) 443 ifttt://webhooksID/Event
ifttt://webhooksID/Event1/Event2/EventN
ifttt://webhooksID/Event1/?+Key=Value
ifttt://webhooksID/Event1/?-Key=value1
Join join:// (TCP) 443 join://apikey/device
join://apikey/device1/device2/deviceN/
join://apikey/group
join://apikey/groupA/groupB/groupN
join://apikey/DeviceA/groupA/groupN/DeviceN/
KODI kodi:// or kodis:// (TCP) 8080 or 443 kodi://hostname
kodi://user@hostname
kodi://user:password@hostname:port
Kumulos kumulos:// (TCP) 443 kumulos://apikey/serverkey
LaMetric Time lametric:// (TCP) 443 lametric://apikey@device_ipaddr
lametric://apikey@hostname:port
lametric://client_id@client_secret
Mailgun mailgun:// (TCP) 443 mailgun://user@hostname/apikey
mailgun://user@hostname/apikey/email
mailgun://user@hostname/apikey/email1/email2/emailN
mailgun://user@hostname/apikey/?name=“From%20User”
Matrix matrix:// or matrixs:// (TCP) 80 or 443 matrix://hostname
matrix://user@hostname
matrixs://user:pass@hostname:port/#room_alias
matrixs://user:pass@hostname:port/!room_id
matrixs://user:pass@hostname:port/#room_alias/!room_id/#room2
matrixs://token@hostname:port/?webhook=matrix
matrix://user:token@hostname/?webhook=slack&format=markdown
Mattermost mmost:// or mmosts:// (TCP) 8065 mmost://hostname/authkey
mmost://hostname:80/authkey
mmost://user@hostname:80/authkey
mmost://hostname/authkey?channel=channel
mmosts://hostname/authkey
mmosts://user@hostname/authkey
Microsoft Teams msteams:// (TCP) 443 msteams://TokenA/TokenB/TokenC/
MQTT mqtt:// or mqtts:// (TCP) 1883 or 8883 mqtt://hostname/topic
mqtt://user@hostname/topic
mqtts://user:pass@hostname:9883/topic
Nextcloud ncloud:// or nclouds:// (TCP) 80 or 443 ncloud://adminuser:pass@host/User
nclouds://adminuser:pass@host/User1/User2/UserN
NextcloudTalk nctalk:// or nctalks:// (TCP) 80 or 443 nctalk://user:pass@host/RoomId
nctalks://user:pass@host/RoomId1/RoomId2/RoomIdN
Notica notica:// (TCP) 443 notica://Token/
Notifico notifico:// (TCP) 443 notifico://ProjectID/MessageHook/
Office 365 o365:// (TCP) 443 o365://TenantID:AccountEmail/ClientID/ClientSecret
o365://TenantID:AccountEmail/ClientID/ClientSecret/TargetEmail
o365://TenantID:AccountEmail/ClientID/ClientSecret/TargetEmail1/TargetEmail2/TargetEmailN
OneSignal onesignal:// (TCP) 443 onesignal://AppID@APIKey/PlayerID
onesignal://TemplateID:AppID@APIKey/UserID
onesignal://AppID@APIKey/#IncludeSegment
onesignal://AppID@APIKey/Email
Opsgenie opsgenie:// (TCP) 443 opsgenie://APIKey
opsgenie://APIKey/UserID
opsgenie://APIKey/#Team
opsgenie://APIKey/*Schedule
opsgenie://APIKey/^Escalation
ParsePlatform parsep:// or parseps:// (TCP) 80 or 443 parsep://AppID:MasterKey@Hostname
parseps://AppID:MasterKey@Hostname
PopcornNotify popcorn:// (TCP) 443 popcorn://ApiKey/ToPhoneNo
popcorn://ApiKey/ToPhoneNo1/ToPhoneNo2/ToPhoneNoN/
popcorn://ApiKey/ToEmail
popcorn://ApiKey/ToEmail1/ToEmail2/ToEmailN/
popcorn://ApiKey/ToPhoneNo1/ToEmail1/ToPhoneNoN/ToEmailN
Prowl prowl:// (TCP) 443 prowl://apikey
prowl://apikey/providerkey
PushBullet pbul:// (TCP) 443 pbul://accesstoken
pbul://accesstoken/#channel
pbul://accesstoken/A_DEVICE_ID
pbul://accesstoken/email@address.com
pbul://accesstoken/#channel/#channel2/email@address.net/DEVICE
Push (Techulus) push:// (TCP) 443 push://apikey/
Pushed pushed:// (TCP) 443 pushed://appkey/appsecret/
pushed://appkey/appsecret/#ChannelAlias
pushed://appkey/appsecret/#ChannelAlias1/#ChannelAlias2/#ChannelAliasN
pushed://appkey/appsecret/@UserPushedID
pushed://appkey/appsecret/@UserPushedID1/@UserPushedID2/@UserPushedIDN
Pushover pover:// (TCP) 443 pover://user@token
pover://user@token/DEVICE
pover://user@token/DEVICE1/DEVICE2/DEVICEN
Note: you must specify both your user_id and token
PushSafer psafer:// or psafers:// (TCP) 80 or 443 psafer://privatekey
psafers://privatekey/DEVICE
psafer://privatekey/DEVICE1/DEVICE2/DEVICEN
Reddit reddit:// (TCP) 443 reddit://user:password@app_id/app_secret/subreddit
reddit://user:password@app_id/app_secret/sub1/sub2/subN
Rocket.Chat rocket:// or rockets:// (TCP) 80 or 443 rocket://user:password@hostname/RoomID/Channel
rockets://user:password@hostname:443/#Channel1/#Channel1/RoomID
rocket://user:password@hostname/#Channel
rocket://webhook@hostname
rockets://webhook@hostname/@User/#Channel
Ryver ryver:// (TCP) 443 ryver://Organization/Token
ryver://botname@Organization/Token
SendGrid sendgrid:// (TCP) 443 sendgrid://APIToken:FromEmail/
sendgrid://APIToken:FromEmail/ToEmail
sendgrid://APIToken:FromEmail/ToEmail1/ToEmail2/ToEmailN/
ServerChan serverchan:// (TCP) 443 serverchan://token/
SimplePush spush:// (TCP) 443 spush://apikey
spush://salt:password@apikey
spush://apikey?event=Apprise
Slack slack:// (TCP) 443 slack://TokenA/TokenB/TokenC/
slack://TokenA/TokenB/TokenC/Channel
slack://botname@TokenA/TokenB/TokenC/Channel
slack://user@TokenA/TokenB/TokenC/Channel1/Channel2/ChannelN
SMTP2Go smtp2go:// (TCP) 443 smtp2go://user@hostname/apikey
smtp2go://user@hostname/apikey/email
smtp2go://user@hostname/apikey/email1/email2/emailN
smtp2go://user@hostname/apikey/?name=“From%20User”
Streamlabs strmlabs:// (TCP) 443 strmlabs://AccessToken/
strmlabs://AccessToken/?name=name&identifier=identifier&amount=0&currency=USD
SparkPost sparkpost:// (TCP) 443 sparkpost://user@hostname/apikey
sparkpost://user@hostname/apikey/email
sparkpost://user@hostname/apikey/email1/email2/emailN
sparkpost://user@hostname/apikey/?name=“From%20User”
Spontit spontit:// (TCP) 443 spontit://UserID@APIKey/
spontit://UserID@APIKey/Channel
spontit://UserID@APIKey/Channel1/Channel2/ChannelN
Syslog syslog:// (UDP) 514 (if hostname specified) syslog://
syslog://Facility
syslog://hostname
syslog://hostname/Facility
Telegram tgram:// (TCP) 443 tgram://bottoken/ChatID
tgram://bottoken/ChatID1/ChatID2/ChatIDN
Twitter twitter:// (TCP) 443 twitter://CKey/CSecret/AKey/ASecret
twitter://user@CKey/CSecret/AKey/ASecret
twitter://CKey/CSecret/AKey/ASecret/User1/User2/User2
twitter://CKey/CSecret/AKey/ASecret?mode=tweet
Twist twist:// (TCP) 443 twist://pasword:login
twist://password:login/#channel
twist://password:login/#team:channel
twist://password:login/#team:channel1/channel2/#team3:channel
XMPP xmpp:// or xmpps:// (TCP) 5222 or 5223 xmpp://user:password@hostname
xmpps://user:password@hostname:port?jid=user@hostname/resource
xmpps://user:password@hostname/target@myhost, target2@myhost/resource
Webex Teams (Cisco) wxteams:// (TCP) 443 wxteams://Token
Zulip Chat zulip:// (TCP) 443 zulip://botname@Organization/Token
zulip://botname@Organization/Token/Stream
zulip://botname@Organization/Token/Email

SMS Notification Support

Notification Service Service ID Default Port Example Syntax
AWS SNS sns:// (TCP) 443 sns://AccessKeyID/AccessSecretKey/RegionName/+PhoneNo
sns://AccessKeyID/AccessSecretKey/RegionName/+PhoneNo1/+PhoneNo2/+PhoneNoN
sns://AccessKeyID/AccessSecretKey/RegionName/Topic
sns://AccessKeyID/AccessSecretKey/RegionName/Topic1/Topic2/TopicN
ClickSend clicksend:// (TCP) 443 clicksend://user:pass@PhoneNo
clicksend://user:pass@ToPhoneNo1/ToPhoneNo2/ToPhoneNoN
DAPNET dapnet:// (TCP) 80 dapnet://user:pass@callsign
dapnet://user:pass@callsign1/callsign2/callsignN
D7 Networks d7sms:// (TCP) 443 d7sms://user:pass@PhoneNo
d7sms://user:pass@ToPhoneNo1/ToPhoneNo2/ToPhoneNoN
DingTalk dingtalk:// (TCP) 443 dingtalk://token/
dingtalk://token/ToPhoneNo
dingtalk://token/ToPhoneNo1/ToPhoneNo2/ToPhoneNo1/
Kavenegar kavenegar:// (TCP) 443 kavenegar://ApiKey/ToPhoneNo
kavenegar://FromPhoneNo@ApiKey/ToPhoneNo
kavenegar://ApiKey/ToPhoneNo1/ToPhoneNo2/ToPhoneNoN
MessageBird msgbird:// (TCP) 443 msgbird://ApiKey/FromPhoneNo
msgbird://ApiKey/FromPhoneNo/ToPhoneNo
msgbird://ApiKey/FromPhoneNo/ToPhoneNo1/ToPhoneNo2/ToPhoneNoN/
MSG91 msg91:// (TCP) 443 msg91://AuthKey/ToPhoneNo
msg91://SenderID@AuthKey/ToPhoneNo
msg91://AuthKey/ToPhoneNo1/ToPhoneNo2/ToPhoneNoN/
Nexmo nexmo:// (TCP) 443 nexmo://ApiKey:ApiSecret@FromPhoneNo
nexmo://ApiKey:ApiSecret@FromPhoneNo/ToPhoneNo
nexmo://ApiKey:ApiSecret@FromPhoneNo/ToPhoneNo1/ToPhoneNo2/ToPhoneNoN/
Sinch sinch:// (TCP) 443 sinch://ServicePlanId:ApiToken@FromPhoneNo
sinch://ServicePlanId:ApiToken@FromPhoneNo/ToPhoneNo
sinch://ServicePlanId:ApiToken@FromPhoneNo/ToPhoneNo1/ToPhoneNo2/ToPhoneNoN/
sinch://ServicePlanId:ApiToken@ShortCode/ToPhoneNo
sinch://ServicePlanId:ApiToken@ShortCode/ToPhoneNo1/ToPhoneNo2/ToPhoneNoN/
Twilio twilio:// (TCP) 443 twilio://AccountSid:AuthToken@FromPhoneNo
twilio://AccountSid:AuthToken@FromPhoneNo/ToPhoneNo
twilio://AccountSid:AuthToken@FromPhoneNo/ToPhoneNo1/ToPhoneNo2/ToPhoneNoN/
twilio://AccountSid:AuthToken@FromPhoneNo/ToPhoneNo?apikey=Key
twilio://AccountSid:AuthToken@ShortCode/ToPhoneNo
twilio://AccountSid:AuthToken@ShortCode/ToPhoneNo1/ToPhoneNo2/ToPhoneNoN/

Desktop Notification Support

Notification Service Service ID Default Port Example Syntax
Linux DBus Notifications dbus://
qt://
glib://
kde://
n/a dbus://
qt://
glib://
kde://
Linux Gnome Notifications gnome:// n/a gnome://
MacOS X Notifications macosx:// n/a macosx://
Windows Notifications windows:// n/a windows://

Email Support

Service ID Default Port Example Syntax
mailto:// (TCP) 25 mailto://userid:pass@domain.com
mailto://domain.com?user=userid&pass=password
mailto://domain.com:2525?user=userid&pass=password
mailto://user@gmail.com&pass=password
mailto://mySendingUsername:mySendingPassword@example.com?to=receivingAddress@example.com
mailto://userid:password@example.com?smtp=mail.example.com&from=noreply@example.com&name=no%20reply
mailtos:// (TCP) 587 mailtos://userid:pass@domain.com
mailtos://domain.com?user=userid&pass=password
mailtos://domain.com:465?user=userid&pass=password
mailtos://user@hotmail.com&pass=password
mailtos://mySendingUsername:mySendingPassword@example.com?to=receivingAddress@example.com
mailtos://userid:password@example.com?smtp=mail.example.com&from=noreply@example.com&name=no%20reply

Apprise have some email services built right into it (such as yahoo, fastmail, hotmail, gmail, etc) that greatly simplify the mailto:// service. See more details here.

Custom Notifications

Post Method Service ID Default Port Example Syntax
Form form:// or form:// (TCP) 80 or 443 form://hostname
form://user@hostname
form://user:password@hostname:port
form://hostname/a/path/to/post/to
JSON json:// or jsons:// (TCP) 80 or 443 json://hostname
json://user@hostname
json://user:password@hostname:port
json://hostname/a/path/to/post/to
XML xml:// or xmls:// (TCP) 80 or 443 xml://hostname
xml://user@hostname
xml://user:password@hostname:port
xml://hostname/a/path/to/post/to

Last modified November 24, 2023: update (f4bc5ea)