If you have ever said, “I just want Instagram to answer the basic questions for me,” welcome. That was me.
I did not want to manually reply to every “How do I join?”, “Send the WhatsApp link,” or “How do I get into the group?” message forever. I wanted a system that could handle the obvious questions, leave the real conversations for humans, and not feel like I duct-taped six random tutorials together at 2 AM.
So I built an Instagram DM autoresponder using n8n and the Meta Graph API.
And because nothing in automation is ever as clean as the diagram in your head, I also broke it, fixed it, accidentally made it spam 20 replies, and then tightened it into something I would actually trust.
If you want to build one too, here is the plain-English version.
The goal was simple:
For this setup, I only wanted the bot to answer messages related to joining the community.
That means words and phrases like:
joinlinkgroupwhatsapphow to joinsign upsignupmembermembershipcommunitycrewIf the message says “good morning” or “nice hike today,” the bot should mind its business.
This build used:
https://graph.facebook.com/v21.0/me/messagesThe production webhook ended up looking like this:
https://your-n8n-domain.com/webhook/instagram-dm-autoresponder
I am using a placeholder there on purpose. Publish the workflow pattern, not your live production callback URL.
This sounds basic, but if the account setup is wrong, everything after this is just very expensive confusion.
You need:
Here is what the Instagram/Page connection looked like on my end. I redacted the personal and business-specific bits, because a tutorial should teach the setup without turning into a data leak:

Then I checked Page access and confirmed the correct Facebook user had Full control:

If you skip this part, you will spend hours blaming tokens for a problem that is actually permissions.
This was the biggest trap.
At first, I had a token that looked real enough to trust. Meta disagreed. The API kept returning:
Invalid OAuth access token - Cannot parse access token
That error usually means one of three things:
The fix was not “generate another random token and pray.” The fix was using the correct flow:
pages_show_listbusiness_managementinstagram_basicinstagram_manage_messagespages_read_engagementpages_manage_metadataThe Graph API Explorer setup looked like this. Again, I redacted the actual token and account-specific details:

Then I queried the accounts endpoint for the Page token:
GET https://graph.facebook.com/v25.0/me/accounts
fields: id, name, access_token, instagram_business_account
access_token: USER_TOKEN
That response finally gave me the Page access token I actually needed for sending messages.
That is the token that belongs in n8n.
Not the user token. Not the first thing Meta puts in front of you. The Page token.
The workflow shape was pretty clean once the Meta side stopped fighting me.
I used two webhook paths on the same endpoint:
Used for Meta verification.
Meta sends:
hub.modehub.verify_tokenhub.challengeIf the verify token matches, the workflow responds with the challenge value.
Used for actual Instagram DM events.
The incoming event gives you the sender ID here:
entry[0].messaging[0].sender.id
And the message text here:
entry[0].messaging[0].message.text
From there, the workflow:
This part matters if you do not want your account sounding like a confused robot at a networking event.
I added logic in the n8n Code node to:
The core idea looked like this:
const triggerPhrases = [
'link',
'join',
'whatsapp',
'group',
'how to join',
'sign up',
'signup',
'member',
'membership',
'community',
'crew',
];
const matchedTrigger =
triggerPhrases.find((phrase) => normalizedText.includes(phrase)) || '';
const shouldReply = Boolean(senderId && message && !isEcho && matchedTrigger);
That one check turns the workflow from “reply to everything” into “reply only when the person is clearly asking about joining.”
This was the fun part. By “fun,” I mean deeply annoying.
The bot started sending the same reply over and over again.
Why?
Because Meta was sending my own outgoing messages back into the webhook as events.
In other words:
The clue was the is_echo flag inside the incoming payload.
Once I saw that, the fix was obvious:
message.is_echo === trueThat one change stopped the reply storm immediately.
And honestly, this is why I always say the real work in automation is not the happy path. The real work is all the weird little “Why is the machine talking to itself?” moments.
Once the sender ID and token were correct, the reply node in n8n posted to:
https://graph.facebook.com/v21.0/me/messages
With a body shaped like:
{
"recipient": {
"id": "SENDER_ID"
},
"message": {
"text": "YOUR_REPLY_TEXT"
}
}
When I tested with a fake sender ID, Meta returned:
(#100) Parameter error: You cannot send messages to this id
That turned out to be a good sign.
Why? Because it proved the token was finally valid. The auth layer was working. The only reason it failed was because I used a fake recipient in testing.
That is a much better problem than “your token is nonsense.”
I set the bot to answer with this message when someone asks to join:
Welcome to the Fam! 👋 We are happy to have you join us. No big requirements here, just bring good energy and the ability to manage the hike and you are good to go!
How to stay in the loop 📸 Follow us on IG:
@lifestylehikers🌐 Check the website:lifestylehikers.comHow it works When the next hike drops, you will see the date and meeting spot posted on our socials and the website. Just show up and you are in. It is as simple as that.
Important Please head over to the website and fill out the Join the Community form. This is the best way to stay updated and officially get plugged into the group.
About the WhatsApp group Our WhatsApp group is for active members only. You will get your invite after completing 3 hikes with us. That is how we keep the energy right and the group tight. Show up, hike, and your spot is waiting! 🏔️🌿
See you on the trail! 🇯🇲
That way the bot is useful, on-brand, and not pretending to be a full customer support department.
If you want the short version, here it is:
Most tutorials stop at “send a message automatically.”
That is not the hard part.
The hard part is making it send the right message, to the right person, at the right time, exactly once.
That is the difference between a demo and a real workflow.
My recommendation:
/me/accountsis_echo eventsDo those five things and you will skip half the pain I walked through.
And if your bot suddenly sends 20 messages in a row, congratulations, you are officially building real automation now.