Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Muhammadbugaje/NAMETS_Website/llms.txt

Use this file to discover all available pages before exploring further.

NAMETS uses n8n for automated email notifications triggered by platform events. Rather than running background tasks inside Django, the platform exposes a lightweight REST API that an n8n workflow polls on a schedule. When new announcements are published or upcoming events are detected, n8n fetches the data, retrieves the list of active subscribers, and dispatches personalized emails — all without any code changes on the Django side. This architecture keeps the web server stateless and lets the notification logic be edited visually inside n8n.

Authentication: N8NAuthentication

All API endpoints consumed by n8n are protected by a custom DRF authentication class defined in utils/auth.py. The class reads a token from the X-N8N-Token HTTP header and compares it against the N8N_API_TOKEN setting. If the header is absent or the value does not match, the request is rejected immediately.
from django.conf import settings
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed

class N8NAuthentication(BaseAuthentication):
    def authenticate(self, request):
        token = request.headers.get('X-N8N-Token')
        if not token or token != settings.N8N_API_TOKEN:
            raise AuthenticationFailed('Invalid or missing token')
        return (None, None)  # No user, just authenticated
return (None, None) signals to DRF that the request is authenticated but has no associated Django user object. This is intentional — n8n is a machine client, not a human user.

Environment Variables

N8N_API_TOKEN
string
required
A long-lived API token generated inside your n8n instance (Settings → n8n API → Create API Key). The NAMETS platform reads this from settings.N8N_API_TOKEN and validates every inbound API request against it. Must be identical on both the n8n side (stored as a credential) and the NAMETS side (stored as an environment variable).
N8N_WEBHOOK_URL
string
The full URL of the n8n webhook endpoint that NAMETS posts outbound events to. Declared in render.yaml with a default pointing to the Render-hosted n8n service. Override this if you run n8n on a different host.
N8N_WEBHOOK_URL=https://n8n-render-5s6o.onrender.com/webhook/namets-events
WEBHOOK_SECRET
string
A shared secret included in outbound webhook payloads from NAMETS to n8n. The n8n workflow should verify this value before processing the payload to prevent spoofed requests.

REST API Endpoints

n8n workflows call the following read-only endpoints. All endpoints require the X-N8N-Token header.
MethodPathDescription
GET/api/subscribers/Returns all active subscribers. Filter by ?announcements=1, ?events=1, or ?prayer=1 to get only those who opted into a specific notification type.
GET/api/announcements/new/Returns announcements published after a given timestamp. Pass ?since=<ISO8601> to narrow results. Defaults to the last 24 hours if since is omitted.
GET/api/events/upcoming/Returns events starting within the next N days. Pass ?days=<int> (default: 7).
GET/api/prayer/today/Returns the prayer schedule for the current day.

Calling the API from n8n

Use an HTTP Request node in your n8n workflow. Set the method to GET, add the X-N8N-Token header under Headers, and optionally append query parameters.
GET https://your-site.onrender.com/api/announcements/new/?since=2024-01-01T00:00:00Z
Headers:
  X-N8N-Token: your_n8n_api_token
GET https://your-site.onrender.com/api/subscribers/?announcements=1
Headers:
  X-N8N-Token: your_n8n_api_token
Store your_n8n_api_token as an n8n Credential of type “Header Auth” and reference it in every HTTP Request node. This avoids hardcoding the token in each workflow node.

Typical n8n Announcement Notification Workflow

1

Schedule trigger

Add a Schedule trigger node set to run every 15–60 minutes (or on a cron expression that matches your posting frequency).
2

Fetch new announcements

Add an HTTP Request node that calls GET /api/announcements/new/ with a dynamic since timestamp. Use an expression like {{ $now.minus(1, 'hour').toISO() }} for the since parameter.
3

Check if announcements exist

Add an IF node. If the response array is empty, stop the workflow. If it contains items, proceed to the next step.
4

Fetch active subscribers

Add a second HTTP Request node that calls GET /api/subscribers/?announcements=1 to retrieve all subscribers who opted into announcement notifications.
5

Loop and send emails

Add a Split In Batches or Loop Over Items node. For each subscriber, use an Email (Send) or Gmail node to send a personalized notification containing the new announcement details.

notify_announcements Management Command

The platform also ships a Django management command as a Django-native alternative to the n8n polling approach. It can be run via python manage.py notify_announcements or scheduled with a cron job.
The command queries for all active, currently-live announcements (those where publish_at ≤ now and expire_at ≥ now), limited to 5 for the initial implementation. It then fetches all active subscribers who have notify_announcements=True and calls send_notification_email() for each one, rendering the emails/new_announcements.html template with the announcement list and an unsubscribe URL.
# Run manually
python manage.py notify_announcements

# Or schedule with a cron job on your server
*/30 * * * * /path/to/venv/bin/python /path/to/manage.py notify_announcements
The n8n workflow approach is preferred for production because it avoids the need for a persistent cron daemon and provides a visual audit trail of every notification run.
Keep N8N_API_TOKEN secret at all times. Anyone who obtains this token can call all NAMETS API endpoints, read your full subscriber list including email addresses, and enumerate unpublished announcements. Rotate the token immediately if you suspect it has been leaked, and update it in both the Render environment and your n8n credentials store.

Build docs developers (and LLMs) love