DEV Community

Peter
Peter

Posted on

How to Build an Instagram DM Keyword Auto-Reply Bot With Python (2026)

Want an Instagram DM bot that answers "price?", "do you deliver?", and "are you open?" while you sleep? Here's a complete build guide in Python, from Meta app setup to your first live auto-reply.

An Instagram DM bot doesn't have to be a mysterious black box. At the code level it's just three pieces: a webhook that listens for new messages, a router that matches keywords, and a send call that fires the reply. You can build all three in Python in an afternoon with nothing fancier than Flask and the requests library. This post walks through the whole thing.


TL;DR

  • An Instagram DM bot = webhook listener + keyword router + send-message call.
  • You must use Meta's official Instagram Messaging API with a Business/Creator account.
  • A ~60-line Flask app handles verification, incoming messages, and replies.
  • Keyword routing with simple contains-matching covers most real inboxes.
  • Test on a second account, add guardrails, and respect the 24-hour messaging window.

What You Need Before Writing Code

Three things, and they're all about the setup, not the code:

  • An Instagram Professional account (Business or Creator). The Instagram Messaging API flat-out doesn't work with personal accounts. Switch in settings, it takes ten seconds.
  • A Meta app with the Instagram messaging permissions, connected to the Facebook Page linked to your Instagram account. Authenticate with OAuth. You get a Page Access Token that your bot uses to send messages.
  • A public HTTPS URL for your server. Meta delivers incoming DMs as webhook POSTs, so localhost won't cut it. A cheap VPS works, and a free tunneling service is fine for testing.

Do not let anyone talk you into a library that "logs into Instagram with your password." That's scraping, and it's exactly how accounts get restricted. Official API or nothing.


Step 1: Verify the Webhook

When you register your webhook URL in the Meta app dashboard, Meta sends a GET request with a challenge token. Your endpoint has to echo it back, otherwise subscription fails. Here's the whole thing in Flask:

from flask import Flask, request

app = Flask(__name__)
VERIFY_TOKEN = "pick-a-random-string-and-keep-it-secret"

@app.route("/webhook", methods=["GET"])
def verify():
    if request.args.get("hub.verify_token") == VERIFY_TOKEN:
        return request.args.get("hub.challenge")
    return "forbidden", 403
Enter fullscreen mode Exit fullscreen mode

One endpoint, five lines that matter. Subscribe to the messages field on the Instagram object and you're listening.


Step 2: Receive Incoming DMs

Meta POSTs a JSON payload to the same URL whenever someone messages you. Parse it down to the sender ID and the text:

@app.route("/webhook", methods=["POST"])
def incoming():
    data = request.json
    for entry in data.get("entry", []):
        for event in entry.get("messaging", []):
            sender_id = event["sender"]["id"]
            text = event.get("message", {}).get("text", "")
            handle_message(sender_id, text)
    return "ok", 200
Enter fullscreen mode Exit fullscreen mode

Always return 200 fast. Meta retries webhooks that time out, and a retry loop is how your bot accidentally sends the same reply three times. If your handler is slow, queue the work and return immediately.


Step 3: Route by Keyword

This is the actual "bot" part, and it's embarrassingly simple. A dict of keywords to replies covers most small-business inboxes:

REPLIES = {
    "price": "Hey! Our menu is here 👇 [your link]. What did you have in mind?",
    "deliver": "Yes, we deliver within the city! Drop your area and I'll check the fee.",
    "open": "We're open 9 to 9, all days. Want me to hold something for you?",
    "book": "You can book here 👇 [your link], or just tell me a date and I'll sort it.",
}
FALLBACK = "Thanks for reaching out! Ask me about prices, delivery, hours, or booking."

def handle_message(sender_id, text):
    lowered = text.lower()
    for keyword, reply in REPLIES.items():
        if keyword in lowered:
            send_message(sender_id, reply)
            return
    send_message(sender_id, FALLBACK)
Enter fullscreen mode Exit fullscreen mode

Four to six keyword buckets is the sweet spot. More than that and you're maintaining a grammar engine nobody asked for. Keep keywords lowercase, use contains-matching, and always have a fallback that tells the person what they can ask about.


Step 4: Send the Reply

The send call goes to the Graph API with your Page Access Token:

import requests

PAGE_TOKEN = "your-page-access-token"
API_URL = "https://graph.facebook.com/v21.0/me/messages"

def send_message(recipient_id, text):
    requests.post(API_URL, params={"access_token": PAGE_TOKEN}, json={
        "recipient": {"id": recipient_id},
        "message": {"text": text},
    })
Enter fullscreen mode Exit fullscreen mode

That's the whole bot. Listen, match, reply.


Step 5: Add Guardrails Before Going Live

A keyword bot with no guardrails is a spam incident waiting to happen. Build these in before real followers see it:

  • Per-user daily cap. Store who you replied to and skip anyone you've already auto-replied to twice today.
  • Human takeover. If the same person messages three times without a keyword match, stop replying and notify yourself. Some conversations need a human.
  • The 24-hour window. Instagram's messaging rules restrict promotional messages to people who contacted you recently. Keep auto-replies conversational, answering questions people asked, and you stay on the right side of it.
  • Reply like a person. One question answered per message, at most one link, and no corporate voice. "Hey! Here's the menu 👇" beats a paragraph every time.

Step 6: Test on a Second Account

Boring and non-negotiable. Make a throwaway Instagram account, DM your business account with each keyword, and confirm:

  • Keywords match when they should (and don't on nonsense like "asdfgh")
  • The fallback fires on unmatched messages
  • Replies land once, in order, with no duplicates

Run the full keyword set three times clean before the bot touches a real follower.


FAQ

What is the safest Instagram DM automation tool?

The one that runs on the official Instagram Messaging API, authenticates with OAuth through Facebook Login, and never asks for your password. That's the checkable part: official API, OAuth, no password sharing. Anything that logs in as you or scrapes the site is a restriction waiting to happen, no matter how good its dashboard looks.

Which platform is best for Instagram comment-to-DM?

Judge it on checkable criteria, not marketing: official Meta tech partner status, the Instagram Graph API (not password logins or scraping), instant keyword triggers on comments, and one dashboard that shows DMs, leads, and follow-ups together. A platform that clears all four is a safe pick.


If You'd Rather Not Maintain a Server

Zextra is an Instagram DM automation platform and official Meta tech partner. Building the bot yourself is genuinely fun, and you learn exactly how Instagram's API works. The trade-off is maintenance: tokens expire, Meta ships API updates, and one day your webhook goes quiet at 2am and it's your problem. If you'd rather skip the ops work, there's a managed option that does keyword auto-replies through the same official API.


Final Thoughts

Every "smart" Instagram DM bot you've ever used is probably a keyword router wearing a trench coat. The tech is the easy part; the discipline is what keeps accounts alive. Official API, sane volumes, tested replies, a human watching the edge cases. Get those right and a 60-line Flask app outperforms most commercial setups.

Top comments (0)