Text HELP to your number. An n8n workflow picks up the incoming SMS, checks the keyword, and sends an acknowledgement from the same phone.
That's what we'll build here: a two-way SMS workflow using an Android phone, its existing SIM card, and three n8n nodes. You can use the same pattern for support requests, appointment confirmations, or replies to notifications.
Disclosure: I built SimGate, the Android SMS gateway used in this tutorial. I'll show the complete workflow, including the filtering code and the limitations of the starter template.
How the n8n SMS auto-reply works
Someone texts HELP to your SIM number
→ Android phone receives the SMS
→ SimGate forwards the event to n8n
→ Code node checks the sender, device, and keyword
→ SimGate sends an acknowledgement to the sender
n8n handles the workflow logic. SimGate connects it to the Android phone. The phone sends the reply through its SIM, so the recipient sees that SIM's number.
The starter only replies to one test sender through one configured device. It ignores other messages. This makes it easier to test the whole conversation before connecting customer records or other actions.
What you need
- An Android phone with an active SIM that can send and receive SMS.
- The SimGate app installed and connected to your account.
- n8n Cloud or a self-hosted n8n instance.
- A separate phone you control to send the test message and receive the reply.
Keep the gateway phone powered and online, grant the app its SMS permissions, and confirm that the SIM can receive an ordinary text. If you haven't paired a phone yet, the SimGate setup guide includes a short video and the steps to connect it.
For self-hosted n8n, your webhook URL must be publicly reachable over HTTPS. The hosted SimGate service cannot deliver an event to localhost.
Sending uses your SIM plan and SimGate quota. n8n may also have subscription or hosting costs.
1. Install the SimGate nodes and add credentials
SimGate is a verified n8n integration, available on n8n Cloud and self-hosted instances.
Using an n8n owner or admin account:
- Open a workflow and select + to open the nodes panel.
- Search for SimGate.
- Select the integration and choose Install.
You will use two nodes: SimGate Trigger for incoming SMS and SimGate for sending the reply.
Next, create an API key under API in the SimGate dashboard. In n8n, create a SimGate API credential:
| Field | Value |
|---|---|
| API Key | Your dashboard API key |
| Base URL | https://api.simgate.app |
| Webhook Signing Secret | Leave empty for automatic registration |
Use the credential's Test button to check the connection. Store the key in this credential rather than in the Code node.
2. Import the SMS auto-reply workflow
Download the n8n HELP auto-reply workflow JSON.
In n8n, open the workflow menu, choose Import from File, and select the downloaded JSON. The workflow imports inactive and contains three nodes:
Receive SMS → Prepare HELP reply → Send reply
Before activating it:
- Open Receive SMS, select your SimGate API credential, and keep SMS Received selected.
- Open Prepare HELP reply and replace
REPLACE_WITH_YOUR_TEST_NUMBERwith your separate test phone's number in international format, such as+14155550100. Use your real test number; this is an example. - Replace
REPLACE_WITH_DEVICE_IDwith the gateway phone's device ID from your SimGate dashboard. - Open Send reply and select the same credential.
The following sections explain the payload and every part of the workflow. You can also build it manually with a SimGate Trigger, a Code node, and a SimGate send action.
On activation, the trigger registers its webhook and captures the signing secret automatically. It verifies signed deliveries and checks that their timestamps are within five minutes of the n8n host's clock.
One account has one webhook destination. If your SimGate account already delivers events elsewhere, activation reports a conflict. Review the existing consumer before replacing it. For several inbound automations, use one trigger workflow and branch inside it.
3. Read the incoming SMS payload
The SimGate Trigger emits the event directly as an n8n item. An example looks like this:
{
"id": "3f8f0b16-84e3-4a37-9b0e-53b0d2d1d1a1",
"type": "sms.received",
"createdAt": "2026-10-03T09:12:44.001Z",
"data": {
"deviceId": "android-example-device",
"from": "+14155550100",
"body": "HELP",
"receivedAt": "2026-10-03T09:12:43.880Z"
}
}
The fields we'll use are:
| Field | Purpose |
|---|---|
id |
Identify the event when adding deduplication |
data.from |
Send the acknowledgement back to this number |
data.body |
Match the incoming keyword |
data.deviceId |
Reply through the phone that received the SMS |
With the SimGate Trigger, the message text is at $json.data.body. There is no extra body wrapper around the event.
4. Match HELP in the Code node
Set Prepare HELP reply to Run Once for All Items. This is the filtering code included in the download:
const allowedSender = 'REPLACE_WITH_YOUR_TEST_NUMBER';
const allowedDevice = 'REPLACE_WITH_DEVICE_ID';
return $input.all().flatMap((item, index) => {
const event = item.json;
const data = event.data;
if (event.type !== 'sms.received' || !event.id || !data) return [];
if (data.from !== allowedSender || data.deviceId !== allowedDevice) return [];
if (typeof data.body !== 'string' || data.body.trim().toUpperCase() !== 'HELP') return [];
if (!/^\+[1-9]\d{6,14}$/.test(data.from)) return [];
return [{
json: {
eventId: event.id,
deviceId: data.deviceId,
phoneNumber: data.from,
message: 'Thanks for contacting us. A team member will help you shortly.',
},
pairedItem: { item: index },
}];
});
Replace the two configuration values before running it. The sender comparison is exact: use the format shown in your actual incoming event.
The keyword check accepts HELP, help, and HELP. It ignores Hello and I need help, because neither is the exact keyword after normalization. Returning an empty array stops those items from reaching the send action.
Change the acknowledgement to match what your workflow actually does. This template sends a text; it doesn't create a support ticket. Add a helpdesk or CRM action if you promise follow-up.
5. Send the reply from the receiving device
In Send reply, select resource Message and operation Send. Set these fields to expressions:
| Field | Expression |
|---|---|
| Device, using By ID | {{ $json.deviceId }} |
| To | {{ $json.phoneNumber }} |
| Message | {{ $json.message }} |
These are already configured in the imported workflow.
Test Mode still sends a real SMS. It changes which SimGate quota is used. Keep it enabled for this pilot and use your own test recipient.
The workflow selects the receiving phone, but it does not explicitly choose an outbound SIM slot. If that phone has two SIMs, check its sending configuration and verify which number the reply comes from.
6. Test a complete conversation
- Save and publish or activate the workflow after configuring the credentials and both placeholders.
- From your separate test phone, send
HELPto the gateway SIM's number. - Open the new n8n execution. The trigger should contain the event, and Prepare HELP reply should output one item.
- Check that Send reply returns a message ID, then confirm that the acknowledgement reaches your test phone.
- Send
Hello. A new execution should start, but the Code node should output no items and send no reply.
A successful send response means the command was accepted. To inspect its outcome, use another SimGate node with Message → Get and the returned messageId. Check the recipient phone to confirm receipt.
The template leaves automatic send retries off. A timeout can happen after a command was accepted, so blindly repeating the send may create a second SMS. Inspect the execution and message status before retrying an uncertain result.
Before expanding beyond your test number
The starter does not persist processed event IDs or enforce a cooldown. The same event delivered twice can produce two acknowledgements, even though only your allowed sender receives them.
Remember event IDs across executions
Add a Remove Duplicates node between Prepare HELP reply and Send reply. Choose Remove Items Processed in Previous Executions, set Keep Items Where to Value Is New, and use {{ $json.eventId }} for Value to Dedupe On.
Its history is bounded. Also, remembering an event and sending an SMS are separate operations: a failure between them can leave the event recorded without a reply sent.
For workflows that need recovery, store the event ID, processing state, outgoing message ID, and errors in a database with a unique event-ID constraint. Reconcile uncertain sends before trying again.
Limit replies and keep keyword matching narrow
Store the last reply time by device and sender in a persistent database. A five-minute cooldown is one possible starting point. If executions can overlap, make the cooldown check and claim atomic.
Keep exact keyword matching and exclude your own gateway numbers and known automated senders. Replying to every incoming text can create a conversation between two autoresponders.
If you add subscription messaging, handle STOP separately and store the contact's preference for your outbound workflows. This HELP template ignores STOP; it doesn't implement opt-outs.
Monitor downstream failures
The trigger acknowledges the webhook before downstream actions finish. Successful webhook delivery doesn't prove that the reply or a CRM update succeeded. Monitor failed n8n executions and keep enough state to recover unfinished work.
Troubleshooting
| Symptom | What to check |
|---|---|
| No n8n execution | Workflow activation, phone connection, SMS permissions, and the public HTTPS webhook URL |
| The phone shows a message, but no SMS event arrives | Confirm the sender used SMS; an RCS chat or MMS is a different message type |
| Trigger runs, but no reply | Both placeholders, exact data.from and data.deviceId values, and whether the text matches HELP
|
| Webhook conflict | Another destination or temporary test listener may already use the account's webhook slot |
| Signature or timestamp error | The n8n host clock, current signing secret, and any proxy rewriting the request body |
| Send returns successfully, but no SMS arrives | Message status, gateway connectivity, quota, and the SIM's ability to send ordinary SMS |
Once this works, replace the HELP branch with your own routing: look up a booking, create a support ticket, or record a confirmation. For booking confirmations, include a booking reference when one sender can have several appointments; a plain YES is otherwise ambiguous.
What would you connect to incoming SMS first: appointment confirmations, support requests, or something else?
Adapted from my original SimGate tutorial.

Top comments (0)