foam3

Email Setup Guide with Foam

This step-by-step guide will help you set up and configure email notifications in your Foam application. We’ll use real examples from the Foam codebase to demonstrate each step.

Table of Contents

  1. Prerequisites
  2. Step 1: Configure Email Service
  3. Step 2: Set Up Email Templates
  4. Step 3: Configure Notification Settings
  5. Step 4: Implement Email Notifications
  6. Step 5: Testing
  7. Troubleshooting

Prerequisites

Before starting, ensure you have:

Step 1: Configure Email Service

  1. Create a new file deployment/your-environment/emailServiceConfig.jrl:
p({
  class: 'foam.core.notification.email.EmailServiceConfig',
  id: 'smtp',
  enabled: true,
  host: 'your-smtp-server.com',
  port: '587',
  username: 'your-username',
  password: 'your-password',
  authenticate: true,
  starttls: true,
  protocol: 'smtp'
})

The send rate is not part of this entry: it is set by the smtpAgentThrottle service (default 14 TPS, see foam3/src/foam/core/notification/email/services.jrl).

Example from Foam: See foam3/deployment/test/emailServiceConfig.jrl for a test configuration.

Step 2: Set Up Email Templates

  1. Create a new file deployment/your-environment/emailTemplates.jrl:
p({
  class: 'foam.core.notification.email.EmailTemplate',
  id: 'welcome-email',
  name: 'welcome-email',
  group: 'your-group',
  locale: 'en',
  displayName: '',
  subject: 'Welcome to '
})

Example from Foam: See foam3/deployment/test/emailTemplates.jrl for template examples.

  1. Create a new file deployment/your-environment/notificationTemplates.jrl:
p({
  class: 'foam.core.notification.Notification',
  id: 'welcome-notification',
  template: 'welcome-notification',
  emailName: 'welcome-email',
  groupId: 'your-group',
  notificationType: 'WELCOME'
})

Example from Foam: See foam3/deployment/test/notificationTemplates.jrl for notification template examples.

Step 3: Configure Notification Settings

  1. Create a new file deployment/your-environment/notificationSettings.jrl:
p({
  class: 'foam.core.notification.EmailSetting',
  id: 'user-email-setting',
  owner: userId,
  enabled: true
})

Example from Foam: See foam3/deployment/test/notificationSettings.jrl for settings examples.

Step 4: Implement Email Notifications

Option 1: Using Notification DAO Directly

Create a new Java class in your project:

package your.package.notification;

import foam.lang.X;
import foam.dao.DAO;
import foam.core.notification.Notification;
import java.util.HashMap;
import java.util.Map;

public class WelcomeEmailService {
    private final DAO notificationDAO;

    public WelcomeEmailService(X x) {
        this.notificationDAO = (DAO) x.get("notificationDAO");
    }

    public void sendWelcomeEmail(X x, long userId) {
        Notification notification = new Notification();
        notification.setTemplate("welcome-notification");
        notification.setEmailName("welcome-email");
        notification.setBody("Welcome to our application!");
        notification.setUserId(userId);

        Map<String, Object> emailArgs = new HashMap<>();
        emailArgs.put("templateSource", this.getClass().getName());
        notification.setEmailArgs(emailArgs);

        notificationDAO.put_(x, notification);
    }
}

Example from Foam: See foam3/src/foam/core/notification/test/EmailNotificationTest.js for a complete example.

Option 2: Using DAO Notification Rules

  1. Create a new rule action class:
package your.package.notification;

import foam.core.auth.User;
import foam.core.notification.DAONotificationRuleAction;
import foam.core.notification.Notification;
import foam.core.ruler.Rule;
import foam.core.ruler.RuleEngine;
import foam.dao.DAO;
import foam.lang.Agency;
import foam.lang.FObject;
import foam.lang.X;
import java.util.HashMap;
import java.util.Map;

public class UserCreatedNotificationRuleAction extends DAONotificationRuleAction {
    @Override
    public void applyAction(X x, FObject obj, FObject oldObj, RuleEngine ruler, Rule rule, Agency agency) {
        if (!(obj instanceof User)) return;

        User user = (User) obj;
        Map<String, Object> args = new HashMap<>();
        args.put("userName", user.getLegalName());
        args.put("templateSource", this.getClass().getName());

        Notification notification = new Notification();
        notification.setTemplate("welcome-notification");
        notification.setEmailName("welcome-email");
        notification.setBody("Welcome " + user.getLegalName() + "!");
        notification.setUserId(user.getId());
        notification.setEmailArgs(args);

        ((DAO) x.get("notificationDAO")).put_(x, notification);
    }
}
  1. Register the rule in deployment/your-environment/rules.jrl:
p({
  "class":"foam.core.ruler.Rule",
  "id":"your-package-notification-UserCreatedNotificationRule",
  "name":"UserCreatedNotificationRule",
  "documentation":"Generate notification to new user on user creation",
  "enabled":true,
  "ruleGroup": "auth",
  "daoKey": "localUserDAO",
  "operation": 0,
  "lifecycleState": 1,
  action: {
    "class": "your.package.notification.UserCreatedNotificationRuleAction"
  }
})

Example from Foam: See foam3/src/foam/core/notification/DAONotificationRuleAction.js for rule action examples.

Step 5: Testing

  1. Create a test configuration in deployment/test/emailServiceConfig.jrl:
p({
  class: 'foam.core.notification.email.EmailServiceConfig',
  id: 'test',
  enabled: false,
  pollInterval: 2,
  initialDelay: 1
})
  1. Create a test class:
package your.package.notification.test;

import foam.core.auth.Subject;
import foam.core.test.Test;
import foam.lang.X;
import foam.dao.ArraySink;
import foam.dao.DAO;
import foam.core.notification.Notification;
import foam.core.notification.email.EmailMessage;
import java.util.List;

public class WelcomeEmailTest extends Test {
    @Override
    public void runTest(X x) {
        // Create test notification
        Notification notification = new Notification();
        notification.setTemplate("welcome-notification");
        notification.setEmailName("welcome-email");
        notification.setBody("Test welcome message");
        notification.setUserId(((Subject) x.get("subject")).getUser().getId());

        // Save notification
        ((DAO) x.get("notificationDAO")).put_(x, notification);

        // Verify email was sent
        DAO emailMessageDAO = (DAO) x.get("emailMessageDAO");
        List<EmailMessage> messages = (List) ((ArraySink) emailMessageDAO.select(new ArraySink())).getArray();
        
        // Add your assertions here
    }
}

Example from Foam: See foam3/src/foam/core/notification/test/EmailNotificationTest.js for a complete test example.

Troubleshooting

Common Issues and Solutions

  1. Emails Not Sending
    • Check SMTP configuration in emailServiceConfig.jrl
    • Verify user email settings are enabled
    • Check user lifecycle state
    • Verify template exists and is enabled
    • Check notification DAO logs
  2. Template Variables Not Working
    • Ensure all required variables are provided in emailArgs
    • Check template syntax
    • Verify template locale matches user settings
    • Check notification DAO for template resolution issues
  3. Rate Limiting Issues
    • Adjust the rate of the smtpAgentThrottle service
    • Check SMTP provider limits
    • Monitor email sending logs
    • Implement rate limiting in your notification service if needed

Debugging Tips

  1. Enable debug logging in your email service configuration
  2. Use the test configuration to verify your setup
  3. Check the notification DAO logs for any errors
  4. Verify all required templates and settings are properly configured