Skip to content

[Feature Request]: Support raw content payload for WhatsApp Interactive Messages in messages.create #1147

@rajeev-oravco

Description

@rajeev-oravco

Preflight Checklist

  • I have read the Contributing Guidelines for this project.
  • I agree to follow the Code of Conduct that this project adheres to.
  • I have searched the issue tracker for a feature request that matches the one I want to file, without success.
  • This is not a general Twilio feature request or bug report. It is a feature request for the twilio-node JavaScript package.

Problem Description

Currently, the Twilio Node.js library (and the underlying Programmable Messaging API) restricts WhatsApp Interactive Messages (Buttons, Lists) to the Content API workflow. To send a simple session message with dynamic buttons, developers are forced to:

  1. Create a Content Resource via API (adding latency).
  2. Get the sid.
  3. Pass the contentSid to messages.create.

Attempting to pass a raw JSON payload (similar to the native WhatsApp Cloud API) results in a TypeScript error and is not supported by the library.

Problem
I am trying to send dynamic "Quick Reply" buttons to a user within a 24-hour session. I do not want to use templates because the button text changes dynamically per user context.

When attempting to pass a content object directly:

// ...
const result = await this.client.messages.create({
  from: `whatsapp:${this.config.fromNumber}`,
  to: `whatsapp:${message.to}`,
  // Feature Request: Allow passing this object directly
  content: [{
    type: 'interactive',
    interactive: {
      type: 'button',
      body: { text: message.body },
      action: { buttons: message.buttons }
    }
  }]
});

Actual Behavior
The TypeScript compiler throws the following error:

Object literal may only specify known properties, and 'content' does not exist in type 'MessageListInstanceCreateOptions'.ts(2353)

Expected Behavior
The MessageListInstanceCreateOptions interface and the underlying implementation should allow a content (or payload) property that accepts a JSON object. This object should be passed through to the WhatsApp provider, allowing developers to send dynamic interactive messages without the overhead of creating and managing ephemeral Content Resources for every single message.

Why this is important

  1. Performance: Creating a Content Resource requires an extra HTTP round-trip, adding latency to chat bots.
  2. Complexity: Developers have to manage/clean up thousands of temporary Content Resources created for one-off dynamic interactions.
  3. Parity: The native Meta/WhatsApp Cloud API supports sending raw JSON for interactive messages.

Proposed Solution

I propose extending the MessageListInstanceCreateOptions interface and the underlying messages.create method to accept a raw content or interactive_data property.

This property should accept a JSON object that mirrors the native WhatsApp Business API interactive payload structure. When this property is present, the SDK should pass it directly to the messaging provider without requiring a pre-existing contentSid.

Example Interface Update:

// Proposed addition to MessageListInstanceCreateOptions
export interface MessageListInstanceCreateOptions {
    // ... existing properties (body, from, to, contentSid) ...
    
    /**
     * specific JSON payload for WhatsApp Interactive messages 
     * to bypass Content Resource creation for dynamic session messages.
     */
    interactiveData?: Record<string, any>; 
}

Usage:

await client.messages.create({
  from: 'whatsapp:+1234567890',
  to: 'whatsapp:+0987654321',
  interactiveData: {
    type: "button",
    body: { text: "Do you accept?" },
    action: {
      buttons: [
        { type: "reply", reply: { id: "yes", title: "Yes" } },
        { type: "reply", reply: { id: "no", title: "No" } }
      ]
    }
  }
});

Alternatives Considered

1. Programmatic Content Resource Creation (Current Workaround)
Currently, to achieve dynamic buttons, we must chain two API calls:

  1. Call client.content.v1.contents.create(...) to generate a temporary template with the specific dynamic text/buttons needed for that specific user.
  2. Await the SID.
  3. Call client.messages.create({ contentSid: ... }).
  • Drawbacks:
    • Latency: Doubles the network overhead for every message, which is critical for real-time chat bots.
    • Rate Limits: Increases the risk of hitting API rate limits on the creation endpoint.
    • Resource Pollution: Creates thousands of "ephemeral" Content Resources that are only used once, cluttering the Twilio console and requiring a separate cleanup process.

2. Generic/Reusable Content Templates
We considered creating generic templates (e.g., a template with 3 buttons labeled {{1}}, {{2}}, {{3}}).

  • Drawbacks:
    • Inflexibility: Requires managing different templates for 1-button, 2-button, and 3-button scenarios.
    • Limited Context: Does not allow for dynamic button ID assignment (payloads), which is often necessary for tracking state in complex bot flows.

3. Text Fallback
Sending a standard text message with a numbered list (1. Option A, 2. Option B).

  • Drawbacks:
    • Poor UX: Significantly degrades the user experience compared to native UI elements.
    • Parsing Complexity: Requires natural language processing or strict integer parsing on the response, rather than relying on deterministic button payloads.

Additional Information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions