Skip to content

Commit aaa5407

Browse files
authored
Merge pull request #260 from Secreto31126/interactive-flow
Interactive flow
2 parents 71bfb4d + 7c7de95 commit aaa5407

File tree

4 files changed

+232
-1
lines changed

4 files changed

+232
-1
lines changed

EXAMPLES/README.md

+8
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ the most basic methods or features.
3131
- [Single Product](interactive.md#single-product)
3232
- [Multi Product](interactive.md#multi-product)
3333
- [Catalog](interactive.md#catalog)
34+
- [Click To Action](interactive.md#click-to-action)
35+
- [Navigate Flow](interactive.md#navigate-flow)
36+
- [Data Exchange Flow](interactive.md#data-exchange-flow)
3437
- [Payments and Location request](interactive.md#payments-and-location-request)
3538
- [Contacts](contacts.md)
3639
- [Simple contact](contacts.md#simple-contact)
@@ -42,6 +45,11 @@ the most basic methods or features.
4245
- [Simple template with header media](template.md#simple-template-with-header-media)
4346
- [Complex template with reply buttons](template.md#complex-template-with-reply-buttons)
4447
- [Complex template with call to action url](template.md#complex-template-with-call-to-action-url)
48+
- [Complex template with copy coupon button](template.md#complex-template-with-copy-coupon-button)
49+
- [Complex template with flow component](template.md#complex-template-with-flow-component)
50+
- [Complex template with combination of buttons](template.md#complex-template-with-combination-of-buttons)
51+
- [Complex template with catalog](template.md#complex-template-with-catalog)
52+
- [Complex template with Multi-Product Message](template.md#complex-template-with-multi-product-message)
4553
- [Complex template with Carousel](template.md#complex-template-with-carousel)
4654
- [Complex template with Limited-Time Offer](template.md#complex-template-with-limited-time-offer)
4755
- [OTP prefab template](template.md#otp-prefab-template)

EXAMPLES/interactive.md

+45
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,49 @@ const interactive_catalog_message = new Interactive(
9898
);
9999
```
100100

101+
## Navigate Flow
102+
103+
```ts
104+
import {
105+
Interactive,
106+
ActionNavigateFlow,
107+
Body
108+
} from "whatsapp-api-js/messages";
109+
110+
const interactive_navigate_flow_message = new Interactive(
111+
new ActionNavigateFlow(
112+
"5f9b3b4f-2b7a-4f4f-8f4f-4f4f4f4f4f4f",
113+
"5f9b3b4f-2b7a-4f4f-8f4f-4f4f4f4f4f4f",
114+
"Hello World",
115+
"form_screen",
116+
{
117+
name: "John Doe",
118+
age: 42
119+
}
120+
),
121+
new Body("How was your experience today?")
122+
);
123+
```
124+
125+
## Data Exchange Flow
126+
127+
```ts
128+
import {
129+
Interactive,
130+
ActionDataExchangeFlow,
131+
Body
132+
} from "whatsapp-api-js/messages";
133+
134+
const interactive_data_exchange_flow_message = new Interactive(
135+
new ActionDataExchangeFlow(
136+
"5f9b3b4f-2b7a-4f4f-8f4f-4f4f4f4f4f4f",
137+
"5f9b3b4f-2b7a-4f4f-8f4f-4f4f4f4f4f4f",
138+
"Hello World"
139+
),
140+
new Body("Hello World")
141+
);
142+
```
143+
101144
## Payments and Location request
102145

103146
Check out [#154](https://github.com/Secreto31126/whatsapp-api-js/issues/154) for more information.
@@ -110,3 +153,5 @@ https://whatsappapijs.web.app/classes/messages.ActionList.html
110153
https://whatsappapijs.web.app/classes/messages.ActionProduct.html
111154
https://whatsappapijs.web.app/classes/messages.ActionCatalog.html
112155
https://whatsappapijs.web.app/classes/messages.ActionCTA.html
156+
https://whatsappapijs.web.app/classes/messages.ActionNavigateFlow.html
157+
https://whatsappapijs.web.app/classes/messages.ActionDataExchangeFlow.html

src/messages/interactive.ts

+177
Original file line numberDiff line numberDiff line change
@@ -561,3 +561,180 @@ export class ActionCTA implements InteractiveAction {
561561
};
562562
}
563563
}
564+
565+
/**
566+
* Action API object
567+
*
568+
* @group Interactive
569+
*/
570+
export abstract class ActionFlow implements InteractiveAction {
571+
/**
572+
* The name of the component
573+
*/
574+
readonly name = "flow";
575+
/**
576+
* The Flow parameters
577+
*
578+
* @remarks TSDoc is unable to document this type properly, so most of
579+
* the documentation is in the subclasses constructors instead.
580+
*/
581+
readonly parameters: {
582+
/**
583+
* The Flow can be in either draft or published mode
584+
*/
585+
mode: "published" | "draft";
586+
/**
587+
* The Flow version, must be 3
588+
*/
589+
flow_message_version: "3";
590+
/**
591+
* Flow token that is generated by the business to serve as an identifier
592+
*/
593+
flow_token: string;
594+
/**
595+
* Unique ID of the Flow provided by WhatsApp
596+
*/
597+
flow_id: string;
598+
/**
599+
* Text on the CTA button, character limit - 20 characters (no emoji)
600+
*/
601+
flow_cta: string;
602+
/**
603+
* The Flow type, if set to "navigate", flow_action_payload must be provided
604+
*/
605+
flow_action: "navigate" | "data_exchange";
606+
/**
607+
* Required if flow_action is "navigate", should be omitted otherwise
608+
*/
609+
flow_action_payload?: {
610+
/**
611+
* The ID of the first Screen
612+
*/
613+
screen: string;
614+
/**
615+
* Optional input data for the first Screen of the Flow. If provided, this must be a non-empty object.
616+
*/
617+
data?: unknown;
618+
};
619+
} & (
620+
| {
621+
flow_action: "navigate";
622+
flow_action_payload: {
623+
screen: string;
624+
data?: unknown;
625+
};
626+
}
627+
| {
628+
flow_action: "data_exchange";
629+
flow_action_payload?: never;
630+
}
631+
);
632+
633+
/**
634+
* @override
635+
* @internal
636+
*/
637+
get _type(): "flow" {
638+
return "flow";
639+
}
640+
641+
/**
642+
* Builds a flow component for an Interactive message
643+
*
644+
* @param parameters - The Flow parameters
645+
* @throws If parameters.flow_cta is empty or over 20 characters
646+
* @throws If parameters.flow_cta contains emojis
647+
*/
648+
constructor(parameters: ActionFlow["parameters"]) {
649+
if (!parameters.flow_cta.length || parameters.flow_cta.length > 20) {
650+
throw new Error("Flow CTA must be between 1 and 20 characters");
651+
}
652+
653+
if (/\p{Extended_Pictographic}/u.test(parameters.flow_cta)) {
654+
throw new Error("Flow CTA must not contain emoji");
655+
}
656+
657+
this.parameters = parameters;
658+
}
659+
}
660+
661+
/**
662+
* Action API object
663+
*
664+
* @group Interactive
665+
*/
666+
export class ActionNavigateFlow extends ActionFlow {
667+
/**
668+
* Builds a navigate flow component for an Interactive message
669+
*
670+
* @param flow_token - Flow token that is generated by the business to serve as an identifier
671+
* @param flow_id - ID of the Flow provided by WhatsApp
672+
* @param flow_cta - Text on the CTA button, character limit - 20 characters (no emoji)
673+
* @param screen - The ID of the first Screen
674+
* @param data - Optional input data for the first Screen of the Flow. If provided, this must be a non-empty object.
675+
* @param mode - The Flow can be in either "draft" or "published" mode
676+
* @param flow_message_version - The Flow version, must be "3"
677+
* @throws If flow_cta is empty or over 20 characters
678+
* @throws If flow_cta contains emojis
679+
* @throws If data is provided and is an empty object
680+
*/
681+
constructor(
682+
flow_token: string,
683+
flow_id: string,
684+
flow_cta: string,
685+
screen: string,
686+
data?: unknown,
687+
mode: "published" | "draft" = "published",
688+
flow_message_version: "3" = "3"
689+
) {
690+
super({
691+
mode,
692+
flow_message_version,
693+
flow_token,
694+
flow_id,
695+
flow_cta,
696+
flow_action: "navigate",
697+
flow_action_payload: {
698+
screen,
699+
data
700+
}
701+
});
702+
703+
if (data && !Object.keys(data)) {
704+
throw new Error("Flow data must be a non-empty object if provided");
705+
}
706+
}
707+
}
708+
709+
/**
710+
* Action API object
711+
*
712+
* @group Interactive
713+
*/
714+
export class ActionDataExchangeFlow extends ActionFlow {
715+
/**
716+
* Builds a data exchange flow component for an Interactive message
717+
*
718+
* @param flow_token - Flow token that is generated by the business to serve as an identifier
719+
* @param flow_id - ID of the Flow provided by WhatsApp
720+
* @param flow_cta - Text on the CTA button, character limit - 20 characters (no emoji)
721+
* @param mode - Must be "published" or "draft"
722+
* @param flow_message_version - Must be "3"
723+
*/
724+
constructor(
725+
flow_token: string,
726+
flow_id: string,
727+
flow_cta: string,
728+
mode: "published" | "draft" = "published",
729+
flow_message_version: "3" = "3"
730+
) {
731+
super({
732+
mode,
733+
flow_message_version,
734+
flow_token,
735+
flow_id,
736+
flow_cta,
737+
flow_action: "data_exchange"
738+
});
739+
}
740+
}

src/types.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,8 @@ export interface InteractiveAction extends ClientTypedMessageComponent {
297297
| "catalog_message"
298298
| "product"
299299
| "product_list"
300-
| "cta_url";
300+
| "cta_url"
301+
| "flow";
301302
}
302303

303304
export type ClientMessageNames =

0 commit comments

Comments
 (0)