Email and push notifications

Antimatter sends email for invitations, password resets, verification and missed messages, and push notifications to the mobile app through a push proxy. Neither works until you configure it.

Outgoing email (SMTP)

Antimatter sends email through an SMTP server you provide: your organisation's mail server, or a transactional email service. Without it, people can't reset a forgotten password, email invitations and verification don't arrive, and nobody gets email notifications of missed messages.

Set it in System Console › Environment › SMTP, or with variables:

SettingKey and variableDefault
SMTP ServerEmailSettings.SMTPServer, AM_EMAILSETTINGS_SMTPSERVERlocalhost
SMTP Server PortEmailSettings.SMTPPort, AM_EMAILSETTINGS_SMTPPORT10025
Enable SMTP AuthenticationEmailSettings.EnableSMTPAuth, AM_EMAILSETTINGS_ENABLESMTPAUTHoff without connection security, on with it
SMTP Server UsernameEmailSettings.SMTPUsername, AM_EMAILSETTINGS_SMTPUSERNAMEempty
SMTP Server PasswordEmailSettings.SMTPPassword, AM_EMAILSETTINGS_SMTPPASSWORDempty
Connection SecurityEmailSettings.ConnectionSecurity, AM_EMAILSETTINGS_CONNECTIONSECURITYNone (empty); or TLS or STARTTLS
Skip Server Certificate VerificationEmailSettings.SkipServerCertificateVerificationoff. Leave it off in production.

Use STARTTLS on port 587 or TLS on port 465, as your provider says. Then click Test Connection on the same page: Antimatter sends a test email to your own address.

A typical setup with Docker Compose, in compose.override.yaml next to compose.yaml:

services:
  antimatter:
    environment:
      AM_EMAILSETTINGS_SMTPSERVER: smtp.example.com
      AM_EMAILSETTINGS_SMTPPORT: "587"
      AM_EMAILSETTINGS_CONNECTIONSECURITY: STARTTLS
      AM_EMAILSETTINGS_ENABLESMTPAUTH: "true"
      AM_EMAILSETTINGS_SMTPUSERNAME: chat@example.com
      AM_EMAILSETTINGS_SMTPPASSWORD: ${SMTP_PASSWORD}
      AM_EMAILSETTINGS_FEEDBACKNAME: Antimatter
      AM_EMAILSETTINGS_FEEDBACKEMAIL: chat@example.com
      AM_EMAILSETTINGS_REPLYTOADDRESS: chat@example.com

Put SMTP_PASSWORD in .env. The site's compose file puts the server on the default network, which has Internet access, so it can reach an outside SMTP server.

Sender and notification email settings

In System Console › Site Configuration › Notifications:

SettingKeyDefault
Enable Email NotificationsEmailSettings.SendEmailNotificationson
Notification Display NameEmailSettings.FeedbackNameempty
Notification From AddressEmailSettings.FeedbackEmailtest@example.com: change it
Notification Reply-To AddressEmailSettings.ReplyToAddresstest@example.com: change it
Support Email AddressSupportSettings.SupportEmailempty
Notification Footer Mailing AddressEmailSettings.FeedbackOrganizationempty
Email Notification ContentsEmailSettings.EmailNotificationContentsTypeSend full message contents (full), or a generic description with only the sender's name (generic)
Enable Email BatchingEmailSettings.EnableEmailBatchingoff. On, people can choose to get missed messages grouped in one email every 15 minutes or every hour, instead of one email each.
Use Channel Name in Email NotificationsEmailSettings.UseChannelInEmailNotificationsoff
Enable Preview Mode BannerEmailSettings.EnablePreviewModeBanneron: while email notifications are off, a banner tells administrators that email isn't configured

The From address must be one your SMTP server is allowed to send as; set up SPF and DKIM for its domain, or the emails may land in spam folders.

Email-related sign-in settings (whether new accounts must verify their address, whether invitations can be sent by email) are in Sign-in and accounts.

Push notifications to the mobile app

How push works

Antimatter never talks to Apple or Google itself. For each notification, it calls a push proxy, which holds the mobile app's credentials and forwards the notification to Apple (APNs) for iPhones and to Google (Firebase Cloud Messaging) for Android phones. Apple and Google only deliver a notification when it is sent with the credentials of the app it's for. So a push proxy works with one build of the mobile app: the one whose credentials it holds.

  • Antimatter doesn't run a public push proxy. You run the Antimatter push proxy yourself, with the credentials of the mobile app build your users install.
  • Antimatter never sends notifications to Mattermost's push services, test or hosted: they only deliver to Mattermost's own mobile apps. If the server is set to one of their addresses (such as https://push-test.mattermost.com, which older Mattermost configurations use), it sends nothing and logs a warning at startup.

A new server has no push notification server, so it sends no push notifications until you set the address of your push proxy. Until then, the mobile app works but gets no notifications.

Run the push proxy

The push proxy is in the push-proxy repository. Its README explains how to get the two credentials, which come from the accounts that publish your build of the mobile app:

  • Android: a service account file of the Firebase project your Android build uses.
  • iOS: an APNs authentication key (AuthKey_<KEY ID>.p8) of the Apple developer account that publishes your iOS build, with its key ID and team ID.

Put them next to compose.yaml, with the proxy's configuration file:

push-proxy/
  config/antimatter-push-proxy.json
  certs/AuthKey_ABCDE12345.p8
  certs/firebase-service-account.json

push-proxy/config/antimatter-push-proxy.json, with your bundle identifier, key ID and team ID:

{
    "ListenAddress": ":8066",
    "ThrottlePerSec": 300,
    "ThrottleMemoryStoreSize": 50000,
    "ThrottleVaryByHeader": "X-Forwarded-For",
    "EnableMetrics": false,
    "SendTimeoutSec": 30,
    "RetryTimeoutSec": 8,
    "ApplePushSettings": [
        {
            "Type": "apple_rn",
            "ApplePushUseDevelopment": false,
            "ApplePushTopic": "chat.antimatter.app",
            "AppleAuthKeyFile": "./certs/AuthKey_ABCDE12345.p8",
            "AppleAuthKeyID": "ABCDE12345",
            "AppleTeamID": "FGHIJ67890"
        }
    ],
    "AndroidPushSettings": [
        {
            "Type": "android_rn",
            "ServiceFileLocation": "./certs/firebase-service-account.json"
        }
    ],
    "EnableConsoleLog": true,
    "EnableFileLog": false,
    "LogFormat": "plain",
    "LogLevel": "info"
}

ApplePushTopic is the iOS bundle identifier of your build. ApplePushUseDevelopment is true only for builds installed from Xcode. Calls ring on iPhones through VoIP pushes, which use the same key and need nothing more here.

The site has a ready-made addition to the compose file, compose.push.example.yaml. It runs the published image, ghcr.io/antimatterchat/push-proxy:latest.

curl -fsSLO https://antimatter.chat/compose.push.example.yaml
docker compose -f compose.yaml -f compose.push.example.yaml --profile push up -d
docker compose -f compose.yaml -f compose.push.example.yaml logs push-proxy

At start, the proxy's log names each push target it set up, and logs an error for any whose credentials it can't load. The proxy publishes no port: only Antimatter reaches it, on the compose network.

Without Docker, install the push proxy's .deb or .rpm package instead: see The GIF service and push proxy packages.

The push proxy doesn't check who calls it. Don't expose it to the Internet. If it runs on another host, put it behind HTTPS and restrict who can reach it: notifications can contain message text.

Point Antimatter at the proxy

In System Console › Environment › Push Notification Server, set Enable Push Notifications to Send push notifications through your own push proxy, and Push Notification Server to http://push-proxy:8066 (or the proxy's HTTPS address if it runs elsewhere). The page can't be saved with this option and no address. To stop sending push notifications, choose Do not send push notifications. Or with variables on the antimatter service:

AM_EMAILSETTINGS_SENDPUSHNOTIFICATIONS: "true"
AM_EMAILSETTINGS_PUSHNOTIFICATIONSERVER: http://push-proxy:8066

To check: sign in with the mobile app, put it in the background and have another account mention you. If nothing arrives, look for push in Antimatter's log and in the proxy's log: they say whether the device type is unknown, a key was rejected, or the device belongs to another app build.

What notifications contain

System Console › Site Configuration › Notifications › Push Notification Contents (EmailSettings.PushNotificationContents):

OptionValue
Generic description with only sender namegeneric_no_channel
Generic description with sender and channel namesgeneric
Full message content sent in the notification payload (default)full
Full message content fetched from the server on receiptid_loaded

With id_loaded, the notification that goes through the proxy, Apple and Google carries only an id, and the app fetches the message from your server: message text never passes through their services. It is the best choice when messages are confidential.

Large Channel Notification Threshold, on the Push Notification Server page, (TeamSettings.MaxNotificationsPerChannel, 1000 by default) is the largest number of members a channel can have for @here, @all and @channel to work. In bigger channels, those mentions and the typing indicators are turned off.