Can't get Slack Signature to validate (even though it worked in previous versions of n8n)

Describe the problem/error/question

Slack signature validation isn’t occurring properly. So, I am not sending back any information as per the Respond to Webhook node.

What is the error message (if any)?

Slack request signature validation failed. [line 56, for item 0]

Please share your workflow

Information on your n8n setup

  • n8n version: 1.72.1
  • Database (default: SQLite): Default (use supabase though in the workflow)
  • n8n EXECUTIONS_PROCESS setting (default: own, main): main I think
  • Running n8n via (Docker, npm, n8n cloud, desktop app): n8n cloud
  • Operating system: Edition: Windows 11 Home / Version: 23H2 / OS build: 22631.4602 / Experience: Windows Feature Experience Pack 1000.22700.1055.0

@oleg @barn4k @bartv @Jon - let me know y’alls thoughts on how to solve this.

Hey @dustinAIAIDE , I used to run a no-code approach to signature verification. See if this approach works for you.

@ihortom - this worked mostly! I am getting responses now at least! But, now the response code 200 is not being sent properly… I tried out so many different setups and settings of nodes (4 hours). I don’t think I still need to send the challenge back… I think there’s actually a bug in y’all’s system on this issue.

{
“nodes”: [
{
“parameters”: {
“respondWith”: “text”,
“responseBody”: “=HTTP 200 OK\nContent-type: text/plain\n{{ $json.body.challenge }}\n”,
“options”: {
“responseCode”: 200
}
},
“id”: “7ec444c9-41eb-4f9b-8d42-9928885fb5e1”,
“name”: “Respond to Webhook”,
“type”: “n8n-nodes-base.respondToWebhook”,
“typeVersion”: 1.1,
“position”: [
1980,
2560
],
“executeOnce”: false
},
{
“parameters”: {
“name”: “search_by_section”,
“description”: “Use this tool to query the texas property tax code and texas administrative code related to property tax and the texas arb manual and the continuing education for ARB members and the Texas Property Tax Assistance Property Classification Guide and Senate Bill 2 with a specific section filter”,
“workflowId”: “={{ $workflow.id }}”,
“fields”: {
“values”: [
{
“name”: “tool”,
“stringValue”: “search_by_section”
}
]
},
“specifyInputSchema”: true,
“schemaType”: “manual”,
“inputSchema”: “{\n "type": "object",\n "properties": {\n "search_query": {\n "type": "string",\n "description": "Search query for vector store similarity matching"\n },\n "section_number": {\n "type": "number",\n "format": "float",\n "description": "A float number of the section to search in"\n }\n },\n "required": ["search_query", "section_number"]\n}”
},
“id”: “17e8b37a-58e1-41cb-93db-41da51c3d988”,
“name”: “search_by_section1”,
“type”: “@n8n/n8n-nodes-langchain.toolWorkflow”,
“typeVersion”: 1.1,
“position”: [
1080,
3320
]
},
{
“parameters”: {
“name”: “search_generic”,
“description”: “Use this tool to query texas property tax code across all sections”,
“workflowId”: “={{ $workflow.id }}”,
“fields”: {
“values”: [
{
“name”: “tool”,
“stringValue”: “search”
}
]
},
“specifyInputSchema”: true,
“schemaType”: “manual”,
“inputSchema”: “{\n"type": "object",\n"properties": {\n\t"search_query": {\n\t\t"type": "string",\n\t\t"description": "Search query for vector store similarity matching"\n }\n}\n}”
},
“id”: “709ff385-a11b-4989-a184-e97c52eb6ee4”,
“name”: “search_generic1”,
“type”: “@n8n/n8n-nodes-langchain.toolWorkflow”,
“typeVersion”: 1.1,
“position”: [
940,
3320
]
},
{
“parameters”: {
“contextWindowLength”: 10
},
“id”: “5ed6c524-65c1-4e87-8cfb-61ba586ff802”,
“name”: “Window Buffer Memory1”,
“type”: “@n8n/n8n-nodes-langchain.memoryBufferWindow”,
“typeVersion”: 1.2,
“position”: [
780,
3440
],
“disabled”: true
},
{
“parameters”: {
“content”: “## Create Tools agent and connect two tools — generic search and section search\n”,
“height”: 463.42588305069273,
“width”: 1032.6338251134005,
“color”: 3
},
“id”: “b8de29d5-3012-4eeb-8945-e13aea35fb39”,
“name”: “Sticky Note4”,
“type”: “n8n-nodes-base.stickyNote”,
“typeVersion”: 1,
“position”: [
220,
3140
]
},
{
“parameters”: {
“model”: “gpt-4o”,
“options”: {
“temperature”: 0.2
}
},
“id”: “76a2818e-fbe8-4cfc-8abb-26226795de3c”,
“name”: “OpenAI Chat Model1”,
“type”: “@n8n/n8n-nodes-langchain.lmChatOpenAi”,
“typeVersion”: 1,
“position”: [
620,
3360
],
“credentials”: {
“openAiApi”: {
“id”: “uvVcua4byPMJbP47”,
“name”: “OpenAi account”
}
}
},
{
“parameters”: {
“method”: “POST”,
“url”: “https://slack.com/api/chat.postMessage”,
“authentication”: “predefinedCredentialType”,
“nodeCredentialType”: “slackApi”,
“sendHeaders”: true,
“headerParameters”: {
“parameters”: [
{
“name”: "Authorization ",
“value”: “Bearer xoxb-2316834412-7168517389186-kzCKUL9yPlgniFblE0PcGEXj”
},
{
“name”: “Content-Type”,
“value”: “application/json”
}
]
},
“sendBody”: true,
“bodyParameters”: {
“parameters”: [
{
“name”: “text”,
“value”: “={{ $(‘AI Agent1’).item.json.output }}”
},
{
“name”: “channel”,
“value”: “={{ $(‘Webhook1’).item.json.body.event.channel }}”
}
]
},
“options”: {}
},
“id”: “9371a924-bd7e-4ad0-af24-05ad4e6e73d3”,
“name”: “HTTP Request1”,
“type”: “n8n-nodes-base.httpRequest”,
“typeVersion”: 4.2,
“position”: [
1120,
2780
],
“executeOnce”: true,
“credentials”: {
“slackApi”: {
“id”: “yIUeZvMe0NCetWPY”,
“name”: “Slack account”
}
}
},
{
“parameters”: {
“promptType”: “define”,
“text”: “={{ $json.body.event.text }}”,
“options”: {
“systemMessage”: “You are a helpful Texas property tax code assistant”
}
},
“id”: “118fd29c-ded4-4fbf-842f-215ac4a95af0”,
“name”: “AI Agent1”,
“type”: “@n8n/n8n-nodes-langchain.agent”,
“typeVersion”: 1.6,
“position”: [
680,
3200
]
},
{
“parameters”: {
“httpMethod”: “POST”,
“path”: “c208245c-4d80-4120-87b6-8cd9d631276a”,
“options”: {
“responseData”: “HTTP 200 OK”
}
},
“id”: “4b470b36-c069-4f2d-9b11-3f3085aca571”,
“name”: “Webhook1”,
“type”: “n8n-nodes-base.webhook”,
“typeVersion”: 2,
“position”: [
240,
2460
],
“webhookId”: “c208245c-4d80-4120-87b6-8cd9d631276a”
},
{
“parameters”: {
“action”: “hmac”,
“type”: “SHA256”,
“value”: “=v0:{{ $json["timestamp"] }}:{{ $json["raw_body"] }}”,
“dataPropertyName”: “hash”,
“secret”: “a28949901279e204ea58925285f4f615”
},
“id”: “49daab5b-3cb9-4c5b-9614-924dd9778fd5”,
“name”: “Crypto”,
“type”: “n8n-nodes-base.crypto”,
“typeVersion”: 1,
“position”: [
960,
2440
]
},
{
“parameters”: {},
“id”: “aae0cf7a-ede1-41b2-8f83-c2cdac5d470a”,
“name”: “No Operation, do nothing”,
“type”: “n8n-nodes-base.noOp”,
“typeVersion”: 1,
“position”: [
1400,
2360
]
},
{
“parameters”: {
“conditions”: {
“options”: {
“caseSensitive”: true,
“leftValue”: “”,
“typeValidation”: “strict”,
“version”: 1
},
“conditions”: [
{
“id”: “0e6f9102-2d54-41c8-95ae-7afb5f8b635d”,
“leftValue”: “={{ $json.slack_signature }}”,
“rightValue”: “=v0={{ $json.hash }}”,
“operator”: {
“type”: “string”,
“operation”: “notEquals”
}
}
],
“combinator”: “and”
},
“options”: {}
},
“id”: “71322046-c98e-4911-ac54-8cf0d7ffa88f”,
“name”: “If signature does not match”,
“type”: “n8n-nodes-base.if”,
“typeVersion”: 2,
“position”: [
1180,
2440
]
},
{
“parameters”: {
“assignments”: {
“assignments”: [
{
“id”: “e5ae550a-a310-4af2-b271-f76f777334cc”,
“name”: “slack_signature”,
“value”: “={{ $json.headers["x-slack-signature"] }}”,
“type”: “string”
},
{
“id”: “e0cbfb50-42f9-4156-97f8-cace599f6cdf”,
“name”: “timestamp”,
“value”: “={{ $json.headers["x-slack-request-timestamp"] }}”,
“type”: “string”
},
{
“id”: “d67e380f-0897-4a5f-8e1f-fedb01730cb0”,
“name”: “body”,
“value”: “={{ $json.body }}”,
“type”: “object”
},
{
“id”: “fc10fefd-5a8b-4f26-9ce8-7de1f1bd74b9”,
“name”: “raw_body”,
“value”: “={{ $json.rawBody }}”,
“type”: “string”
}
]
},
“options”: {}
},
“id”: “06dbe6fa-2e84-417f-b972-4a22115148f1”,
“name”: “Verification pretext”,
“type”: “n8n-nodes-base.set”,
“typeVersion”: 3.3,
“position”: [
740,
2440
]
},
{
“parameters”: {
“content”: “## Slack signature verification\n### See Verifying requests from Slack”,
“height”: 272.62045280477054,
“width”: 836.8082543637081
},
“id”: “653a0199-d5a2-4ccc-827a-bb5e5645ee91”,
“name”: “Sticky Note5”,
“type”: “n8n-nodes-base.stickyNote”,
“typeVersion”: 1,
“position”: [
700,
2340
]
},
{
“parameters”: {
“operation”: “text”,
“destinationKey”: “rawBody”,
“options”: {
“keepSource”: “json”
}
},
“id”: “26711374-8e2f-448c-97e4-8a93f4cafe21”,
“name”: “Extract from File1”,
“type”: “n8n-nodes-base.extractFromFile”,
“typeVersion”: 1,
“position”: [
520,
2440
]
},
{
“parameters”: {
“conditions”: {
“options”: {
“caseSensitive”: true,
“leftValue”: “”,
“typeValidation”: “strict”,
“version”: 2
},
“conditions”: [
{
“id”: “b3f6571f-3a51-4f95-a02b-3f9d2e75eb3c”,
“leftValue”: “={{ $json.body.type }}”,
“rightValue”: “url_verification”,
“operator”: {
“type”: “string”,
“operation”: “equals”,
“name”: “filter.operator.equals”
}
}
],
“combinator”: “and”
},
“options”: {}
},
“type”: “n8n-nodes-base.if”,
“typeVersion”: 2.2,
“position”: [
1640,
2720
],
“id”: “39d4e8a1-ae54-4236-a00b-74b8cccabd9d”,
“name”: “If”
},
{
“parameters”: {
“respondWith”: “text”,
“responseBody”: “=success\n”,
“options”: {
“responseCode”: 200
}
},
“id”: “73b3dcb9-955c-414c-9999-806a34b35502”,
“name”: “Respond to Webhook2”,
“type”: “n8n-nodes-base.respondToWebhook”,
“typeVersion”: 1.1,
“position”: [
1960,
2980
],
“executeOnce”: false
}
],
“connections”: {
“Respond to Webhook”: {
“main”: [

]
},
“search_by_section1”: {
“ai_tool”: [
[
{
“node”: “AI Agent1”,
“type”: “ai_tool”,
“index”: 0
}
]
]
},
“search_generic1”: {
“ai_tool”: [
[
{
“node”: “AI Agent1”,
“type”: “ai_tool”,
“index”: 0
}
]
]
},
“Window Buffer Memory1”: {
“ai_memory”: [
[
{
“node”: “AI Agent1”,
“type”: “ai_memory”,
“index”: 0
}
]
]
},
“OpenAI Chat Model1”: {
“ai_languageModel”: [
[
{
“node”: “AI Agent1”,
“type”: “ai_languageModel”,
“index”: 0
}
]
]
},
“AI Agent1”: {
“main”: [
[
{
“node”: “HTTP Request1”,
“type”: “main”,
“index”: 0
}
]
]
},
“Webhook1”: {
“main”: [
[
{
“node”: “AI Agent1”,
“type”: “main”,
“index”: 0
},
{
“node”: “Extract from File1”,
“type”: “main”,
“index”: 0
}
]
]
},
“Crypto”: {
“main”: [
[
{
“node”: “If signature does not match”,
“type”: “main”,
“index”: 0
}
]
]
},
“If signature does not match”: {
“main”: [
[
{
“node”: “No Operation, do nothing”,
“type”: “main”,
“index”: 0
}
],
[
{
“node”: “If”,
“type”: “main”,
“index”: 0
}
]
]
},
“Verification pretext”: {
“main”: [
[
{
“node”: “Crypto”,
“type”: “main”,
“index”: 0
}
]
]
},
“Extract from File1”: {
“main”: [
[
{
“node”: “Verification pretext”,
“type”: “main”,
“index”: 0
}
]
]
},
“If”: {
“main”: [
[
{
“node”: “Respond to Webhook”,
“type”: “main”,
“index”: 0
}
],
[
{
“node”: “Respond to Webhook2”,
“type”: “main”,
“index”: 0
}
]
]
}
},
“pinData”: {}
}

@ihortom @oleg @barn4k @bartv @Jon - I think the Respond to Webhook node has a bug in it… or, Slack’s side is not receiving 200 codes properly

Hey @dustinAIAIDE , your Webhook is configured to reply immediately. You do not really engage Respond to Webhook nodes. See how Webhook is configured in my workflow. In particular, pay attention to this part - both Respond and Options. The former is needed to reply with Respond to Webhook while the letter is needed for signature varification.

image

@ihortom i realized that my n8n workflow was actually instead in an infinite loop being triggered by my (Dustin Hirner) direct message initially in Slack. But, when my n8n Slack Chatbot responded in the same chat… it was triggering the same n8n workflow… that’s, instead, why it was continuously responding with messages… cause the workflow was in an infinite loop. I instead by a condition at the beginning letting it not be triggered by the user id coming from the Slack chatbot.

2 Likes

@ihortom thank you for your help and for your suggestions which helped me stumble upon the real issue! I really appreciate it! I was going crazy troubleshooting this.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.