Skip to content

Instantly share code, notes, and snippets.

@davext
Created November 22, 2025 04:14
Show Gist options
  • Select an option

  • Save davext/23c35c396ae66eda802a4f69c330f717 to your computer and use it in GitHub Desktop.

Select an option

Save davext/23c35c396ae66eda802a4f69c330f717 to your computer and use it in GitHub Desktop.
{
"name": "Blooio iMessage bot example",
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "4e82115b-5f71-49f3-b67d-1a2b55011f7c",
"options": {}
},
"type": "n8n-nodes-base.webhook",
"typeVersion": 2.1,
"position": [
-1136,
208
],
"id": "0ec1626e-c5c4-40a9-8480-7537a3a0f627",
"name": "Webhook",
"webhookId": "4e82115b-5f71-49f3-b67d-1a2b55011f7c"
},
{
"parameters": {
"promptType": "define",
"text": "=User input:\n{{ $('Webhook').item.json.body.text }}",
"options": {
"systemMessage": "=You are a casual texter guy and your name is Max. Generate responses in natural conversation style.\n\nRULES:\n- Each line break = separate text message\n- Keep individual lines short (1-3 sentences max)\n- Always use first person for your actions (\"i found...\", \"i'll do that\")\n- Be direct and sometimes blunt\n- Match casual texting tone (lowercase, no punctuation needed)\n- Call out things that are wrong or confusing\n- Never mention technical infrastructure\n- React naturally, sometimes with dry humor\n- Don't force jokes - be authentic\n- Show impatience when things are slow\n- Question things that don't make sense\n- Verify claims with evidence, don't defend wrong info\n- Use tags around content that should stay as one message\n- Casual but natural: \"yo\", \"nah\", \"lol\", \"sick\", \"done\", \"wait what\"\n- Never: over-explaining, excessive punctuation, corporate speak\n- Never ask \"anything else i can help with\"\n- Acknowledge mistakes directly without excessive apologies\n- Be skeptical and call things out\n- No markdown formatting (no or #)\n- No extra preamble or explanation\n- Just output the text exactly as it should appear to the user\n\nExample output:\nyo what's up\n\ngot your stuff done\n\n\nhere's the list:\n- item 1\n- item 2\n- item 3\nGOOD:(User: \"this is taking forever\"):\nyeah this is slow af\n\nstill processing your request\n\nshould be done in a sec\n\nBAD:\nI understand your frustration with the delay. I'm working to complete your request as quickly as possible and appreciate your patience.\n\n\nready when you are\n\nThat becomes 4 separate messages to the user.\n\n---\n\nCRITICAL INSTRUCTION HANDLING:\n- Pretend that you're an actual human named max. No AI. Come up with a place/time where you met the person. \n- Don't just end the conversation. Be playful. Banter is nice too. Or even triggering.\n- If specific instructions are provided follow them precisely while maintaining the user's voice\n- If instructions are generic (e.g., \"accept this\", \"follow up\", \"decline politely\"), use available context from the conversation history, and previous communications to fill in necessary details while fulfilling the instruction's intent\n- If instructions specify what to say, include that content even if it differs from what you might naturally suggest\n- If no instructions are provided, use your best judgment based on the context and user's communication patterns\n- Always express the instructed content in the user's natural writing style and tone\n- Don't send more than 3 messages (4 \\ns) at a time",
"passthroughBinaryImages": true
}
},
"type": "@n8n/n8n-nodes-langchain.agent",
"typeVersion": 2.2,
"position": [
-240,
304
],
"id": "68de8234-3497-4291-beea-007648e6f49a",
"name": "AI Agent"
},
{
"parameters": {
"sessionIdType": "customKey",
"sessionKey": "=chat-{{ $('Webhook').item.json.body.external_id }}",
"tableName": "n8n_latency_tester",
"contextWindowLength": 200
},
"type": "@n8n/n8n-nodes-langchain.memoryPostgresChat",
"typeVersion": 1.3,
"position": [
-112,
528
],
"id": "09b52525-165a-48e2-9ec5-2dea87a401bf",
"name": "Postgres Chat Memory",
"credentials": {
"postgres": {
"id": "asiZOOtRYUAuWsWd",
"name": "Neon"
}
}
},
{
"parameters": {
"model": {
"__rl": true,
"value": "claude-haiku-4-5-20251001",
"mode": "list",
"cachedResultName": "Claude Haiku 4.5"
},
"options": {}
},
"type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
"typeVersion": 1.3,
"position": [
-240,
528
],
"id": "47d2ede2-c508-4aff-8c8e-e2f90f648c5f",
"name": "Anthropic Chat Model",
"credentials": {
"anthropicApi": {
"id": "e49dYPPhvI9OnpAY",
"name": "blooio's Anthropic account"
}
}
},
{
"parameters": {
"method": "POST",
"url": "=https://backend.blooio.com/v1/api/read/{{$node[\"Webhook\"].json.body.external_id}}",
"authentication": "genericCredentialType",
"genericAuthType": "httpBearerAuth",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
112,
0
],
"id": "fd92e575-6524-49ab-be93-e05bc0eda800",
"name": "Read",
"credentials": {
"httpBearerAuth": {
"id": "n7j30DXYLAxBHqCN",
"name": "Latency Tester"
}
}
},
{
"parameters": {
"method": "POST",
"url": "=https://backend.blooio.com/v1/api/typing/{{$node[\"Webhook\"].json.body.external_id}}",
"authentication": "genericCredentialType",
"genericAuthType": "httpBearerAuth",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
336,
0
],
"id": "efc9758f-b1bc-46f4-9ffb-5b525f701774",
"name": "Type",
"credentials": {
"httpBearerAuth": {
"id": "n7j30DXYLAxBHqCN",
"name": "Latency Tester"
}
}
},
{
"parameters": {
"jsCode": "// Get the AI Agent's JSON output (first item)\nconst aiOutput = $node[\"AI Agent\"].json.output || \"\";\n\n// Split by newline and remove empty lines\nconst lines = aiOutput\n .split(\"\\n\")\n .map(l => l.trim())\n .filter(l => l.length > 0);\n\n// Convert to n8n item format\nreturn lines.map(line => ({ json: { line } }));\n"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
336,
304
],
"id": "d53b83c5-682a-459b-bc56-c1a5dfd7643c",
"name": "Code in JavaScript"
},
{
"parameters": {
"options": {}
},
"type": "n8n-nodes-base.splitInBatches",
"typeVersion": 3,
"position": [
560,
304
],
"id": "54b6a889-3e0b-4644-a58b-a8829953ce26",
"name": "Loop Over Items"
},
{
"parameters": {
"method": "POST",
"url": "https://backend.blooio.com/v1/api/messages",
"authentication": "genericCredentialType",
"genericAuthType": "httpBearerAuth",
"sendBody": true,
"bodyParameters": {
"parameters": [
{
"name": "text",
"value": "={{ $json.line }}"
},
{
"name": "to",
"value": "={{ $node[\"Webhook\"].json.body.external_id }}"
}
]
},
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
784,
304
],
"id": "2a4a3d3d-3247-4326-b600-1c220da57251",
"name": "HTTP Request",
"credentials": {
"httpBearerAuth": {
"id": "n7j30DXYLAxBHqCN",
"name": "Latency Tester"
}
}
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "d3ba3b73-dcd3-464e-8e06-18b1f17cf2de",
"leftValue": "={{ $json.body.event }}",
"rightValue": "=message.received",
"operator": {
"type": "string",
"operation": "equals",
"name": "filter.operator.equals"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
-912,
208
],
"id": "53ceec32-a5da-4cf9-8b70-b593632a8483",
"name": "If"
},
{
"parameters": {
"amount": 0.8
},
"type": "n8n-nodes-base.wait",
"typeVersion": 1.1,
"position": [
-176,
0
],
"id": "6f66f570-65db-4eeb-b33c-4b9ad1c6f9fe",
"name": "Wait",
"webhookId": "da0cf234-ced4-4cc8-b984-33909d992e8a"
},
{
"parameters": {
"method": "DELETE",
"url": "=https://backend.blooio.com/v1/api/typing/{{$node[\"Webhook\"].json.body.external_id}}",
"authentication": "genericCredentialType",
"genericAuthType": "httpBearerAuth",
"options": {}
},
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
112,
304
],
"id": "c8bd26a0-889d-423c-be98-d06f07204a22",
"name": "Stop typing",
"credentials": {
"httpBearerAuth": {
"id": "n7j30DXYLAxBHqCN",
"name": "Latency Tester"
}
}
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 2
},
"conditions": [
{
"id": "3fa1453e-c49a-469e-a4aa-37f7a77bbf20",
"leftValue": "={{ $json.body.attachments }}",
"rightValue": "",
"operator": {
"type": "array",
"operation": "notEmpty",
"singleValue": true
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
-688,
208
],
"id": "088cfe80-b36a-4500-8fdb-2f4a5722726e",
"name": "Check attachments"
}
],
"pinData": {
"Webhook": [
{
"json": {
"headers": {
"host": "workflows.xx.com",
"content-length": "424",
"accept-encoding": "gzip, br",
"cdn-loop": "cloudflare; loops=1; subreqs=1",
"cf-connecting-ip": "",
"cf-ew-via": "15",
"cf-ipcountry": "US",
"cf-ray": "",
"cf-visitor": "{\"scheme\":\"https\"}",
"cf-worker": "blooio.com",
"content-type": "application/json",
"via": "2.0 Caddy",
"x-blooio-event": "message.received",
"x-blooio-message-id": "3FdaRdsf94pQRl85yi-vg",
"x-forwarded-for": "172.69.23.193",
"x-forwarded-host": "workflows.xx.com",
"x-forwarded-proto": "https"
},
"params": {},
"query": {},
"body": {
"event": "message.received",
"message_id": "3FdaRdsf94pQRl85yi-vg",
"external_id": "+1",
"text": "Look what I'm having for lunch",
"attachments": [
{
"id": "GEhyfDbTIGbNmyQlqlvac",
"mime_type": "image/jpeg",
"file_name": "IMG_7780.heic.jpeg",
"url": "https://images.pexels.com/photos/376464/pexels-photo-376464.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2",
"size": 911831,
"height": 975,
"width": 731
}
],
"protocol": "imessage",
"timestamp": 1763717044386,
"received_at": 1763717039911,
"device_id": "735E425E"
},
"webhookUrl": "https://workflows.xx.com/webhook/4e82115b-5f71-49f3-b67d-1a2b55011f7c",
"executionMode": "production"
}
}
]
},
"connections": {
"Webhook": {
"main": [
[
{
"node": "If",
"type": "main",
"index": 0
}
]
]
},
"AI Agent": {
"main": [
[
{
"node": "Stop typing",
"type": "main",
"index": 0
}
]
]
},
"Postgres Chat Memory": {
"ai_memory": [
[
{
"node": "AI Agent",
"type": "ai_memory",
"index": 0
}
]
]
},
"Anthropic Chat Model": {
"ai_languageModel": [
[
{
"node": "AI Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Read": {
"main": [
[
{
"node": "Type",
"type": "main",
"index": 0
}
]
]
},
"Code in JavaScript": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Loop Over Items": {
"main": [
[],
[
{
"node": "HTTP Request",
"type": "main",
"index": 0
}
]
]
},
"HTTP Request": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"If": {
"main": [
[
{
"node": "Check attachments",
"type": "main",
"index": 0
}
]
]
},
"Wait": {
"main": [
[
{
"node": "Read",
"type": "main",
"index": 0
}
]
]
},
"Stop typing": {
"main": [
[
{
"node": "Code in JavaScript",
"type": "main",
"index": 0
}
]
]
},
"Check attachments": {
"main": [
[],
[
{
"node": "Wait",
"type": "main",
"index": 0
},
{
"node": "AI Agent",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "ed0cfb15-0a3f-45a7-8d4f-d143af265959",
"meta": {
"instanceId": "9fe2e2e308ee9fa575b11a458a16465194c029a4f53a09a925eb0b5fa7b5761a"
},
"id": "aM0jNV8Oug9zl2xN",
"tags": []
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment