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

> Learn to set up email and webhook notifications in TREK using SMTP. Configure credentials via the Admin UI for seamless alerts and integrate with nodemailer and HTTP POST.

- Repository: [Maurice/TREK](https://github.com/mauriceboe/TREK)
- Tags: how-to-guide
- Published: 2026-07-11

---

**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`](https://github.com/mauriceboe/TREK/blob/main/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`](https://github.com/mauriceboe/TREK/blob/main/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`](https://github.com/mauriceboe/TREK/blob/main/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`](https://github.com/mauriceboe/TREK/blob/main/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`](https://github.com/mauriceboe/TREK/blob/main/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`](https://github.com/mauriceboe/TREK/blob/main/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:**

```typescript
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:**

```typescript
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`](https://github.com/mauriceboe/TREK/blob/main/notifications.ts).
- **Admin Activation** happens through the **Notifications** tab in [`AdminNotificationsTab.tsx`](https://github.com/mauriceboe/TREK/blob/main/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`](https://github.com/mauriceboe/TREK/blob/main/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`](https://github.com/mauriceboe/TREK/blob/main/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.