This workflow corresponds to n8n.io template #10185 — we link there as the canonical source.
This workflow follows the Chainllm → HTTP Request recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"name": "Slack Multilingual Assistant with Gemini 2.5 Flash",
"tags": [],
"nodes": [
{
"id": "613a274c-124d-42cb-bcea-7769e8050eb1",
"name": "Webhook (Slack /trans)",
"type": "n8n-nodes-base.webhook",
"position": [
3328,
512
],
"parameters": {
"path": "slack/trans",
"options": {},
"httpMethod": "POST",
"responseMode": "responseNode"
},
"typeVersion": 2
},
{
"id": "1f1ec470-c751-4de8-b2a8-4f9c2841139f",
"name": "Ack (Respond to Slack)",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
3584,
416
],
"parameters": {
"options": {
"responseCode": 200,
"responseHeaders": {
"entries": [
{
"name": "Content-Type",
"value": "text/plain; charset=utf-8"
}
]
}
},
"respondWith": "text",
"responseBody": "Translating..."
},
"typeVersion": 1
},
{
"id": "021bfa0c-46a6-45ca-89a2-bee8f1a28270",
"name": "Parse Slash Payload",
"type": "n8n-nodes-base.code",
"position": [
3584,
576
],
"parameters": {
"jsCode": "const payload = $json.body || $json;\nconst text = (payload.text || '').trim();\nreturn [{\n json: {\n text,\n response_url: payload.response_url,\n user_id: payload.user_id,\n user_name: payload.user_name\n }\n}];"
},
"typeVersion": 2
},
{
"id": "9229c1c8-99a3-47e9-9e51-9fdf611f3d6f",
"name": "Ack Mention Event",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
3584,
736
],
"parameters": {
"options": {
"responseCode": 200,
"responseHeaders": {
"entries": [
{
"name": "Content-Type",
"value": "application/json; charset=utf-8"
}
]
}
},
"respondWith": "json",
"responseBody": "={{ $json.body && $json.body.challenge ? {\"challenge\": $json.body.challenge } : {\"ok\": true} }}"
},
"typeVersion": 1
},
{
"id": "59f4988f-274d-4f5c-b304-7f253d507306",
"name": "Parse Mention Event",
"type": "n8n-nodes-base.code",
"position": [
3584,
896
],
"parameters": {
"jsCode": "/* app_mention \u30a4\u30d9\u30f3\u30c8\u5f62\u5f0f:\n{\n body: {\n event: {\n type: 'app_mention',\n user: 'U123',\n text: '<@Ubot> @trans \u3053\u308c\u8a33\u3057\u3066',\n channel: 'C123',\n ts: '173+1234567890',\n thread_ts: '173+1234567890' (optional)\n }\n }\n}\n*/\n\nconst body = $json.body || $json;\nconst ev = body.event || {};\n\nlet raw = ev.text || '';\n// <@U...> \u3068\u304b @trans \u3092\u9664\u53bb\nraw = raw.replace(/<@[^>]+>/g, '').replace(/@trans/gi, '').trim();\n\nconst thread_ts = ev.thread_ts || ev.ts;\n\nreturn [{\n json: {\n textToTranslate: raw,\n channel: ev.channel,\n thread_ts,\n user_id: ev.user\n }\n}];"
},
"typeVersion": 2
},
{
"id": "313833d3-b896-42e3-8c85-37a5f8140e4f",
"name": "Ack Reaction Event",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
3584,
1056
],
"parameters": {
"options": {
"responseCode": 200,
"responseHeaders": {
"entries": [
{
"name": "Content-Type",
"value": "application/json; charset=utf-8"
}
]
}
},
"respondWith": "json",
"responseBody": "={{ $json.body && $json.body.challenge ? {\"challenge\": $json.body.challenge } : {\"ok\": true} }}"
},
"typeVersion": 1
},
{
"id": "19651cc6-1157-4baf-a330-b1d999212c32",
"name": "Parse Reaction Event",
"type": "n8n-nodes-base.code",
"position": [
3584,
1216
],
"parameters": {
"jsCode": "/*\n Slack reaction_added payload \u4f8b:\n {\n \"event\": {\n \"type\": \"reaction_added\",\n \"user\": \"U123456\",\n \"reaction\": \"jp\",\n \"item\": {\n \"type\": \"message\",\n \"channel\": \"C123456\",\n \"ts\": \"173+1234567890\"\n }\n }\n }\n*/\n\nlet body = $json;\n\n// n8n\u306eWebhook\u30ce\u30fc\u30c9\u3067\u306f payload \u304c body \u4e0b\u306b\u5165\u308b\u5834\u5408\u3068\u3001\u76f4\u4e0b\u306b\u5165\u308b\u5834\u5408\u304c\u3042\u308b\nif ($json.body && typeof $json.body === 'object') {\n body = $json.body;\n}\n\nconst ev = body.event || {};\n\n// \u30c7\u30d0\u30c3\u30b0\u7528\u30ed\u30b0\uff08\u5fc5\u8981\u306a\u3089\u4e00\u6642\u7684\u306bON\uff09\nconsole.log('reaction event', ev);\n\nreturn [\n {\n json: {\n reactor_user: ev.user || null,\n reaction: ev.reaction || null,\n channel: ev.item?.channel || null,\n message_ts: ev.item?.ts || null,\n raw: ev\n }\n }\n];\n"
},
"typeVersion": 2
},
{
"id": "cc79dec9-6da6-4abb-bc92-47b01b6d1e48",
"name": "Fetch Original Message",
"type": "n8n-nodes-base.httpRequest",
"position": [
3760,
1376
],
"parameters": {
"url": "={{`https://slack.com/api/conversations.replies?channel=${$json.channel}&ts=${$json.message_ts}&limit=1`}}",
"options": {},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer YOUR_TOKEN_HERE"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "fc114495-2e73-4a78-ab32-43291dd7b326",
"name": "Prep Reaction Translation Input",
"type": "n8n-nodes-base.code",
"position": [
3936,
1376
],
"parameters": {
"jsCode": "const eventCtx = $node['Parse Reaction Event'].json;\nconst apiRes = $json;\n\nif (!apiRes.ok || !apiRes.messages || !apiRes.messages.length) {\n return [{ json: { skip: true, reason: 'no message found' } }];\n}\n\nconst msg = apiRes.messages[0];\nconst textToTranslate = msg.text || '';\nconst thread_ts = msg.thread_ts || msg.ts;\nconst channel = eventCtx.channel;\n\nreturn [{\n json: {\n textToTranslate,\n channel,\n thread_ts\n }\n}];"
},
"typeVersion": 2
},
{
"id": "b00abedc-8dd1-4193-b825-4b51b79694a5",
"name": "Google Gemini Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
3856,
1072
],
"parameters": {
"options": {
"temperature": 0.2,
"maxOutputTokens": 1024
}
},
"credentials": {
"googlePalmApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "be154439-e6f6-4eed-9715-2fbd5d3cd9b1",
"name": "Basic LLM Chain (/trans)",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"position": [
4096,
736
],
"parameters": {
"text": "=",
"batching": {},
"messages": {
"messageValues": [
{
"message": "You are a bilingual assistant for a Japanese/English mixed team.\nDetect whether the input is mainly Japanese or English.\nReturn exactly two labeled parts:\n\n[Original]\n<the original text>\n\n[Translation]\n<the translation in the OTHER language>\n\nRules:\n- Detect source language automatically (JA or EN).\n- Translate into the opposite language.\n- Do not add explanations or extra comments.\n- Keep both blocks in plain text."
},
{
"type": "HumanMessagePromptTemplate",
"message": "={{ $json.textToTranslate || $json.text }}"
}
]
},
"promptType": "define"
},
"typeVersion": 1.7
},
{
"id": "ecbacf69-4903-4643-9398-89ab3d903609",
"name": "Basic LLM Chain (@trans)",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"position": [
4096,
896
],
"parameters": {
"text": "=",
"batching": {},
"messages": {
"messageValues": [
{
"message": "You are a bilingual assistant for a Japanese/English mixed team.\nDetect whether the input is mainly Japanese or English.\nReturn exactly two labeled parts:\n\n[Original]\n<the original text>\n\n[Translation]\n<the translation in the OTHER language>\n\nRules:\n- Detect source language automatically (JA or EN).\n- Translate into the opposite language.\n- Do not add explanations or extra comments.\n- Keep both blocks in plain text."
},
{
"type": "HumanMessagePromptTemplate",
"message": "={{ $json.textToTranslate || $json.text }}"
}
]
},
"promptType": "define"
},
"typeVersion": 1.7
},
{
"id": "adeaa1b3-fbcb-4a11-a1cc-84dc75602478",
"name": "Basic LLM Chain (reaction)",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"position": [
4096,
1056
],
"parameters": {
"text": "=",
"batching": {},
"messages": {
"messageValues": [
{
"message": "You are a bilingual assistant for a Japanese/English mixed team.\nDetect whether the input is mainly Japanese or English.\nReturn exactly two labeled parts:\n\n[Original]\n<the original text>\n\n[Translation]\n<the translation in the OTHER language>\n\nRules:\n- Detect source language automatically (JA or EN).\n- Translate into the opposite language.\n- Do not add explanations or extra comments.\n- Keep both blocks in plain text."
},
{
"type": "HumanMessagePromptTemplate",
"message": "={{ $json.textToTranslate || $json.text }}"
}
]
},
"promptType": "define"
},
"typeVersion": 1.7
},
{
"id": "c443fefb-b54e-4b7a-b97f-60f115daa471",
"name": "Format Slack Message (/trans)",
"type": "n8n-nodes-base.code",
"position": [
4400,
736
],
"parameters": {
"jsCode": "/* /trans \u7528\u30d5\u30a9\u30fc\u30de\u30c3\u30bf\n \u51fa\u529b\u30a4\u30e1\u30fc\u30b8:\n \u3010from @\u5f8c\u85e4\u3011\\n(\u65e5\u672c\u8a9e\u539f\u6587...)\\n----------\\n(\u82f1\u8a9e\u8a33...)\n*/\nconst ctx = $node['Parse Slash Payload'].json;\nconst llm = $json;\n\nlet output = llm.text || llm.output || '';\n\n// [Original] \u3068 [Translation] \u3092\u5206\u96e2\nlet original = '';\nlet translation = '';\nconst match = output.match(/\\[Original\\]([\\s\\S]*?)\\[Translation\\]([\\s\\S]*)/i);\nif (match) {\n original = match[1].trim();\n translation = match[2].trim();\n} else {\n translation = output.trim();\n}\n\nconst fromUser = ctx.user_id ? `<@${ctx.user_id}>` : (ctx.user_name || 'someone');\nconst finalMessage = `\u3010from ${fromUser}\u3011\\n${original}\\n----------\\n${translation}`;\n\nreturn [{\n json: {\n response_url: ctx.response_url,\n message: finalMessage\n }\n}];"
},
"typeVersion": 2
},
{
"id": "c939414e-b72e-4a70-a60c-809294ba8d58",
"name": "Format Slack Message (@trans)",
"type": "n8n-nodes-base.code",
"position": [
4400,
896
],
"parameters": {
"jsCode": "/* @trans \u7528\u30d5\u30a9\u30fc\u30de\u30c3\u30bf\n \u8a33\u6587\u3060\u3051\u8fd4\u3059\uff08\u30b9\u30ec\u30c3\u30c9\uff09\n*/\nconst ctx = $node['Parse Mention Event'].json;\nconst llm = $json;\n\nlet output = llm.text || llm.output || '';\noutput = output\n .replace(/\\[Original\\][\\s\\S]*?\\[Translation\\]/i, '')\n .replace(/\\[Translation\\]/i, '')\n .trim();\n\nreturn [{\n json: {\n channel: ctx.channel,\n thread_ts: String(ctx.thread_ts),\n text: output\n }\n}];"
},
"typeVersion": 2
},
{
"id": "05b95459-5234-479d-8455-74504d4fbfa6",
"name": "Format Slack Message (reaction)",
"type": "n8n-nodes-base.code",
"position": [
4400,
1056
],
"parameters": {
"jsCode": "/* reaction \u7528\u30d5\u30a9\u30fc\u30de\u30c3\u30bf\n \u8a33\u6587\u3060\u3051\u8fd4\u3059\uff08\u30b9\u30ec\u30c3\u30c9\uff09\n*/\nconst ctx = $node['Prep Reaction Translation Input'].json;\nconst llm = $json;\n\nlet output = llm.text || llm.output || '';\noutput = output\n .replace(/\\[Original\\][\\s\\S]*?\\[Translation\\]/i, '')\n .replace(/\\[Translation\\]/i, '')\n .trim();\n\nreturn [{\n json: {\n channel: ctx.channel,\n thread_ts: String(ctx.thread_ts),\n text: output\n }\n}];"
},
"typeVersion": 2
},
{
"id": "3a592c03-37b3-4d68-a22c-1b7bff70c5f1",
"name": "Post to Slack (response_url)",
"type": "n8n-nodes-base.httpRequest",
"position": [
4576,
736
],
"parameters": {
"url": "={{$json.response_url}}",
"method": "POST",
"options": {},
"sendBody": true,
"sendHeaders": true,
"bodyParameters": {
"parameters": [
{
"name": "response_type",
"value": "in_channel"
},
{
"name": "text",
"value": "={{ $json.message }}"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json; charset=utf-8"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "07a8ba81-4fee-4073-b8fa-48de1e829bc9",
"name": "Post to Slack (@trans reply)",
"type": "n8n-nodes-base.httpRequest",
"position": [
4576,
896
],
"parameters": {
"url": "https://slack.com/api/chat.postMessage",
"method": "POST",
"options": {},
"sendBody": true,
"sendHeaders": true,
"bodyParameters": {
"parameters": [
{
"name": "channel",
"value": "={{ $json.channel }}"
},
{
"name": "text",
"value": "={{ $json.text }}"
},
{
"name": "thread_ts",
"value": "={{ $json.thread_ts.toString() }}"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json; charset=utf-8"
},
{
"name": "Authorization",
"value": "Bearer YOUR_TOKEN_HERE"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "4a426e04-11a0-4e99-b37a-0aa2580ea043",
"name": "Post to Slack (reaction reply)",
"type": "n8n-nodes-base.httpRequest",
"position": [
4576,
1056
],
"parameters": {
"url": "https://slack.com/api/chat.postMessage",
"method": "POST",
"options": {},
"sendBody": true,
"sendHeaders": true,
"bodyParameters": {
"parameters": [
{
"name": "channel",
"value": "={{$json.channel}}"
},
{
"name": "text",
"value": "={{$json.text}}"
},
{
"name": "thread_ts",
"value": "={{$json.thread_ts}}"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json; charset=utf-8"
},
{
"name": "Authorization",
"value": "Bearer YOUR_TOKEN_HERE"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "a83c3091-3bac-4fe9-ba77-f15fd9051db3",
"name": "How to set up",
"type": "n8n-nodes-base.stickyNote",
"position": [
2880,
240
],
"parameters": {
"color": 4,
"width": 648,
"height": 200,
"content": "Slack Multilingual Assistant (Gemini 2.5 Flash)\n\n\ud83d\udd27 Three translation modes unified in one workflow:\n1\ufe0f\u20e3 /trans \u2014 Public bilingual announcements \n\u2003\u2003Format: \u3010from @user\u3011 Original ---------- Translation \n2\ufe0f\u20e3 @trans \u2014 Mention trigger for thread translation (translation only) \n3\ufe0f\u20e3 \ud83c\uddef\ud83c\uddf5 / \ud83c\uddfa\ud83c\uddf8 Reaction \u2014 Private on-demand translation \n\n\ud83d\udca1 All modes share the same Google Gemini 2.5 Flash core for automatic JA\u21c4EN detection."
},
"typeVersion": 1
},
{
"id": "c5f820f6-5027-49d4-89de-a1781aa354e9",
"name": "Webhook (Slack @trans + reaction)",
"type": "n8n-nodes-base.webhook",
"position": [
2944,
976
],
"parameters": {
"path": "slack/mention",
"options": {},
"httpMethod": "POST",
"responseMode": "responseNode"
},
"typeVersion": 2
},
{
"id": "0a859374-d091-468f-bd68-ecb898b7a435",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
4384,
-16
],
"parameters": {
"color": 5,
"width": 480,
"height": 720,
"content": "\ud83d\udd27 Create and Configure your Slack App (TransBot)\n\n1\ufe0f\u20e3 Create App \n\u2003\u2192 From scratch \u2192 Name it \u201cTransBot\u201d \u2192 Select your workspace \n\n2\ufe0f\u20e3 Add Bot Token Scopes in OAuth & Permissions\n\u2003\u2022 commands \n\u2003\u2022 chat:write \n\u2003\u2022 app_mentions:read \n\u2003\u2022 reactions:read \n\u2003\u2022 channels:history \n\u2003\u2022 groups:history (optional for private channels)\n\n3\ufe0f\u20e3 Event Subscriptions \n\u2003Enable Events \u2705 \n\u2003Request URL \u2192 \n\u2003 https://<your-n8n-domain>/webhook/slack/mention \n\u2003Once verified, subscribe to bot events: \n\u2003 \u2013 app_mention \n\u2003 \u2013 message.channels \n\u2003and subscribe on behalf of users: \n\u2003 \u2013 reaction_added \n\n4\ufe0f\u20e3 Slash Command \n\u2003Command name: `/trans` \n\u2003Request URL \u2192 \n\u2003 https://<your-n8n-domain>/webhook/slack/trans \n\u2003Short desc: \u201cTranslate text JA\u21c4EN with Gemini 2.5 Flash\u201d\n\n5\ufe0f\u20e3 Install or Reinstall to Workspace \n\u2003Copy the new Bot User OAuth Token (xoxb-\u2026) \n\u2003and paste it into the HTTP Request headers in n8n \n\u2003(`Authorization: Bearer YOUR_TOKEN_HERE`)\n\n6\ufe0f\u20e3 Invite the bot to your channels: \n\u2003`/invite @TransBot`"
},
"typeVersion": 1
},
{
"id": "3e9045e2-e73b-4a23-a30a-9ecc27a16ed8",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
3824,
240
],
"parameters": {
"color": 3,
"width": 480,
"height": 368,
"content": "\ud83d\udd01 Workflow Architecture\n\n\u2022 Webhooks:\n\u2003 \u2013 /slack/trans \u2192 Slash Command \n\u2003 \u2013 /slack/mention \u2192 app_mention & reaction_added events \n\n\u2022 Language Model: Google Gemini 2.5 Flash \n\u2022 Logic:\n\u2003 \u2013 Detect source language (JA/EN) \n\u2003 \u2013 Translate to the opposite language \n\u2003 \u2013 Format Slack message per mode \n\n\u2022 Outputs:\n\u2003 \u2013 /trans \u2192 Posts bilingual message to channel (via response_url) \n\u2003 \u2013 @trans \u2192 Replies in thread with translation only \n\u2003 \u2013 Reaction \u2192 Replies in thread with translation only (for reader)\n\nAll three paths share the same Gemini core."
},
"typeVersion": 1
},
{
"id": "11a71607-a154-4a2a-8903-c896f4462551",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
2880,
1200
],
"parameters": {
"color": 3,
"width": 480,
"height": 272,
"content": "\ud83d\udea8 Common Errors & Fixes\n\n\u274c invalid_auth \n\u2003\u2192 Using an old token or bot not invited to channel \n\u2003\u2003Fix: Reinstall app / use latest xoxb token / `/invite @TransBot`\n\n\u274c missing_scope \n\u2003\u2192 A required scope is missing \n\u2003\u2003Fix: Add scope in OAuth & Permissions \u2192 Save \u2192 Reinstall\n\n\u274c no message found \n\u2003\u2192 Reaction event can\u2019t fetch original text \n\u2003\u2003Fix: Add `groups:history` scope for private channels"
},
"typeVersion": 1
},
{
"id": "a6cce3e2-180b-45ee-ba6d-b81e1bcdb5b5",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
4336,
1328
],
"parameters": {
"color": 4,
"width": 528,
"height": 144,
"content": "\u2705 Workflow is Active in n8n \n\u2705 Slack Event Subscription Request URL shows \u201cVerified \u2705\u201d \n\u2705 Bot Token includes chat:write, channels:history, reactions:read \n\u2705 /trans Slash Command responds with \u201cTranslating...\u201d then Gemini output \n\u2705 @trans mention replies in thread with translation only \n\u2705 \ud83c\uddef\ud83c\uddf5/\ud83c\uddfa\ud83c\uddf8 reaction adds translation reply in thread"
},
"typeVersion": 1
},
{
"id": "88bac316-9994-466b-8f75-b7d2f8cf1467",
"name": "Route by Event Type",
"type": "n8n-nodes-base.switch",
"position": [
3328,
976
],
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "1927dafe-a218-44de-a76b-47eefeabc55e",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{$json.event_type}}",
"rightValue": "app_mention"
}
]
}
},
{
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "adda84a4-9099-4b3d-8ef2-4968c8ab8670",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{$json.event_type}}",
"rightValue": "reaction_added"
}
]
}
}
]
},
"options": {}
},
"typeVersion": 3.3
},
{
"id": "1a9163a3-bcab-475d-8372-de95de586e4f",
"name": "Skip Reaction When No Message Found",
"type": "n8n-nodes-base.if",
"position": [
4112,
1376
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "922fba50-9c9e-49c7-9bb0-6efe56e2f216",
"operator": {
"type": "string",
"operation": "notEquals"
},
"leftValue": "={{$json.skip}}",
"rightValue": "true"
},
{
"id": "d98fdf6c-83c4-4a66-8bdf-6d5854131727",
"operator": {
"type": "string",
"operation": "notEmpty",
"singleValue": true
},
"leftValue": "={{$json.textToTranslate}}",
"rightValue": ""
}
]
},
"looseTypeValidation": true
},
"typeVersion": 2.2
},
{
"id": "1eb61e22-6993-4fd0-ac72-0f9b0fbb976d",
"name": "Filter Reaction Type",
"type": "n8n-nodes-base.code",
"position": [
3584,
1376
],
"parameters": {
"jsCode": "/*\n :jp: / :jp-flag: / :flag-jp: / :us: / :flag-us: \u306a\u3069\u306b\u5bfe\u5fdc\n \u2192 \u305d\u308c\u4ee5\u5916\u306e\u30ea\u30a2\u30af\u30b7\u30e7\u30f3\u306f\u30b9\u30ad\u30c3\u30d7\n*/\n\nconst allowedPatterns = ['jp', 'us'];\nconst reaction = ($json.reaction || '').toLowerCase();\n\n// \u90e8\u5206\u4e00\u81f4\u30c1\u30a7\u30c3\u30af\nconst isAllowed = allowedPatterns.some(p => reaction.includes(p));\n\nif (!isAllowed) {\n return [{ json: { skip: true, reason: `irrelevant reaction: ${reaction}` } }];\n}\n\nreturn [{ json: $json }];\n"
},
"typeVersion": 2
},
{
"id": "e3aa1071-f785-4338-a8f4-ae20384ae621",
"name": "Detect Slack Event Type",
"type": "n8n-nodes-base.code",
"position": [
3136,
976
],
"parameters": {
"jsCode": "const event = $json.body?.event || $json.event;\nreturn [{ json: { event_type: event.type, event } }];"
},
"typeVersion": 2
}
],
"active": true,
"settings": {
"executionOrder": "v1"
},
"connections": {
"Parse Mention Event": {
"main": [
[
{
"node": "Basic LLM Chain (@trans)",
"type": "main",
"index": 0
}
]
]
},
"Parse Slash Payload": {
"main": [
[
{
"node": "Basic LLM Chain (/trans)",
"type": "main",
"index": 0
}
]
]
},
"Route by Event Type": {
"main": [
[
{
"node": "Ack Mention Event",
"type": "main",
"index": 0
},
{
"node": "Parse Mention Event",
"type": "main",
"index": 0
}
],
[
{
"node": "Ack Reaction Event",
"type": "main",
"index": 0
},
{
"node": "Parse Reaction Event",
"type": "main",
"index": 0
}
]
]
},
"Filter Reaction Type": {
"main": [
[
{
"node": "Fetch Original Message",
"type": "main",
"index": 0
}
]
]
},
"Parse Reaction Event": {
"main": [
[
{
"node": "Filter Reaction Type",
"type": "main",
"index": 0
}
]
]
},
"Fetch Original Message": {
"main": [
[
{
"node": "Prep Reaction Translation Input",
"type": "main",
"index": 0
}
]
]
},
"Webhook (Slack /trans)": {
"main": [
[
{
"node": "Ack (Respond to Slack)",
"type": "main",
"index": 0
},
{
"node": "Parse Slash Payload",
"type": "main",
"index": 0
}
]
]
},
"Detect Slack Event Type": {
"main": [
[
{
"node": "Route by Event Type",
"type": "main",
"index": 0
}
]
]
},
"Basic LLM Chain (/trans)": {
"main": [
[
{
"node": "Format Slack Message (/trans)",
"type": "main",
"index": 0
}
]
]
},
"Basic LLM Chain (@trans)": {
"main": [
[
{
"node": "Format Slack Message (@trans)",
"type": "main",
"index": 0
}
]
]
},
"Google Gemini Chat Model": {
"ai_languageModel": [
[
{
"node": "Basic LLM Chain (reaction)",
"type": "ai_languageModel",
"index": 0
},
{
"node": "Basic LLM Chain (@trans)",
"type": "ai_languageModel",
"index": 0
},
{
"node": "Basic LLM Chain (/trans)",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Basic LLM Chain (reaction)": {
"main": [
[
{
"node": "Format Slack Message (reaction)",
"type": "main",
"index": 0
}
]
]
},
"Format Slack Message (/trans)": {
"main": [
[
{
"node": "Post to Slack (response_url)",
"type": "main",
"index": 0
}
]
]
},
"Format Slack Message (@trans)": {
"main": [
[
{
"node": "Post to Slack (@trans reply)",
"type": "main",
"index": 0
}
]
]
},
"Format Slack Message (reaction)": {
"main": [
[
{
"node": "Post to Slack (reaction reply)",
"type": "main",
"index": 0
}
]
]
},
"Prep Reaction Translation Input": {
"main": [
[
{
"node": "Skip Reaction When No Message Found",
"type": "main",
"index": 0
}
]
]
},
"Webhook (Slack @trans + reaction)": {
"main": [
[
{
"node": "Detect Slack Event Type",
"type": "main",
"index": 0
}
]
]
},
"Skip Reaction When No Message Found": {
"main": [
[
{
"node": "Basic LLM Chain (reaction)",
"type": "main",
"index": 0
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
googlePalmApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow automatically translates messages between Japanese and English inside Slack — perfect for mixed-language teams. In our real-world use case, our 8-person team includes Arif, an English-speaking teammate from Indonesia, while the rest mainly speak Japanese.
Source: https://n8n.io/workflows/10185/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
ANIS_HUB 1. Uses gmail, googleDrive, googleSheets, httpRequest. Webhook trigger; 89 nodes.
CLINICAINTEGRAL_secretary. Uses postgres, mcpClientTool, googleDriveTool, toolWorkflow. Webhook trigger; 89 nodes.
secretaria. Uses postgres, n8n-nodes-evolution-api, openAi, httpRequest. Webhook trigger; 71 nodes.
Resume Screening & Behavioral Interviews with Gemini, Elevenlabs, & Notion ATS copy. Uses outputParserStructured, chainLlm, googleDrive, stickyNote. Webhook trigger; 67 nodes.
Candidate Engagement | Resume Screening | AI Voice Interviews | Applicant Insights