How to Set Up Email and Webhook Notifications in TREK Using SMTP

TREK delivers notifications through SMTP email and webhook channels by storing credentials in the app_settings table and activating them through the Admin UI, with delivery handled by nodemailer for email and validated HTTP POST requests for webhooks.

Setting up external notifications in the TREK travel management platform requires configuring both the server-side SMTP transport and webhook endpoints. This guide covers the complete implementation based on the source code in mauriceboe/TREK, including the specific configuration keys, database storage patterns, and admin interface workflows needed to enable reliable message delivery.

SMTP Configuration Architecture

The email notification system relies on a centralized configuration getter that prioritizes environment variables while falling back to database-stored settings.

Environment Variables and Database Storage

In server/src/services/notifications.ts, the getSmtpConfig function (lines 44-52) implements a hierarchical lookup strategy. It first checks process.env.SMTP_* variables, then queries the app_settings table via getAppSetting. If the required host, port, or from values are missing, the function returns null, which effectively disables the email channel at runtime.

Required SMTP Parameters

To enable email delivery, you must provide these five configuration keys:

  • smtp_host – The SMTP server hostname (e.g., smtp.gmail.com)
  • smtp_port – TCP port (typically 587 for TLS or 465 for SSL)
  • smtp_user – Authentication username (optional but recommended)
  • smtp_pass – Encrypted password stored in app_settings (decrypted at runtime using decrypt_api_key)
  • smtp_from – The "From" address displayed to recipients (e.g., notifications@yourdomain.com)

The sendEmail function (lines 52-78) in notifications.ts uses these values to create a nodemailer transport and dispatch HTML-formatted messages built by buildEmailHtml.

Enabling Email Notifications in the Admin UI

Administrators activate SMTP through the React-based admin interface located at client/src/pages/admin/AdminNotificationsTab.tsx (lines 60-68).

  1. Navigate to Settings → Notifications in the Admin panel.
  2. Expand the Email (SMTP) panel (translation key: admin.notifications.emailPanel.title).
  3. Enter the SMTP host, port, username, and password in the provided fields.
  4. Click Save to persist values to app_settings and update the notification_channels record to include email.

The notificationPreferencesService.ts file contains getActiveChannels (lines 61-65), which checks this configuration to determine if the email channel is globally available before attempting delivery.

Configuring Webhook Notifications

TREK supports webhook delivery for external integrations like Discord or Slack, with configuration available at both admin and user levels.

Admin-Level Webhook Setup

In the same Admin → Notifications tab where you configure SMTP:

  1. Expand the Webhook panel (admin.notifications.webhookPanel.title).
  2. Enter a complete HTTP(S) URL (e.g., https://discord.com/api/webhooks/...).
  3. Save the setting to store the value as admin_webhook_url (encrypted in the database).

The sendWebhook function (lines 12-22) in notifications.ts validates this URL against an SSRF guard, formats the payload for Discord or Slack compatibility using buildWebhookBody, and executes a POST request.

User-Level Webhook URLs

Individual users can override the admin webhook by setting a personal URL in their account settings. The system retrieves this value via getUserWebhookUrl (lines 104-107) in notifications.ts, which queries the settings table for user-specific webhook configurations.

Testing Your Configuration

TREK provides built-in test endpoints to verify both channels before production use.

Test SMTP Delivery:

import { testSmtp } from '@trek/server/src/services/notifications';

async function verifyEmail() {
  const result = await testSmtp('admin@example.com');
  console.log(result); // { success: true }
}
verifyEmail();

Test Webhook Delivery:

import { testWebhook } from '@trek/server/src/services/notifications';

async function verifyWebhook() {
  const result = await testWebhook('https://hooks.slack.com/services/AAA/BBB/CCC');
  console.log(result); // { success: true }
}
verifyWebhook();

These functions create test transports and payloads without triggering actual notification events, returning { success: true } upon successful delivery.

Runtime Delivery Logic

When a notification event occurs, the server executes the following sequence:

  1. Channel Validation: Calls getAvailableChannels() to verify that SMTP configuration exists for email and that notification_channels includes the webhook flag.
  2. Email Processing: If enabled, sendEmail builds the HTML body and dispatches via nodemailer.sendMail.
  3. Webhook Processing: If enabled, sendWebhook POSTs a JSON payload containing the event title, body, and trip details.
  4. Fallback Behavior: If SMTP is not configured, the email channel is silently skipped and the event is logged only in-app.

Summary

  • SMTP Setup requires five parameters (smtp_host, smtp_port, smtp_user, smtp_pass, smtp_from) stored in app_settings or environment variables, read by getSmtpConfig in notifications.ts.
  • Admin Activation happens through the Notifications tab in AdminNotificationsTab.tsx, which updates the notification_channels configuration.
  • Webhook Configuration supports both admin-level (admin_webhook_url) and user-level settings via getUserWebhookUrl.
  • Security includes SSRF protection for webhook URLs and encrypted storage for SMTP passwords using decrypt_api_key.
  • Testing is available through testSmtp() and testWebhook() helper functions before enabling production notifications.

Frequently Asked Questions

How does TREK store SMTP passwords securely?

TREK encrypts the smtp_pass value when saving to the app_settings table. At runtime, the sendEmail function in server/src/services/notifications.ts decrypts the password using decrypt_api_key before passing credentials to the nodemailer transport, ensuring passwords are never stored in plain text.

Can I use different SMTP servers for different users?

No. TREK implements a global SMTP configuration via getSmtpConfig that applies to all email notifications across the instance. While individual users can set personal webhook URLs via getUserWebhookUrl, the SMTP transport is shared and configured exclusively through the admin panel or environment variables.

What happens if SMTP configuration is missing or invalid?

If getSmtpConfig cannot retrieve valid host, port, and from values, it returns null, causing getAvailableChannels to exclude email from active channels. The notification system silently skips email delivery and logs the event only in-app, without raising runtime errors that would disrupt the user experience.

Does TREK support Discord and Slack webhook formats natively?

Yes. The sendWebhook function in notifications.ts (lines 12-22) automatically formats the JSON payload for Discord and Slack compatibility. It extracts the webhook URL from either the admin settings or user preferences and POSTs a structured body containing the event title, notification text, and trip link, requiring no manual payload formatting.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →