pythonwhatsappwhatsapiwhatsapp-flows

Not receiving INIT action from WhatsApp Flows after sending an interactive flow or template?


Can someone please advise how to get the INIT action?

I expect the INIT action to be triggered automatically when the user taps the 'Fill form' button to open the form from the message sent to them.

I experimented with sending initial messages using various marketing and utility templates, each featuring different structures. I also tried the approach I discovered here, where the action "INIT" is included in the payload of the template message. Additionally, I attempted using an interactive type as suggested by ChatGPT. However, I am not receiving the "INIT" action.

In the logs, I consistently see a 'ping' action, and then a subsequent log entry appears when I submit my data_exchange for MYFIRSTSCREEN. But the user_id can only be retrieved from the INIT action so I am unable to proceed with my flow.

When testing the flow with the builder, I notice that the INIT action is sent with a response code of 200, and I can see it in the logs in that case.

Please let me know what I might be doing wrong or how I can obtain the user_id (to_number) while working with the flow. The decrypted body contains only the data that I submitted during the data_exchange using the Flow JSON.

message = {
        "messaging_product": "whatsapp",
        "recipient_type": "individual",
        "to": user_id,
        "type": "interactive",
        "interactive": {
            "type": "flow",
            "header": {
                "type": "text",
                "text": "Welcome"
            },
            "body": {
                "text": "Click fill form"
            },
            "action": {
                "name": "flow",
                "parameters": {
                    "flow_message_version": "3",
                    "flow_cta": "Fill form",
                    "flow_name": "my_main_form_name"
                }
            }
        }
    }
message = {
        "messaging_product": "whatsapp",
        "to": user_id,
        "type": "template",
        "template": {
            "name": "main_flow_en",
            "language": {"code": "en"},
            "components": [
                {
                    "type": "body",
                    "parameters": [
                        {
                            "type": "text",
                            "parameter_name": "profile_name",
                            "text": profile_name
                        }
                    ]
                },
                {
                    "type": "button",
                    "sub_type": "flow",
                    "index": "0",
                    "parameters": [
                        {
                            "type": "payload",
                            "payload": json.dumps({
                                "action": "INIT",
                                "data": {
                                    "to_number": str(user_id)
                                }
                            })
                        }
                    ]
                }
            ]
        }
    }

And tried these parameters:

{
                    "type": "button",
                    "sub_type": "flow",
                    "index": "0",
                    "parameters": [
                        {
                            "type": "action",
                            "action": {
                                "flow_action_data": {
                                    "user_id": user_id,
                                    "user_name": profile_name
                                }
                            }
                        }
                    ]
                }

Flow endpoint code:

def handle_form_submission(event, context):
    body = json.loads(event.get('body', '{}'))
    decrypted  = decrypt_flow_data(body)
    logger.info("✅ Decrypted body: %s", decrypted)

    user_id = decrypted.get('to_number')
    action = decrypted.get('action')
    screen = decrypted.get('screen')
    data = decrypted.get('data') or {}
    flow_token = decrypted.get('flow_token')

    if action == 'INIT':
        logger.info("🚀 INIT state")
        profile = get_user_profile(user_id)
        store_user_data(user_id, {
            'SK': 'META',
            'flow_token': flow_token,
            'profile_name': profile,
            'started_at': iso_now()
        })
        response = {'version': '3.0', 'screen': 'MYFIRSTSCREEN',
                    'data': {'greeting': 'Welcome'}}
    elif action == "ping":
        response = {"version": "3.0", "data": {"status": "active"}}
    elif action == 'data_exchange' and screen == 'MYFIRSTSCREEN':
        ....

Solution

  • Here you go. What you should do to initialize the process is to set flow action as data exchange. Try this approach and let me know if it works for you.

    "action": {
          "name": "flow",
          "parameters": {
            "flow_id": "<YOUR_FLOW_ID>", #(You can retrieve it once the flow is published)
            "flow_cta": "Fill form",
            "flow_token": "unique-flow-token-123", #(Each interaction should have a unique token)
            "flow_message_version": "3",
            "flow_action": "data_exchange" #(This is where you INIT the process)
          }
        }