Skip to main content

Single Mail

This service listen for ActivityPub activities in all users' inboxes and turns them into email notification using the ActivityMappingService.


1. Add mappings for the activities

If you want an activity to be sent as an email notification, it must be mapped using the ActivityMappingService

If you use the default template provided, the following properties should be mapped:

  • title
  • description
  • actionName
  • actionLink

Here's an example:

const { ActivityMappingService } = require('@semapps/activitypub');

module.exports = {
mixins: [ActivityMappingService],
settings: {
mappers: [
match: {
type: 'Announce',
object: {
type: 'Create',
object: {
type: 'Event'
mapping: {
title: '{{}}',
description: '{{activity.object.object.description}}',
actionName: 'View',
actionLink: '/Event/{{activity.object.object.url}}'

You may map other properties, which will be available in a custom template or passed to the filterNotification method (see below).

2. Setup the SingleMailNotificationsService

const { SingleMailNotificationsService } = require('@semapps/notifications');
const QueueMixin = require('moleculer-bull');

module.exports = {
mixins: [SingleMailNotificationsService, QueueMixin('redis://localhost:6379/0')],
settings: {
defaultLocale: 'en',
defaultFrontUrl: '', // Base URL for the action links
color: '#E2003B', // Color of the mail buttons
delay: 0, // Delay (in ms) before processing notifications
// The following settings are from the moleculer-mail mixin used to send emails
// See
from: `"My service" <>`,
transport: {},
// Directory with the template. It looks for a template named 'digest'
templateFolder: path.join(__dirname, '../templates'),
// Global data to be used in the template
data: {}
methods: {
// Optional method called for each notification
// Return true if you want the notification to be sent by email
async filterNotification(notification, activity, recipientUri) {
return true;
// Method called to format the actionLink prop of each notification
// Overwrite it if you have custom needs
async formatLink(link, recipientUri) {
if (link && !link.startsWith('http')) {
return urlJoin(this.settings.defaultFrontUrl, link);
} else {
return link;

If you want some notifications to be sent immediately in single mails, and others in a digest, you should add a new property to the mappings (for example: immediate: true/false) and use the filterNotification method in both services to differentiate the notifications.