AutomationFlowsSlack & Telegram › Whatsapp Micro-crm with Baserow & Wasenderapi

Whatsapp Micro-crm with Baserow & Wasenderapi

ByStephan Koning @reklaim on n8n.io

Struggling to manage WhatsApp client communications? This n8n workflow isn't just automation; it's your centralized CRM solution for small businesses and freelancers.

Webhook trigger★★★★☆ complexity29 nodesHTTP RequestBaserow
Slack & Telegram Trigger: Webhook Nodes: 29 Complexity: ★★★★☆ Added:

This workflow corresponds to n8n.io template #6584 — we link there as the canonical source.

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 →

Download .json
{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "e276ac8b-4659-431e-a876-590b2532289e",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        280,
        -100
      ],
      "parameters": {
        "width": 540,
        "height": 740,
        "content": "## WhatsApp Mini-CRM with Baserow & WasenderAPI\n\nAutomate WhatsApp communication and client management for small businesses and freelancers. This n8n workflow centralizes CRM by processing messages, organizing contacts, and logging interactions, eliminating manual data entry.\n\n**How it works**\n* Receives WhatsApp messages via WasenderAPI.\n* Standardizes contact data and manages contacts (create/update).\n* Fetches profile pictures and decrypts image messages.\n* Logs all conversations, including media, into Baserow.\n\n**Setup Steps**\nSetup is quick (under 15 min). Simply connect WasenderAPI webhooks to n8n, duplicate Baserow 'Contacts' ([link](https://baserow.io/public/grid/a5iWkAQpu8QljUlgwgm_pour_Au5BKd3mtkfu-B6N7Y)) and 'Messages' ([link](https://baserow.io/public/grid/0H22XZitFDWnrVNnKwBfiI7M6XX5CugHrXHEzdCY4xY)) table templates, and add API credentials in n8n. Detailed instructions are in the workflow's sticky notes.\n\n**Requirements**\n* Active n8n instance (self-hosted/cloud).\n* WasenderAPI.com trial/subscription.\n* Baserow account.\n* External media decryption service (if used by provider).\n\n**How to customize the workflow**\nCustomize Baserow IDs, decryption, data extraction, and message content. Detailed guidance in workflow sticky notes.\n\n**Note:** Keep the flow layout as is! This will ensure that the flow is running in the correct order."
      },
      "typeVersion": 1
    },
    {
      "id": "6ffa7908-f596-4654-99f2-9ea6c57bc4a7",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1820,
        60
      ],
      "parameters": {
        "color": 7,
        "width": 820,
        "height": 520,
        "content": "## 1. Manage Incoming Contacts\n\n* **Existing Contact:** Update last activity timestamp.\n* **New Contact:** Create a new contact record using the WhatsApp number."
      },
      "typeVersion": 1
    },
    {
      "id": "83efa23c-d381-4b91-8eeb-522a544b55db",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2760,
        0
      ],
      "parameters": {
        "color": 7,
        "width": 700,
        "height": 540,
        "content": "## Optional: Contact Profile Picture\n\nThis feature fetches the WhatsApp profile picture for contacts. It is entirely optional and can be removed if not required. When enabled, this data enhances visual contact management, such as in a Baserow gallery view: [Baserow Gallery View Example](https://baserow.io/public/gallery/v7PfThVQLOIc6moc9j0Ebjq_Az4Nm3TMMDzpvF30Esk)."
      },
      "typeVersion": 1
    },
    {
      "id": "6b74df85-924c-471c-9848-e4ea2030f967",
      "name": "webhooktest (delete after testing)",
      "type": "n8n-nodes-base.noOp",
      "position": [
        2060,
        620
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "ea447200-f883-428f-b7ac-1aebe35e0979",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2000,
        800
      ],
      "parameters": {
        "color": 7,
        "width": 1160,
        "height": 520,
        "content": "## 2. Message Type Detection & Image Handling\n\nFor images, messages are first decrypted via WasenderAPI. Decrypted images are then uploaded and mapped directly to Baserow's image fields, ensuring visual content storage.\n\n\n\n\n\n\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "ce955b07-9257-4458-8301-e0a2412ccb8a",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1960,
        1640
      ],
      "parameters": {
        "color": 7,
        "width": 820,
        "height": 560,
        "content": "## 3. We only log a text message here \n\nTHE IF node is to check if the message comes from your connected wasenderapi number "
      },
      "typeVersion": 1
    },
    {
      "id": "c940dd3a-0984-49dd-848e-38608a0d877c",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1060,
        420
      ],
      "parameters": {
        "color": 6,
        "width": 380,
        "height": 240,
        "content": "## Important Note\n\nFor all message notifications (inbound/outbound), you *must* select the `messages.upsert` event.\n\n### Recommendation\n\nImplement header authentication using \"x-webhook-signature\"."
      },
      "typeVersion": 1
    },
    {
      "id": "ccb8b5b5-dec7-4d69-b3bd-e5e6e8087e64",
      "name": "Baserow: Search Contact",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1900,
        260
      ],
      "parameters": {
        "url": "https://api.baserow.io/api/database/rows/table/622539/",
        "options": {},
        "sendQuery": true,
        "sendHeaders": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "user_field_names",
              "value": "true"
            },
            {
              "name": "search",
              "value": "={{ $json.readable_phone_number }}"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Token <your token>"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "8f2f2f9c-3824-42e7-a4b7-23d4b82f20b7",
      "name": "Route: Contact Exists?",
      "type": "n8n-nodes-base.switch",
      "position": [
        2120,
        260
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "New_Contact",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "loose"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "e930a9f3-ad63-4c99-bff4-931ddbfe1bca",
                    "operator": {
                      "type": "number",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.count }}",
                    "rightValue": 0
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Existing_Contact",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "loose"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "6071cc1e-70ba-4072-bfcb-6c56aa3ecb4e",
                    "operator": {
                      "type": "number",
                      "operation": "gt"
                    },
                    "leftValue": "={{ $json.count }}",
                    "rightValue": 0
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {},
        "looseTypeValidation": true
      },
      "typeVersion": 3.2
    },
    {
      "id": "8efc8abc-e331-4a0e-b14b-b5047fbcf086",
      "name": "Create New Contact",
      "type": "n8n-nodes-base.baserow",
      "position": [
        2460,
        160
      ],
      "parameters": {
        "tableId": 622539,
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": 5064505,
              "fieldValue": "={{ $('Prepare: Standardize Incoming Data').item.json.readable_phone_number }}"
            },
            {
              "fieldId": 5064506,
              "fieldValue": "={{ $('Prepare: Standardize Incoming Data').item.json.body.data.messages.pushName }}"
            },
            {
              "fieldId": 5064507,
              "fieldValue": "New"
            },
            {
              "fieldId": 5064508,
              "fieldValue": "={{ $('Prepare: Standardize Incoming Data').item.json.body.timestamp.toDateTime('ms')}}"
            }
          ]
        },
        "operation": "create",
        "databaseId": 264981
      },
      "credentials": {
        "baserowApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "4f976974-20c2-4a52-8c29-330aad9404d7",
      "name": "Update Contact Timestamp",
      "type": "n8n-nodes-base.baserow",
      "position": [
        2460,
        360
      ],
      "parameters": {
        "rowId": "={{ $json.results[0].id }}",
        "tableId": 622539,
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": 5064508,
              "fieldValue": "={{$now.setLocale(nl-NL).toLocal()}}"
            }
          ]
        },
        "operation": "update",
        "databaseId": 264981
      },
      "credentials": {
        "baserowApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "841d7a05-5afd-4d53-80cb-bbb7b5665201",
      "name": "WasenderAPI: Fetch Profile Picture URL",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2840,
        160
      ],
      "parameters": {
        "url": "=https://www.wasenderapi.com/api/contacts/{{ $('Prepare: Standardize Incoming Data').item.json.body.data.messages.key.remoteJid }}/picture",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer <your token>"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "9f7c8e1b-94e7-446c-8286-2720c051510d",
      "name": "Baserow: Upload Profile Picture File",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        3060,
        160
      ],
      "parameters": {
        "url": "https://api.baserow.io/api/user-files/upload-via-url/",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n    \"url\": \"{{ $json.data.imgUrl}}\"\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Token <your token>"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "c834feb4-f935-4606-bf2b-c4fc27b8a2ce",
      "name": "Update Contact Profile Picture Field",
      "type": "n8n-nodes-base.baserow",
      "position": [
        3280,
        160
      ],
      "parameters": {
        "rowId": "={{ $('Create New Contact').item.json.id }}",
        "tableId": 622539,
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": 5065051,
              "fieldValue": "={{ $json.name }}"
            }
          ]
        },
        "operation": "update",
        "databaseId": 264981
      },
      "credentials": {
        "baserowApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "bd55cfc2-db60-44a3-ae86-8b5d743d385b",
      "name": "Route: Message Type (Image/Text)",
      "type": "n8n-nodes-base.switch",
      "position": [
        1600,
        980
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "Testing",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "loose"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "abc80fe6-2034-4918-8738-2cc3ce93cd03",
                    "operator": {
                      "type": "boolean",
                      "operation": "true",
                      "singleValue": true
                    },
                    "leftValue": "={{ $json.body.data.test }}",
                    "rightValue": "webhook.test"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "has_image",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "loose"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "b865b469-58bd-4cfa-b359-bb2dbeb11134",
                    "operator": {
                      "type": "boolean",
                      "operation": "true",
                      "singleValue": true
                    },
                    "leftValue": "={{ $json.found_image }}",
                    "rightValue": ""
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "txt_only",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "loose"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "9a58353d-6ed0-45b4-8553-87d4326c5bb9",
                    "operator": {
                      "type": "boolean",
                      "operation": "false",
                      "singleValue": true
                    },
                    "leftValue": "={{ $json.found_image }}",
                    "rightValue": ""
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {},
        "looseTypeValidation": true
      },
      "typeVersion": 3.2
    },
    {
      "id": "96602e32-242e-435d-9d41-4bec08ad2f8d",
      "name": "Extract: Image Message Data",
      "type": "n8n-nodes-base.set",
      "position": [
        2040,
        980
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "08f9b688-dc42-4724-b9e3-5969215f69f2",
              "name": "message_object",
              "type": "object",
              "value": "={{ $json.body.data.messages.message }}"
            },
            {
              "id": "ca2ab33b-ab78-4615-9052-f7dfafe9d20d",
              "name": "message_id",
              "type": "string",
              "value": "={{ $json.body.data.messages.key.id }}"
            },
            {
              "id": "cd93ec84-ccb1-4944-bee9-ef360bb7df8d",
              "name": "remoteJid (wasenderapi)",
              "type": "string",
              "value": "={{ $json.body.data.messages.key.remoteJid }}"
            },
            {
              "id": "a25f071c-70a6-45aa-b0fe-0c3256d41039",
              "name": "fromMe (for filtering purposes)",
              "type": "boolean",
              "value": "={{ $json.body.data.messages.key.fromMe }}"
            },
            {
              "id": "a09926b2-52ab-44ce-ba6c-29a58c90d99a",
              "name": "readable_phone_number",
              "type": "string",
              "value": "={{ $json.readable_phone_number }}"
            },
            {
              "id": "72993315-16a0-4aab-89d5-38dd354aa6df",
              "name": "found_image",
              "type": "boolean",
              "value": "={{ $json.found_image }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "18b56bc9-a2c5-48b0-a9e2-e6397b1ac522",
      "name": "WasenderAPI: Decrypt Image Outbound",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2520,
        920
      ],
      "parameters": {
        "url": "https://www.wasenderapi.com/api/decrypt-media",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"data\": {\n    \"messages\": {\n      \"key\": {\n        \"id\": \"{{ $json.message_id }}\"\n      },\n      \"message\": {\n        \"imageMessage\": {\n          \"url\": \"{{ $json.message_object.imageMessage.url }}\",\n          \"mimetype\": \"{{ $json.message_object.imageMessage.mimetype }}\",\n          \"mediaKey\": \"{{ $json.message_object.imageMessage.mediaKey }}\"\n        }\n      }\n    }\n  }\n} ",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer <your token>"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "dcce686f-56c4-4073-917f-1cdbcf2f2668",
      "name": "WasenderAPI: Decrypt Image Inbound",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2520,
        1100
      ],
      "parameters": {
        "url": "https://www.wasenderapi.com/api/decrypt-media",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"data\": {\n    \"messages\": {\n      \"key\": {\n        \"id\": \"{{ $json.message_id }}\"\n      },\n      \"message\": {\n        \"imageMessage\": {\n          \"url\": \"{{ $json.message_object.imageMessage.url }}\",\n          \"mimetype\": \"{{ $json.message_object.imageMessage.mimetype }}\",\n          \"mediaKey\": \"{{ $json.message_object.imageMessage.mediaKey }}\"\n        }\n      }\n    }\n  }\n} ",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer <your token>"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "bf50d793-04a4-4b5d-bf13-c311b604a2d1",
      "name": "Baserow Upload Message Image",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2720,
        920
      ],
      "parameters": {
        "url": "https://api.baserow.io/api/user-files/upload-via-url/",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n    \"url\": \"{{ $json.publicUrl }}\"\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Token <your token>"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "87b605aa-b7be-4a36-bb9d-e1d35e67afbd",
      "name": "Baserow_Upload Message Image",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2720,
        1100
      ],
      "parameters": {
        "url": "https://api.baserow.io/api/user-files/upload-via-url/",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n    \"url\": \"{{ $json.publicUrl }}\"\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Token <your token>"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "65ecd4e0-6b34-4b76-8ab5-9bcb7ff9d23e",
      "name": "Log Inbound Image Message",
      "type": "n8n-nodes-base.baserow",
      "position": [
        2940,
        1100
      ],
      "parameters": {
        "tableId": 622533,
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": 5064439,
              "fieldValue": "={{ $('Extract: Image Message Data').item.json.message_id }}"
            },
            {
              "fieldId": 5064440,
              "fieldValue": "={{ $('Extract: Image Message Data').item.json.readable_phone_number }}"
            },
            {
              "fieldId": 5065335,
              "fieldValue": "={{ $json.name }}"
            },
            {
              "fieldId": 5064444,
              "fieldValue": "Unread"
            },
            {
              "fieldId": 5064441,
              "fieldValue": "Inbound"
            },
            {
              "fieldId": 5064443,
              "fieldValue": "={{ $('Extract: Image Message Data').item.json.message_object.messageContextInfo.deviceListMetadata.recipientTimestamp.toDateTime('s')}}"
            }
          ]
        },
        "operation": "create",
        "databaseId": 264981
      },
      "credentials": {
        "baserowApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "421dce70-b96e-4697-8db1-2d3b1914aad5",
      "name": "Log Outbound Image Message",
      "type": "n8n-nodes-base.baserow",
      "position": [
        2940,
        920
      ],
      "parameters": {
        "tableId": 622533,
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": 5064439,
              "fieldValue": "={{ $('Extract: Image Message Data').item.json.message_id }}"
            },
            {
              "fieldId": 5064440,
              "fieldValue": "={{ $('Extract: Image Message Data').item.json.readable_phone_number }}"
            },
            {
              "fieldId": 5065335,
              "fieldValue": "={{ $json.name }}"
            },
            {
              "fieldId": 5064444,
              "fieldValue": "Unread"
            },
            {
              "fieldId": 5064441,
              "fieldValue": "Outbound"
            },
            {
              "fieldId": 5064443,
              "fieldValue": "={{ $('Extract: Image Message Data').item.json.message_object.messageContextInfo.deviceListMetadata.recipientTimestamp.toDateTime('s')}}"
            }
          ]
        },
        "operation": "create",
        "databaseId": 264981
      },
      "credentials": {
        "baserowApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "fd725c80-806f-463e-b812-093d86eec91d",
      "name": "Extract: Text Message Data",
      "type": "n8n-nodes-base.set",
      "position": [
        2000,
        1860
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "08f9b688-dc42-4724-b9e3-5969215f69f2",
              "name": "message_object",
              "type": "object",
              "value": "={{ $json.body.data.messages.message }}"
            },
            {
              "id": "ca2ab33b-ab78-4615-9052-f7dfafe9d20d",
              "name": "message_id",
              "type": "string",
              "value": "={{ $json.body.data.messages.key.id }}"
            },
            {
              "id": "cd93ec84-ccb1-4944-bee9-ef360bb7df8d",
              "name": "remoteJid (wasenderapi)",
              "type": "string",
              "value": "={{ $json.body.data.messages.key.remoteJid }}"
            },
            {
              "id": "a25f071c-70a6-45aa-b0fe-0c3256d41039",
              "name": "fromMe (for filtering purposes)",
              "type": "boolean",
              "value": "={{ $json.body.data.messages.key.fromMe }}"
            },
            {
              "id": "a09926b2-52ab-44ce-ba6c-29a58c90d99a",
              "name": "readable_phone_number",
              "type": "string",
              "value": "={{ $json.readable_phone_number }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "e05079d7-6e92-4716-bec1-240886628b50",
      "name": "Route: Message Origin (Outbound/Inbound)",
      "type": "n8n-nodes-base.if",
      "position": [
        2180,
        1860
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "87a619cb-67b0-4f86-abdf-6e06a53da2d4",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json['fromMe (for filtering purposes)'] }}",
              "rightValue": ""
            }
          ]
        },
        "looseTypeValidation": true
      },
      "typeVersion": 2.2
    },
    {
      "id": "b543195a-4ae8-40a3-8401-f0e422bb80dc",
      "name": "Log Outbound Text Message",
      "type": "n8n-nodes-base.baserow",
      "position": [
        2480,
        1760
      ],
      "parameters": {
        "tableId": 622533,
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": 5064439,
              "fieldValue": "={{ $json.message_id }}"
            },
            {
              "fieldId": 5064440,
              "fieldValue": "={{ $json.readable_phone_number }}"
            },
            {
              "fieldId": 5064444,
              "fieldValue": "Unread"
            },
            {
              "fieldId": 5064441,
              "fieldValue": "Outbound"
            },
            {
              "fieldId": 5064443,
              "fieldValue": "={{ $json.message_object.messageContextInfo.deviceListMetadata.recipientTimestamp.toDateTime('s')}}"
            },
            {
              "fieldId": 5064442,
              "fieldValue": "={{ $json.message_object.conversation || $json.message_object.reactionMessage.text}}"
            }
          ]
        },
        "operation": "create",
        "databaseId": 264981
      },
      "credentials": {
        "baserowApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "da6b95a9-ac1d-4f90-a1ac-ff47b2826eaa",
      "name": "Log Inbound Text Message",
      "type": "n8n-nodes-base.baserow",
      "position": [
        2460,
        1980
      ],
      "parameters": {
        "tableId": 622533,
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": 5064439,
              "fieldValue": "={{ $json.message_id }}"
            },
            {
              "fieldId": 5064440,
              "fieldValue": "={{ $json.readable_phone_number }}"
            },
            {
              "fieldId": 5064444,
              "fieldValue": "Unread"
            },
            {
              "fieldId": 5064441,
              "fieldValue": "Inbound"
            },
            {
              "fieldId": 5064443,
              "fieldValue": "={{ $json.message_object.messageContextInfo.deviceListMetadata.recipientTimestamp.toDateTime('s')}}"
            },
            {
              "fieldId": 5064442,
              "fieldValue": "={{ $json.message_object.conversation || $json.message_object.reactionMessage.text}}"
            }
          ]
        },
        "operation": "create",
        "databaseId": 264981
      },
      "credentials": {
        "baserowApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "ff623bac-b802-41c0-9053-129b725c0e78",
      "name": "Trigger: WhatsApp Message",
      "type": "n8n-nodes-base.webhook",
      "position": [
        1140,
        720
      ],
      "parameters": {
        "path": "9218c291-18b1-44a6-9b1c-4df4ff7605f6",
        "options": {},
        "httpMethod": "POST",
        "authentication": "headerAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "70541065-1e4c-4ad0-bdd8-73a319f48699",
      "name": "Prepare: Standardize Incoming Data",
      "type": "n8n-nodes-base.code",
      "position": [
        1320,
        720
      ],
      "parameters": {
        "language": "python",
        "pythonCode": "import json\n\ndef check_for_image_message(whatsapp_payload_body):\n    \"\"\"\n    Checks if a WhatsApp webhook payload contains an image message\n    and extracts the URL if present. \n\n    Args:\n        whatsapp_payload_body (dict): The 'body' of the WhatsApp webhook payload.\n\n    Returns:\n        tuple: (bool, str or None) A tuple where the first element is True\n                       if an image message is found, otherwise False.\n                       The second element is the URL of the image if found,\n                       otherwise None.\n    \"\"\"\n    try:\n        message_data = whatsapp_payload_body.get('data', {}).get('messages', {}).get('message', {})\n\n        if 'imageMessage' in message_data and message_data['imageMessage']:\n            image_message = message_data['imageMessage']\n            image_url = image_message.get('url')\n            return True, image_url\n        else:\n            return False, None\n    except Exception as e:\n        print(f\"Error in check_for_image_message: {e}\")\n        return False, None\n\n# Function to convert JID to readable phone number\ndef jid_to_readable_number(jid):\n    \"\"\"\n    Converts a WhatsApp JID to a readable phone number format.\n    Example: 'user@example.com' -> '+1234567890'\n    \"\"\"\n    if jid and '@s.whatsapp.net' in jid:\n        number_part = jid.split('@')[0]\n        return f'+{number_part}'\n    return jid # Returns original JID if format not recognized\n\n\nfor item in items:\n    whatsapp_full_payload = item.json\n\n    # Check if 'body' and 'remoteJid' exist before attempting to convert\n    remote_jid = whatsapp_full_payload.get('body', {}).get('data', {}).get('messages', {}).get('remoteJid')\n    \n    # Add the readable phone number\n    item.json['readable_phone_number'] = jid_to_readable_number(remote_jid)\n\n    # Perform image detection as before\n    found_image, image_url = check_for_image_message(whatsapp_full_payload.get('body', {}))\n    item.json['found_image'] = found_image\n    item.json['image_url'] = image_url\n    \nreturn items"
      },
      "typeVersion": 2
    },
    {
      "id": "0bfec423-676f-4113-8d12-8b8b41c3d67d",
      "name": "Route: Message Origin (Outbound/Inbound)1",
      "type": "n8n-nodes-base.if",
      "position": [
        2240,
        980
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "87a619cb-67b0-4f86-abdf-6e06a53da2d4",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json['fromMe (for filtering purposes)'] }}",
              "rightValue": ""
            }
          ]
        },
        "looseTypeValidation": true
      },
      "typeVersion": 2.2
    }
  ],
  "connections": {
    "Create New Contact": {
      "main": [
        [
          {
            "node": "WasenderAPI: Fetch Profile Picture URL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route: Contact Exists?": {
      "main": [
        [
          {
            "node": "Create New Contact",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Update Contact Timestamp",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Baserow: Search Contact": {
      "main": [
        [
          {
            "node": "Route: Contact Exists?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Trigger: WhatsApp Message": {
      "main": [
        [
          {
            "node": "Prepare: Standardize Incoming Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract: Text Message Data": {
      "main": [
        [
          {
            "node": "Route: Message Origin (Outbound/Inbound)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract: Image Message Data": {
      "main": [
        [
          {
            "node": "Route: Message Origin (Outbound/Inbound)1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Baserow Upload Message Image": {
      "main": [
        [
          {
            "node": "Log Outbound Image Message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Baserow_Upload Message Image": {
      "main": [
        [
          {
            "node": "Log Inbound Image Message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route: Message Type (Image/Text)": {
      "main": [
        [
          {
            "node": "webhooktest (delete after testing)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Extract: Image Message Data",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Extract: Text Message Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare: Standardize Incoming Data": {
      "main": [
        [
          {
            "node": "Route: Message Type (Image/Text)",
            "type": "main",
            "index": 0
          },
          {
            "node": "Baserow: Search Contact",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "WasenderAPI: Decrypt Image Inbound": {
      "main": [
        [
          {
            "node": "Baserow_Upload Message Image",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "WasenderAPI: Decrypt Image Outbound": {
      "main": [
        [
          {
            "node": "Baserow Upload Message Image",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Baserow: Upload Profile Picture File": {
      "main": [
        [
          {
            "node": "Update Contact Profile Picture Field",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "WasenderAPI: Fetch Profile Picture URL": {
      "main": [
        [
          {
            "node": "Baserow: Upload Profile Picture File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route: Message Origin (Outbound/Inbound)": {
      "main": [
        [
          {
            "node": "Log Outbound Text Message",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Log Inbound Text Message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route: Message Origin (Outbound/Inbound)1": {
      "main": [
        [
          {
            "node": "WasenderAPI: Decrypt Image Outbound",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "WasenderAPI: Decrypt Image Inbound",
            "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.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Struggling to manage WhatsApp client communications? This n8n workflow isn't just automation; it's your centralized CRM solution for small businesses and freelancers.

Source: https://n8n.io/workflows/6584/ — original creator credit. Request a take-down →

More Slack & Telegram workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Slack & Telegram

This workflow integrates with your Baserow 'Messages' table, triggering on 'Sent' status. Messages fire via WasenderAPI, rigorously logged as 'Outbound' in Baserow. Gain total control; drive results.

HTTP Request, Baserow
Slack & Telegram

HR teams, IT Operations, and System Administrators managing employee onboarding at scale. It’s perfect if you use Odoo 18 to trigger account requests and need Redmine + GitLab accounts created instant

HTTP Request, Slack
Slack & Telegram

This workflow is a complete, production-ready solution for recovering abandoned carts in Shopify stores using a multi-channel, multi-touch approach. It automates personalized follow-ups via Email, SMS

HTTP Request, Shopify, SendGrid +5
Slack & Telegram

qualiopi. Uses airtable, telegram, emailSend, httpRequest. Webhook trigger; 51 nodes.

Airtable, Telegram, Email Send +3
Slack & Telegram

This workflow automates end-to-end research analysis by coordinating multiple AI models—including NVIDIA NIM (Llama), OpenAI GPT-4, and Claude to analyze uploaded documents, extract insights, and gene

HTTP Request, Postgres, Slack +1