Files
telegram-bot-workers/n8n-workflow-example.json
kappa 1e71e035e7 Initial commit: Telegram bot with Cloudflare Workers
- OpenAI GPT-4o-mini with Function Calling
- Cloudflare D1 for user profiles and message buffer
- Sliding window (3 summaries max) for infinite context
- Tools: weather, search, time, calculator
- Workers AI fallback support
- Webhook security with rate limiting

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-14 13:00:44 +09:00

446 lines
12 KiB
JSON

{
"name": "Telegram Bot Handler",
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "telegram-bot",
"responseMode": "responseNode",
"options": {}
},
"id": "webhook-1",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [250, 300],
"webhookId": "telegram-bot"
},
{
"parameters": {
"rules": {
"rules": [
{
"outputKey": "weather",
"conditions": {
"options": { "version": 2 },
"combinator": "and",
"conditions": [
{
"leftValue": "={{ $json.type }}",
"rightValue": "weather",
"operator": { "type": "string", "operation": "equals" }
}
]
}
},
{
"outputKey": "search",
"conditions": {
"options": { "version": 2 },
"combinator": "and",
"conditions": [
{
"leftValue": "={{ $json.type }}",
"rightValue": "search",
"operator": { "type": "string", "operation": "equals" }
}
]
}
},
{
"outputKey": "translate",
"conditions": {
"options": { "version": 2 },
"combinator": "and",
"conditions": [
{
"leftValue": "={{ $json.type }}",
"rightValue": "translate",
"operator": { "type": "string", "operation": "equals" }
}
]
}
},
{
"outputKey": "image",
"conditions": {
"options": { "version": 2 },
"combinator": "and",
"conditions": [
{
"leftValue": "={{ $json.type }}",
"rightValue": "image",
"operator": { "type": "string", "operation": "equals" }
}
]
}
},
{
"outputKey": "summarize_url",
"conditions": {
"options": { "version": 2 },
"combinator": "and",
"conditions": [
{
"leftValue": "={{ $json.type }}",
"rightValue": "summarize_url",
"operator": { "type": "string", "operation": "equals" }
}
]
}
},
{
"outputKey": "default",
"conditions": {
"options": { "version": 2 },
"combinator": "and",
"conditions": [
{
"leftValue": "={{ $json.type }}",
"rightValue": "",
"operator": { "type": "string", "operation": "notEmpty" }
}
]
}
}
]
},
"options": {}
},
"id": "switch-1",
"name": "Route by Type",
"type": "n8n-nodes-base.switch",
"typeVersion": 3,
"position": [480, 300]
},
{
"parameters": {
"method": "GET",
"url": "=https://api.openweathermap.org/data/2.5/weather?q={{ $json.message.match(/[가-힣a-zA-Z]+/)?.[0] || 'Seoul' }}&appid={{ $env.OPENWEATHER_API_KEY }}&units=metric&lang=kr",
"options": {}
},
"id": "weather-api",
"name": "Weather API",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [720, 100]
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "reply",
"name": "reply",
"value": "={{ '🌤 ' + $json.name + ' 날씨\\n온도: ' + $json.main.temp + '°C\\n체감: ' + $json.main.feels_like + '°C\\n습도: ' + $json.main.humidity + '%\\n' + $json.weather[0].description }}",
"type": "string"
}
]
},
"options": {}
},
"id": "weather-format",
"name": "Format Weather",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [940, 100]
},
{
"parameters": {
"model": "gpt-4o-mini",
"messages": {
"values": [
{
"content": "=다음 질문에 대해 웹 검색 결과를 바탕으로 답변해주세요: {{ $('Webhook').item.json.message }}"
}
]
},
"options": {}
},
"id": "search-ai",
"name": "AI Search",
"type": "@n8n/n8n-nodes-langchain.openAi",
"typeVersion": 1.4,
"position": [720, 220]
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "reply",
"name": "reply",
"value": "={{ $json.message.content }}",
"type": "string"
}
]
},
"options": {}
},
"id": "search-format",
"name": "Format Search",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [940, 220]
},
{
"parameters": {
"method": "POST",
"url": "https://api-free.deepl.com/v2/translate",
"sendBody": true,
"bodyParameters": {
"parameters": [
{
"name": "text",
"value": "={{ $('Webhook').item.json.message }}"
},
{
"name": "target_lang",
"value": "EN"
}
]
},
"options": {
"headers": {
"header": [
{
"name": "Authorization",
"value": "=DeepL-Auth-Key {{ $env.DEEPL_API_KEY }}"
}
]
}
}
},
"id": "translate-api",
"name": "Translate API",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [720, 340]
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "reply",
"name": "reply",
"value": "=🌐 번역 결과:\\n{{ $json.translations[0].text }}",
"type": "string"
}
]
},
"options": {}
},
"id": "translate-format",
"name": "Format Translate",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [940, 340]
},
{
"parameters": {
"method": "POST",
"url": "https://api.openai.com/v1/images/generations",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "=Bearer {{ $env.OPENAI_API_KEY }}"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\n \"model\": \"dall-e-3\",\n \"prompt\": \"{{ $('Webhook').item.json.message }}\",\n \"n\": 1,\n \"size\": \"1024x1024\"\n}",
"options": {}
},
"id": "image-api",
"name": "Image Generation",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [720, 460]
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "reply",
"name": "reply",
"value": "=🎨 이미지 생성 완료!\\n{{ $json.data[0].url }}",
"type": "string"
}
]
},
"options": {}
},
"id": "image-format",
"name": "Format Image",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [940, 460]
},
{
"parameters": {
"method": "GET",
"url": "={{ $('Webhook').item.json.message.match(/https?:\\/\\/[^\\s]+/)?.[0] }}",
"options": {}
},
"id": "fetch-url",
"name": "Fetch URL",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [720, 580]
},
{
"parameters": {
"model": "gpt-4o-mini",
"messages": {
"values": [
{
"content": "=다음 웹페이지 내용을 한국어로 300자 이내로 요약해주세요:\\n\\n{{ $json.data.substring(0, 5000) }}"
}
]
},
"options": {}
},
"id": "summarize-ai",
"name": "Summarize URL",
"type": "@n8n/n8n-nodes-langchain.openAi",
"typeVersion": 1.4,
"position": [940, 580]
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "reply",
"name": "reply",
"value": "=📄 URL 요약:\\n{{ $json.message.content }}",
"type": "string"
}
]
},
"options": {}
},
"id": "summarize-format",
"name": "Format Summary",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [1160, 580]
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "reply",
"name": "reply",
"value": "=❓ 지원하지 않는 기능입니다: {{ $('Webhook').item.json.type }}",
"type": "string"
}
]
},
"options": {}
},
"id": "default-response",
"name": "Default Response",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [720, 700]
},
{
"parameters": {
"options": {}
},
"id": "respond-1",
"name": "Respond to Webhook",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.1,
"position": [1380, 300]
}
],
"connections": {
"Webhook": {
"main": [
[{ "node": "Route by Type", "type": "main", "index": 0 }]
]
},
"Route by Type": {
"main": [
[{ "node": "Weather API", "type": "main", "index": 0 }],
[{ "node": "AI Search", "type": "main", "index": 0 }],
[{ "node": "Translate API", "type": "main", "index": 0 }],
[{ "node": "Image Generation", "type": "main", "index": 0 }],
[{ "node": "Fetch URL", "type": "main", "index": 0 }],
[{ "node": "Default Response", "type": "main", "index": 0 }]
]
},
"Weather API": {
"main": [
[{ "node": "Format Weather", "type": "main", "index": 0 }]
]
},
"Format Weather": {
"main": [
[{ "node": "Respond to Webhook", "type": "main", "index": 0 }]
]
},
"AI Search": {
"main": [
[{ "node": "Format Search", "type": "main", "index": 0 }]
]
},
"Format Search": {
"main": [
[{ "node": "Respond to Webhook", "type": "main", "index": 0 }]
]
},
"Translate API": {
"main": [
[{ "node": "Format Translate", "type": "main", "index": 0 }]
]
},
"Format Translate": {
"main": [
[{ "node": "Respond to Webhook", "type": "main", "index": 0 }]
]
},
"Image Generation": {
"main": [
[{ "node": "Format Image", "type": "main", "index": 0 }]
]
},
"Format Image": {
"main": [
[{ "node": "Respond to Webhook", "type": "main", "index": 0 }]
]
},
"Fetch URL": {
"main": [
[{ "node": "Summarize URL", "type": "main", "index": 0 }]
]
},
"Summarize URL": {
"main": [
[{ "node": "Format Summary", "type": "main", "index": 0 }]
]
},
"Format Summary": {
"main": [
[{ "node": "Respond to Webhook", "type": "main", "index": 0 }]
]
},
"Default Response": {
"main": [
[{ "node": "Respond to Webhook", "type": "main", "index": 0 }]
]
}
},
"settings": {
"executionOrder": "v1"
}
}