WhatsApp Flow
Handle & process flow templates
WhatsApp introduced flows, mobile-app-screen like message types.
This type makes collecting user information a breeze and greatly improves your chatbot UX
WCE has out-of-the box support for flows. An example flow template will be as below
"STAGE_NAME":
type: flow
message:
id: flow-id
name: flow-name
title: "My Flow Title"
body: "Flow message body"
button: flow-btn
routes:
"re:.*": "NEXT_STAGE"
WCE tries to keep template signature similar, a flow template can have a title
, body
and or footer
like any other interactive message template.
Draft Flows
During testing, you may have a draft flow. It's easy to include a draft flow in wce templates, simply add a draft
attr
"STAGE_NAME":
type: flow
message:
id: flow-id
draft: true # signal that flow is in draft mode
name: flow-name
title: "My Flow Title"
body: "Flow message body"
button: flow-btn
routes:
"re:.*": "NEXT_STAGE"
Dynamic properties - Passing initial data
You may have a flow that requires initial values (Dynamic Properties). Use cases for this can be if you have a flow that takes in initial dropdown items or just to populate a field with a default value.
The template "template"
hook can be used for this, instead of returning a render payload, it also takes in additional_data field that can be used for this.
pywce
template"STAGE-NAME":
type: flow
# jawce template
template: "zw.co.dcl.jchatbot.hooks.AuthHook:registerTemplate"
message:
id: 1234567890
draft: true
name: SCR_REGISTER
title: "New Account"
body: "Register with us to access our services"
button: Register
routes:
"re:.*": "STAGE-USER-LOOKUP"
You have to define a template as below
// zw.co.dcl.jchatbot.hooks.AuthHook.java
public class AuthHook extends AbstractHook {
public AuthHook(HookArgs args) {
super(args, SessionLocator.getSessionManager());
}
/*
Take current user mobile number and set it as default msisdn
*/
public Object registerTemplate() {
// match keys as set in your flow
Map<String, Object> flowDynamicProps = Map.of(
"msisdn", this.args.getChannelUser().waId()
);
// note that render-payload is set to null
args.setTemplateDynamicBody(new TemplateDynamicBody(
WebhookResponseMessageType.INTERACTIVE,
flowDynamicProps,
null
));
return args;
}
}
Flow Response
When user fills your flow form, the engine returns this in the additional data
property of the hook model
A (python) hook model is as below.
You will learn more on Hooks in the next section
@dataclass
class HookArg:
user: WaUser
params: Dict[str, Any] = field(default_factory=dict)
template_body: TemplateDynamicBody = None
from_trigger: bool = False
user_input: str = None
flow: str = None
additional_data: Dict[str, Any] = None # <=== Will contain flow response data
session_manager: ISessionManager = None
Example on-receive
hook to process flow response (assume a template has a hook defined below)
# ecommerce.hooks.auth_service.py
from pywce import HookArg
def login(arg: HookArg) -> HookArg:
"""
Process flow response data -
Take user msisdn field and pin field and attempt login
"""
print(f"Received hook arg: {arg}")
flow_auth_data = arg.additional_data
# TODO: attempt auth business logic
result = LoginService.login(
username=flow_auth_data.get('msisdn'),
password=flow_auth_data.get('pin')
)
return arg