Persona is an n8n workflow that delivers a personalized news digest by email. Users interact via a chatbot (register, login, manage preferences) and receive a daily newsletter curated by Claude AI from NewsAPI, Hacker News, and The Guardian.
Two workflows work together:
Persona DB— handles all database operations (auth, sessions, user CRUD). Imported first.Persona Main(persona.json) — the chat interface + scheduled newsletter dispatcher. CallsPersona DBas a sub-workflow.
Data is stored in three n8n Data Tables (not external databases).
Option A — Docker (recommended)
docker run -it --rm \
-p 5678:5678 \
-v ~/.n8n:/home/node/.n8n \
n8nio/n8nOption B — npm
npm install -g n8n
n8n startn8n is then available at http://localhost:5678. Create your account on first launch.
- A running n8n instance (self-hosted or cloud)
- API keys for:
- Anthropic (Claude Haiku)
- NewsAPI
- The Guardian
- An SMTP account configured in n8n credentials
- Python 3 (for the ID injection script)
In n8n, go to Data Tables and create three tables by importing the CSV files in this repo:
| Table name | CSV file | Key columns |
|---|---|---|
persona_users |
persona_users.csv |
username, passwordHash, email, interests, scheduleTime, scheduleTimezone, isActive, gdprConsent, sendNow, ... |
persona_sessions |
persona_sessions.csv |
token, username, expiresAt |
persona_login_attempts |
persona_login_attempts.csv |
attemptKey, count, resetAt |
The CSV files contain a
_schema_initplaceholder row that defines the columns. You can delete it after import.
After creation, note the ID of each table — visible in the URL when you open it:
/data-table/<ID>
- In n8n go to Workflows → Import from file.
- Import
Persona DB.json. - Activate the workflow.
- Note its workflow ID — visible in the URL:
/workflow/<ID>.
The persona.json workflow file contains four placeholders that must be replaced with your real IDs before import:
| Placeholder | Replaced by |
|---|---|
{{DT_USERS}} |
Data Table ID for persona_users |
{{DT_SESSIONS}} |
Data Table ID for persona_sessions |
{{DT_LOGIN_ATTEMPTS}} |
Data Table ID for persona_login_attempts |
{{WORKFLOW_DB}} |
Workflow ID of Persona DB |
Run the script:
python replace_ids.py \
--dt-users <DT_USERS_ID> \
--dt-sessions <DT_SESSIONS_ID> \
--dt-login-attempts <DT_LOGIN_ATTEMPTS_ID> \
--workflow-db <PERSONA_DB_WORKFLOW_ID> \
persona.json "Persona DB.json"The script edits the files in place. Use --output-dir to write to a separate directory instead:
python replace_ids.py \
--dt-users oU88XZmCfb87Oxbn \
--dt-sessions gLuygoEITlAypAmJ \
--dt-login-attempts 4jjAebbyEijIfBx3 \
--workflow-db coEXen1CzEdEG3hH \
--output-dir ./patched \
persona.json "Persona DB.json"The script will warn about any remaining unfilled placeholders.
- In n8n go to Workflows → Import from file.
- Import the (now patched)
persona.json.
In the imported workflows, link your credentials for each node that requires them:
| Node | Credential type |
|---|---|
Anthropic Chat Model, Message a model |
Anthropic API key |
Send Newsletter Email |
SMTP account |
Fetch NewsAPI |
Insert your key directly in the URL (apiKey=YOUR_NEWSAPI_KEY) |
Fetch Guardian |
Insert your key directly in the URL (api-key=YOUR_GUADRIAN_API_KEY) |
In persona.json, the Compose HTML Email node contains a hardcoded base URL used to generate the unsubscribe link:
const base = 'YOUR_N8N_BASE_URL';
Edit that node and replace YOUR_N8N_BASE_URL with your actual n8n public URL (e.g. https://n8n.example.com).
Activate Persona DB first, then Persona Main. The newsletter scheduler runs every 30 minutes and sends emails to users whose scheduled delivery time falls within the current ±15-minute window.
usage: replace_ids.py [-h] [--dt-users ID] [--dt-sessions ID]
[--dt-login-attempts ID] [--workflow-db ID]
[--output-dir DIR]
file [file ...]
options:
--dt-users ID Users datatable ID
--dt-sessions ID Sessions datatable ID
--dt-login-attempts ID Login attempts datatable ID
--workflow-db ID Persona DB workflow ID
--output-dir DIR Write results here instead of editing in place
You can pass one or more JSON files and only the flags you need — unspecified placeholders are left unchanged.
Schedule (every 30 min)
→ Get Active Users (Data Table)
→ For Each User
→ Check Send Conditions (timezone window + no recent send)
→ Fetch NewsAPI / HackerNews / Guardian (parallel)
→ Merge + deduplicate articles
→ Claude AI selects top 5 relevant articles
→ Compose HTML email
→ Send via SMTP
→ Update lastNewsletter timestamp
Chat Trigger (n8n chatbot UI or API)
→ Persona AI Agent (Claude Haiku)
Tools: check_session / register_user / login_user /
get_profile / update_preferences /
delete_my_account / send_newsletter_now
→ All tools call Persona DB sub-workflow