Guide

InstantDM Flow Editor - Complete Technical Documentation

The Flow Editor is a visual automation builder powered by React Flow that allows users to create Instagram/Facebook DM automation workflows. It uses a node-based architecture where different node

Meta Business Partner
30,000+ creators
$9.99/mo flat

Overview

The Flow Editor is a visual automation builder powered by React Flow that allows users to create Instagram/Facebook DM automation workflows. It uses a node-based architecture where different node types handle specific automation tasks.


Architecture

Technology Stack

  • React Flow: Visual node-based editor (@xyflow/react)
  • Firebase Firestore: Draft storage (automations/{userId}/draft_automations/{automationId})
  • REST API: Production publishing (/flow_editor)
  • Ant Design: UI components
  • react-beautiful-dnd: Drag-and-drop within nodes

Key Files

File Purpose
src/pages/flow-automte/main.js Main flow editor component
src/pages/flow-automte/comps/trigger/main.js Trigger configuration node
src/pages/flow-automte/comps/message_reply/main.js Message reply node
src/pages/flow-automte/comps/question_node/main.js Lead capture questions
src/pages/flow-automte/comps/followers_only/main.js Followers-only gate
src/pages/automationList/templates.json Pre-built automation templates

Complete Flow Payload Structure

Top-Level State Object

{
  "name": "My Automation Flow",
  "description": "Flow description",
  "live": false,
  "unsaved_changes": true,
  "published_on": "2025-01-26T12:00:00Z",
  "gsheet_id": "google_sheet_id",
  "gsheetName": "My Leads Sheet",
  "nodes": [],
  "edges": []
}

Node Types

1. TriggerComp (triggerComp)

Purpose: Entry point for automation - defines when the automation triggers

{
  "id": "node-1",
  "type": "triggerComp",
  "position": { "x": 40, "y": 40 },
  "data": {
    "auto_reply": {
      "dm_reply": {
        "enabled": true,
        "automate_all": "false",
        "triger_words": ["info", "details", "price"],
        "one_time_only": true
      },
      "story_reply": {
        "enabled": true,
        "automate_all": "false",
        "triger_words": ["interested"],
        "all_stories": "true",
        "selected_posts": ["post_id_1", "post_id_2"]
      },
      "comment_reply": {
        "enabled": true,
        "automate_all": "false",
        "triger_words": ["link", "interested"],
        "all_posts": "true",
        "selected_posts": ["post_id_1"],
        "comment_response": ["Thanks for commenting!"]
      },
      "welcome_message": {
        "title": "Welcome Title",
        "description": "Welcome description",
        "button": "Continue"
      }
    }
  }
}

Trigger Types:

Type Purpose Options
dm_reply DM keyword triggers automate_all, one_time_only
story_reply Story reply triggers all_stories, selected_posts
comment_reply Comment triggers all_posts, selected_posts, comment_response

2. MessageReply (messageReply)

Purpose: Send automated DM responses

{
  "id": "node-2",
  "type": "messageReply",
  "position": { "x": 500, "y": 40 },
  "data": {
    "toogleDrawer": false,
    "messages": []
  }
}

Message Types:

Text Message:

{
  "id": "msg-uuid",
  "type": "text",
  "text": "Hello! Thanks for reaching out 👋",
  "smartReplies": ["Tell me more", "Get Started", "No thanks"],
  "follow_up_duration": 30,
  "follow_up_duration_type": "m"
}

Button Template Message:

{
  "id": "msg-uuid",
  "type": "button",
  "templates": [
    {
      "id": "template-uuid",
      "title": "Choose an Option",
      "description": "What would you like to know?",
      "thumb_url": "https://..../image.jpg",
      "buttons": [
        { "title": "Pricing", "type": "postback" },
        { "title": "Visit Website", "type": "web_url", "url": "https://..." }
      ]
    }
  ],
  "follow_up_duration": 60,
  "follow_up_duration_type": "m"
}

Image Message:

{
  "id": "msg-uuid",
  "type": "image",
  "image_url": "https://public-assets.instantdm.com/..."
}

Audio Message:

{
  "id": "msg-uuid",
  "type": "audio",
  "audio_url": "https://public-assets.instantdm.com/..."
}

Delay Message:

{
  "id": "msg-uuid",
  "type": "delay",
  "delayDuration": 30,
  "durationType": "s"
}

3. QuestionNode (questionNode)

Purpose: Capture lead information with validation

{
  "id": "node-3",
  "type": "questionNode",
  "position": { "x": 800, "y": 40 },
  "data": {
    "messages": []
  }
}

Question Types:

Type Purpose Validation
name Full name Valid name format
email Email address Valid email format
phone Phone number Valid phone format
address Full address Street + postal code
text Free text input No validation
number Numeric input Integer validation
date Date input Date format validation
bool Yes/No choice Choice selection
rating Star rating (1-5) Rating selection

Question Message Structure:

{
  "id": "q-uuid",
  "question_type": "email",
  "question": "What's your email address?",
  "smartReplies": [],
  "skip_option": {
    "enable": true,
    "skip_text": "Skip this question"
  },
  "retry_attempt": {
    "count": 3
  },
  "wrong_input": {
    "message": "Please enter a valid email (e.g., name@example.com)"
  },
  "custom_variable_name": "user_email",
  "follow_up_duration": 30,
  "follow_up_duration_type": "m"
}

Bool/Rating with Choices:

{
  "id": "q-uuid",
  "question_type": "rating",
  "question": "How would you rate our service?",
  "smartReplies": ["⭐⭐⭐⭐⭐", "⭐⭐⭐⭐", "⭐⭐⭐", "⭐⭐", "⭐"]
}

4. FollowersOnly (followersOnly)

Purpose: Gate content for followers only

{
  "id": "node-4",
  "type": "followersOnly",
  "position": { "x": 300, "y": 200 },
  "data": {
    "followers_only": true,
    "message_reply": "true",
    "message": {
      "title": "Follow for Exclusive Content",
      "description": "Looks like you haven't followed me yet!",
      "button": "I started following you"
    }
  }
}

5. Notes (notes)

Purpose: Internal notes (not sent to users)

{
  "id": "node-5",
  "type": "notes",
  "position": { "x": 100, "y": 300 },
  "data": {
    "notes": "Internal note: Follow up with this user after 24 hours"
  }
}

Edge Structure

Edges define connections between nodes.

{
  "id": "e-1-3",
  "source": "node-1",
  "target": "node-3",
  "sourceHandle": "node-1-right",
  "targetHandle": "node-3-top",
  "type": "custom-edge",
  "markerEnd": {
    "type": "arrowclosed"
  },
  "data": {}
}

Handle Types:

  • Source handles (output): {nodeId}, {messageId}-{buttonIndex}, {messageId}-followup
  • Target handles (input): {nodeId}-top

Smart Reply Connection:

{
  "source": "node-2",
  "sourceHandle": "msg-uuid-0",
  "target": "node-3"
}

Button Template Connection:

{
  "source": "node-2",
  "sourceHandle": "template-uuid-0",
  "target": "node-3"
}

Follow-up Connection:

{
  "source": "node-2",
  "sourceHandle": "msg-uuid-followup",
  "target": "node-4"
}

API Endpoints

1. Get Flow Data

GET /flow_editor?flow_id={automation_id}

2. Publish Flow (Set Live)

POST /flow_editor?flow_id={automation_id}
Body: { ...complete_flow_payload }

3. Delete Flow

DELETE /flow_editor?flow_id={automation_id}

4. Get Flow Responses

GET /flow_editor_response?flow_id={flow_id}

Firebase Storage

Draft Automations: automations/{userId}/draft_automations/{automationId}

Auto-saves on every state change with debounced updates.


Complete Example Payload

{
  "name": "Lead Collection Flow",
  "live": true,
  "published_on": "2025-01-26T12:00:00Z",
  "nodes": [
    {
      "id": "trigger-1",
      "type": "triggerComp",
      "position": { "x": 50, "y": 50 },
      "data": {
        "auto_reply": {
          "comment_reply": {
            "enabled": true,
            "triger_words": ["interested"],
            "all_posts": "true"
          },
          "welcome_message": {
            "title": "Thanks!",
            "description": "Let me get your details",
            "button": "Continue"
          }
        }
      }
    },
    {
      "id": "welcome-1",
      "type": "messageReply",
      "position": { "x": 50, "y": 200 },
      "data": {
        "messages": [
          {
            "id": "msg-1",
            "type": "text",
            "text": "Thanks for your interest! 🎉"
          }
        ]
      }
    },
    {
      "id": "question-email",
      "type": "questionNode",
      "position": { "x": 50, "y": 350 },
      "data": {
        "messages": [
          {
            "id": "q-email",
            "question_type": "email",
            "question": "What's your email?",
            "retry_attempt": { "count": 3 },
            "wrong_input": { "message": "Please enter valid email" }
          }
        ]
      }
    }
  ],
  "edges": [
    {
      "id": "e1",
      "source": "trigger-1",
      "target": "welcome-1",
      "type": "custom-edge"
    },
    {
      "id": "e2",
      "source": "welcome-1",
      "target": "question-email",
      "type": "custom-edge"
    }
  ]
}

Quick DM Feature Design

Concept

A simplified "click and use" interface that generates the full flow payload in the background.

Proposed Approach

  1. Pre-select Trigger Type → Comment/DM/Story reply
  2. Quick Message Templates → Select from pre-built responses
  3. Lead Collection Fields → Toggle on/off: Name, Email, Phone
  4. Confirmation Message → Set closing message

The UI will auto-generate:

  • Trigger node with selected configuration
  • Message nodes for each response
  • Question nodes for selected lead fields
  • Proper edges connecting all nodes

Quick DM → Flow Mapping

Quick DM Field Flow Payload Location
Trigger Type nodes[0].data.auto_reply.{type}.enabled
Trigger Words nodes[0].data.auto_reply.{type}.triger_words
Welcome Message nodes[1].data.messages[0].text
Collect Name Add questionNode with question_type: "name"
Collect Email Add questionNode with question_type: "email"
Collect Phone Add questionNode with question_type: "phone"
Thank You Final messageReply node

Pre-built Templates

Available in src/pages/automationList/templates.json:

Template Description
lead-collection Name, email, phone collection
product-inquiry Product selection + order capture
feedback-collection Rating + feedback
appointment-booking Date/time scheduling
quiz-engagement Interactive quiz

Key TypeScript/Interface Definitions

interface FlowState {
  name: string;
  live: boolean;
  published_on?: string;
  gsheet_id?: string;
  nodes: FlowNode[];
  edges: FlowEdge[];
}

interface FlowNode {
  id: string;
  type: 'triggerComp' | 'messageReply' | 'questionNode' | 'followersOnly' | 'notes';
  position: { x: number; y: number };
  data: TriggerData | MessageData | QuestionData | FollowersOnlyData | NotesData;
}

interface FlowEdge {
  id: string;
  source: string;
  target: string;
  sourceHandle?: string;
  targetHandle?: string;
  type: 'custom-edge';
  markerEnd?: { type: 'arrowclosed' };
}

interface Message {
  id: string;
  type: 'text' | 'button' | 'image' | 'audio' | 'delay';
  text?: string;
  smartReplies?: string[];
  templates?: Template[];
  image_url?: string;
  audio_url?: string;
  delayDuration?: number;
  durationType?: 's' | 'm';
  follow_up_duration?: number;
  follow_up_duration_type?: 's' | 'm' | 'h';
}

interface Question extends Message {
  question_type: 'name' | 'email' | 'phone' | 'address' | 'text' | 'number' | 'date' | 'bool' | 'rating';
  question: string;
  skip_option?: { enable: boolean; skip_text: string };
  retry_attempt?: { count: number };
  wrong_input?: { message: string };
  custom_variable_name?: string;
}

Ready to Automate Your Instagram DMs?

Join 30,000+ creators and brands using InstantDM today.

Start Your Free Trial

No credit card required. Setup in under 15 minutes.