Flows Examples#
Tip
This page contains examples of flows for different versions of the WhatsApp Business API.
You can find the code in the tests/data/flows directory of the repository.
v7.1 Examples#
1from pywa.types.flows import * # noqa
2
3image_carousel = FlowJSON(
4 version="7.1",
5 screens=[
6 Screen(
7 id="DEMO_SCREEN",
8 terminal=True,
9 title="Demo screen",
10 layout=Layout(
11 type=LayoutType.SINGLE_COLUMN,
12 children=[
13 ImageCarousel(
14 scale_type=ScaleType.COVER,
15 images=[
16 ImageCarouselItem(
17 alt_text="Landscape image",
18 src="iVBORw0KGgoAAAANSUhEUgAAAB4AAAAKCAIAAAAsFXl4AAAANElEQVR4nGL5ctWagWjwuH0b8YqZiFdKKhg1Gg2wzOawIV61t1AF8YqHZoAMTaMBAQAA",
19 ),
20 ImageCarouselItem(
21 alt_text="Square image",
22 src="iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAIAAAACUFjqAAAALElEQVR4nGIRPRrBgATeWLsjc5kY8AKaSrPIL3FA5i9evZNudhOQBgQAAP",
23 ),
24 ImageCarouselItem(
25 alt_text="Portrait image",
26 src="iVBORw0KGgoAAAANSUhEUgAAAAoAAAAUCAIAAAA7jDsBAAAALUlEQVR4nGIJWfabAQls8DVA5jIx4AUjVZqRP2AJMn",
27 ),
28 ],
29 ),
30 Footer(
31 label="Continue",
32 on_click_action=CompleteAction(),
33 ),
34 ],
35 ),
36 ),
37 ],
38)
v6.3 Examples#
1from pywa.types.flows import * # noqa
2
3chips_selector = FlowJSON(
4 version="6.3",
5 screens=[
6 Screen(
7 id="DEMO_SCREEN",
8 terminal=True,
9 title="Demo screen",
10 layout=Layout(
11 type=LayoutType.SINGLE_COLUMN,
12 children=[
13 ChipsSelector(
14 name="chips",
15 label="Personalize your experience",
16 description="Choose your interests to get personalized design ideas and solution",
17 max_selected_items=2,
18 data_source=[
19 DataSource(id="room_layout", title="🏡 Room layouts"),
20 DataSource(id="lighting", title="💡 Lighting"),
21 DataSource(id="renovation", title="🛠️ Renovation"),
22 DataSource(id="furnitures", title="📐 Room layouts"),
23 ],
24 ),
25 Footer(
26 label="Continue",
27 on_click_action=CompleteAction(),
28 ),
29 ],
30 ),
31 ),
32 ],
33)
v6.2 Examples#
1import re
2
3from pywa.types.flows import * # noqa
4
5regex = FlowJSON(
6 version="6.2",
7 screens=[
8 Screen(
9 id="DEMO_SCREEN",
10 title="Demo Screen",
11 terminal=True,
12 layout=Layout(
13 type=LayoutType.SINGLE_COLUMN,
14 children=[
15 TextInput(
16 required=True,
17 label="Regex Input",
18 input_type=InputType.TEXT,
19 pattern=re.compile(
20 "^(19|20)\\d\\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$"
21 ),
22 helper_text="E.g. 1993-08-04",
23 name="regex input",
24 ),
25 TextInput(
26 required=True,
27 label="Regex Passcode",
28 pattern="007",
29 input_type=InputType.PASSCODE,
30 name="passcode_oo7",
31 helper_text="Contains: 007",
32 ),
33 Footer(
34 label="Continue",
35 on_click_action=CompleteAction(),
36 ),
37 ],
38 ),
39 )
40 ],
41)
42
43navigation_list = FlowJSON(
44 version="6.2",
45 routing_model={
46 "FIRST_SCREEN": ["SECOND_SCREEN", "THIRD_SCREEN", "FIFTH_SCREEN"],
47 "SECOND_SCREEN": ["CONTACT"],
48 "THIRD_SCREEN": ["CONTACT"],
49 "FIFTH_SCREEN": ["CONTACT"],
50 "CONTACT": [],
51 },
52 screens=[
53 Screen(
54 id="FIRST_SCREEN",
55 title="Our offers",
56 data={},
57 layout=Layout(
58 type=LayoutType.SINGLE_COLUMN,
59 children=[
60 NavigationList(
61 name="insurances",
62 list_items=[
63 NavigationItem(
64 id="home",
65 main_content=NavigationItemMainContent(
66 title="Home Insurance",
67 metadata="Safeguard your home against natural disasters, theft, and accidents",
68 ),
69 end=NavigationItemEnd(
70 title="$100", description="/ month"
71 ),
72 on_click_action=NavigateAction(
73 next=Next(name="SECOND_SCREEN"),
74 ),
75 ),
76 NavigationItem(
77 id="health",
78 main_content=NavigationItemMainContent(
79 title="Health Insurance",
80 metadata="Get essential coverage for doctor visits, prescriptions, and hospital stays",
81 ),
82 end=NavigationItemEnd(
83 title="$80", description="/ month"
84 ),
85 on_click_action=NavigateAction(
86 next=Next(name="SECOND_SCREEN"),
87 ),
88 ),
89 NavigationItem(
90 id="intergalactic",
91 main_content=NavigationItemMainContent(
92 title="Intergalactic Insurance",
93 metadata="Enjoy coverage for asteroid collisions, alien encounters, and other risks",
94 ),
95 end=NavigationItemEnd(
96 title="$1.000", description="/ month"
97 ),
98 on_click_action=NavigateAction(
99 next=Next(name="FOURTH_SCREEN"),
100 ),
101 ),
102 NavigationItem(
103 id="timetravel",
104 main_content=NavigationItemMainContent(
105 title="Time Travel Insurance",
106 metadata="Ready for paradox-related damages or unforeseen consequences of altering history",
107 ),
108 end=NavigationItemEnd(
109 title="$980", description="/ month"
110 ),
111 on_click_action=NavigateAction(
112 next=Next(name="FIFTH_SCREEN"),
113 ),
114 ),
115 NavigationItem(
116 id="dream",
117 main_content=NavigationItemMainContent(
118 title="Dream Loss Insurance",
119 metadata="Protection from recurring nightmares or lost opportunities due to poor sleep",
120 ),
121 end=NavigationItemEnd(
122 title="$540", description="/ month"
123 ),
124 on_click_action=NavigateAction(
125 next=Next(name="FIFTH_SCREEN"),
126 payload={"first_name": True},
127 ),
128 ),
129 ],
130 )
131 ],
132 ),
133 ),
134 Screen(
135 id="SECOND_SCREEN",
136 title="Home Insurance",
137 data={},
138 layout=Layout(
139 type=LayoutType.SINGLE_COLUMN,
140 children=[
141 TextSubheading(text="Tell us about your property"),
142 Form(
143 name="property_details_form",
144 children=[
145 Dropdown(
146 name="property_type",
147 required=True,
148 label="Property Type",
149 data_source=[
150 DataSource(id="House", title="House"),
151 DataSource(id="Apartment", title="Apartment"),
152 DataSource(id="Condo", title="Condo"),
153 ],
154 ),
155 TextInput(
156 name="surface",
157 label="Total surface (sqm)",
158 input_type=InputType.NUMBER,
159 required=True,
160 ),
161 TextInput(
162 name="rooms",
163 input_type=InputType.NUMBER,
164 label="Number or rooms",
165 required=True,
166 ),
167 TextInput(name="floors", label="Number of floors"),
168 Footer(
169 label="Continue",
170 on_click_action=NavigateAction(
171 next=Next(name="CONTACT"),
172 ),
173 ),
174 ],
175 ),
176 ],
177 ),
178 ),
179 Screen(
180 id="THIRD_SCREEN",
181 title="Health Insurance",
182 data={},
183 layout=Layout(
184 type=LayoutType.SINGLE_COLUMN,
185 children=[
186 TextSubheading(
187 text="Tell us about the type of insurance you are looking for"
188 ),
189 Form(
190 name="health_insurance_form",
191 children=[
192 Dropdown(
193 label="Insurance type",
194 name="insurance_type",
195 required=True,
196 data_source=[
197 DataSource(id="individual", title="Individual"),
198 DataSource(id="family", title="Family"),
199 ],
200 ),
201 TextInput(
202 label="Count",
203 required=True,
204 helper_text="How may people will be covered by this insurance",
205 name="number_of_people",
206 ),
207 Dropdown(
208 label="Age range",
209 name="age_range",
210 required=True,
211 data_source=[
212 DataSource(id="18-24", title="18-24"),
213 DataSource(id="25-34", title="25-34"),
214 ],
215 ),
216 Footer(
217 label="Next",
218 on_click_action=NavigateAction(
219 next=Next(name="CONTACT"),
220 ),
221 ),
222 ],
223 ),
224 ],
225 ),
226 ),
227 Screen(
228 id="FIFTH_SCREEN",
229 title="Time Travel Insurance",
230 data=[first_name := ScreenData(key="first_name", example="Bob")],
231 layout=Layout(
232 type=LayoutType.SINGLE_COLUMN,
233 children=[
234 TextBody(
235 text=f"`{first_name.ref} ', we are excited you are joining our community of time travellers!'`"
236 ),
237 TextBody(
238 text="We require a few more details to make sure you have the best cover possible for your needs."
239 ),
240 Form(
241 name="health_insurance_form",
242 children=[
243 Dropdown(
244 label="Insurance type",
245 name="insurance_type",
246 required=True,
247 data_source=[
248 DataSource(id="individual", title="Individual"),
249 DataSource(id="family", title="Family"),
250 ],
251 ),
252 TextInput(
253 label="Count",
254 required=True,
255 helper_text="How may people will be covered by this insurance",
256 name="number_of_people",
257 ),
258 Dropdown(
259 label="Age range",
260 name="age_range",
261 required=True,
262 data_source=[
263 DataSource(id="18-24", title="18-24"),
264 DataSource(id="25-34", title="25-34"),
265 ],
266 ),
267 Footer(
268 label="Next",
269 on_click_action=NavigateAction(
270 next=Next(name="CONTACT"),
271 ),
272 ),
273 ],
274 ),
275 ],
276 ),
277 ),
278 Screen(
279 id="CONTACT",
280 title="Contact details",
281 terminal=True,
282 data={},
283 layout=Layout(
284 type=LayoutType.SINGLE_COLUMN,
285 children=[
286 TextHeading(text="How can we get in contact with you?"),
287 Form(
288 name="form",
289 children=[
290 name := TextInput(
291 name="name",
292 label="Full name",
293 required=True,
294 ),
295 phone := TextInput(
296 name="phone",
297 required=True,
298 label="Phone number",
299 ),
300 Footer(
301 label="Complete",
302 on_click_action=CompleteAction(
303 payload={
304 "phone": phone.ref,
305 "name": name.ref,
306 },
307 ),
308 ),
309 ],
310 ),
311 ],
312 ),
313 ),
314 ],
315)
316
317
318navigation_list_dynamic = FlowJSON(
319 version="6.2",
320 data_api_version="3.0",
321 routing_model={
322 "FIRST_SCREEN": ["SECOND_SCREEN", "THIRD_SCREEN"],
323 "SECOND_SCREEN": ["CONTACT"],
324 "THIRD_SCREEN": ["CONTACT"],
325 "CONTACT": [],
326 },
327 screens=[
328 Screen(
329 id="FIRST_SCREEN",
330 title="Our offers",
331 data=[
332 insurances := ScreenData(
333 key="insurances",
334 example=[
335 NavigationItem(
336 id="home",
337 main_content=NavigationItemMainContent(
338 title="Home Insurance",
339 metadata="Safeguard your home against natural disasters, theft, and accidents.",
340 ),
341 on_click_action=DataExchangeAction(
342 payload={"selection": "home"},
343 ),
344 ),
345 NavigationItem(
346 id="health",
347 main_content=NavigationItemMainContent(
348 title="Health Insurance",
349 metadata="Get essential coverage for doctor visits, prescriptions, and hospital stays.",
350 ),
351 on_click_action=DataExchangeAction(
352 payload={"selection": "health"},
353 ),
354 ),
355 ],
356 ),
357 ],
358 layout=Layout(
359 type=LayoutType.SINGLE_COLUMN,
360 children=[
361 NavigationList(
362 name="insurances",
363 list_items=insurances.ref,
364 )
365 ],
366 ),
367 ),
368 Screen(
369 id="SECOND_SCREEN",
370 title="Home Insurance",
371 data={},
372 layout=Layout(
373 type=LayoutType.SINGLE_COLUMN,
374 children=[
375 TextSubheading(text="Tell us about your property"),
376 Form(
377 name="property_details_form",
378 children=[
379 Dropdown(
380 name="property_type",
381 required=True,
382 label="Property Type",
383 data_source=[
384 DataSource(id="House", title="House"),
385 DataSource(id="Apartment", title="Apartment"),
386 DataSource(id="Condo", title="Condo"),
387 ],
388 ),
389 TextInput(
390 name="surface",
391 label="Total surface (sqm)",
392 input_type=InputType.NUMBER,
393 required=True,
394 ),
395 TextInput(
396 name="rooms",
397 input_type=InputType.NUMBER,
398 label="Number or rooms",
399 required=True,
400 ),
401 TextInput(
402 name="floors",
403 label="Number of floors",
404 ),
405 Footer(
406 label="Continue",
407 on_click_action=NavigateAction(
408 next=Next(name="CONTACT"),
409 ),
410 ),
411 ],
412 ),
413 ],
414 ),
415 ),
416 Screen(
417 id="THIRD_SCREEN",
418 title="Health Insurance",
419 data={},
420 layout=Layout(
421 type=LayoutType.SINGLE_COLUMN,
422 children=[
423 TextSubheading(
424 text="Tell us about the type of insurance you are looking for"
425 ),
426 Form(
427 name="health_insurance_form",
428 children=[
429 Dropdown(
430 label="Insurance type",
431 name="insurance_type",
432 required=True,
433 data_source=[
434 DataSource(id="individual", title="Individual"),
435 DataSource(id="family", title="Family"),
436 ],
437 ),
438 TextInput(
439 label="Count",
440 required=True,
441 helper_text="How may people will be covered by this insurance",
442 name="number_of_people",
443 ),
444 Dropdown(
445 label="Age range",
446 name="age_range",
447 required=True,
448 data_source=[
449 DataSource(id="18-24", title="18-24"),
450 DataSource(id="25-34", title="25-34"),
451 ],
452 ),
453 Footer(
454 label="Next",
455 on_click_action=NavigateAction(
456 next=Next(name="CONTACT"),
457 ),
458 ),
459 ],
460 ),
461 ],
462 ),
463 ),
464 Screen(
465 id="CONTACT",
466 title="Contact details",
467 terminal=True,
468 data={},
469 layout=Layout(
470 type=LayoutType.SINGLE_COLUMN,
471 children=[
472 TextHeading(text="How can we get in contact with you?"),
473 Form(
474 name="form",
475 children=[
476 name := TextInput(
477 name="name",
478 label="Full name",
479 required=True,
480 ),
481 phone := TextInput(
482 name="phone",
483 required=True,
484 label="Phone number",
485 ),
486 Footer(
487 label="Complete",
488 on_click_action=CompleteAction(
489 payload={
490 "phone": phone.ref,
491 "name": name.ref,
492 }
493 ),
494 ),
495 ],
496 ),
497 ],
498 ),
499 ),
500 ],
501)
v6.1 Examples#
1from pywa.types.flows import * # noqa
2import datetime
3
4
5calendar_picker_single_mode = FlowJSON(
6 version="6.1",
7 data_api_version="3.0",
8 routing_model={},
9 screens=[
10 Screen(
11 id="DEMO_SCREEN",
12 terminal=True,
13 title="Demo screen",
14 layout=Layout(
15 type=LayoutType.SINGLE_COLUMN,
16 children=[
17 CalendarPicker(
18 name="calendar",
19 label="Single date",
20 helper_text="Select a date",
21 required=True,
22 mode=CalendarPickerMode.SINGLE,
23 min_date=datetime.date(2024, 10, 21),
24 max_date=datetime.date(2025, 12, 12),
25 unavailable_dates=[
26 datetime.date(2024, 11, 28),
27 datetime.date(2024, 11, 1),
28 ],
29 include_days=[
30 CalendarDay.MON,
31 CalendarDay.TUE,
32 CalendarDay.WED,
33 CalendarDay.THU,
34 CalendarDay.FRI,
35 ],
36 init_value=datetime.date(2024, 10, 23),
37 on_select_action=DataExchangeAction(
38 payload={"calendar": ComponentRef("calendar")},
39 ),
40 ),
41 Footer(
42 label="Continue",
43 on_click_action=DataExchangeAction(),
44 ),
45 ],
46 ),
47 )
48 ],
49)
50
51
52calendar_picker_range_mode = FlowJSON(
53 version="6.1",
54 data_api_version="3.0",
55 routing_model={},
56 screens=[
57 Screen(
58 id="DEMO_SCREEN",
59 terminal=True,
60 title="Demo screen",
61 layout=Layout(
62 type=LayoutType.SINGLE_COLUMN,
63 children=[
64 CalendarPicker(
65 name="calendar_range",
66 title="Range calendar",
67 description="Use this to select a date range",
68 label=CalendarRangeValues(
69 start_date="Start date",
70 end_date="End date",
71 ),
72 helper_text=CalendarRangeValues(
73 start_date="Select from date",
74 end_date="Select to date",
75 ),
76 required=CalendarRangeValues(
77 start_date=True,
78 end_date=False,
79 ),
80 mode=CalendarPickerMode.RANGE,
81 min_date=datetime.date(2024, 10, 21),
82 max_date=datetime.date(2025, 12, 12),
83 unavailable_dates=[
84 datetime.date(2024, 11, 28),
85 datetime.date(2024, 11, 1),
86 ],
87 include_days=[
88 CalendarDay.MON,
89 CalendarDay.TUE,
90 CalendarDay.WED,
91 CalendarDay.THU,
92 CalendarDay.FRI,
93 ],
94 min_days=3,
95 max_days=10,
96 init_value=CalendarRangeValues(
97 start_date=datetime.date(2024, 10, 22),
98 end_date=datetime.date(2024, 10, 25),
99 ),
100 on_select_action=DataExchangeAction(
101 payload={"calendar_range": ComponentRef("calendar_range")},
102 ),
103 ),
104 Footer(
105 label="Continue",
106 on_click_action=DataExchangeAction(),
107 ),
108 ],
109 ),
110 )
111 ],
112)
v6.0 Examples#
1from pywa.types.flows import * # noqa
2
3string_concatenation = FlowJSON(
4 version="6.0",
5 screens=[
6 Screen(
7 id="DEMO_SCREEN",
8 terminal=True,
9 title="Demo screen",
10 layout=Layout(
11 type=LayoutType.SINGLE_COLUMN,
12 children=[
13 first_name := TextInput(
14 label="First name",
15 input_type=InputType.TEXT,
16 name="first_name",
17 required=True,
18 ),
19 age := TextInput(
20 label="Age",
21 input_type=InputType.NUMBER,
22 name="age",
23 required=True,
24 ),
25 TextBody(text=FlowStr("Hello {name}", name=first_name.ref)),
26 TextBody(
27 text=FlowStr(
28 "{name} you are {age} years old.",
29 name=first_name.ref,
30 age=age.ref,
31 )
32 ),
33 Footer(
34 label="Footer",
35 on_click_action=CompleteAction(),
36 ),
37 ],
38 ),
39 )
40 ],
41)
42
43open_url = FlowJSON(
44 version="6.0",
45 screens=[
46 Screen(
47 id="DEMO_SCREEN",
48 terminal=True,
49 title="Demo screen",
50 layout=Layout(
51 type=LayoutType.SINGLE_COLUMN,
52 children=[
53 EmbeddedLink(
54 text="This is an external link.",
55 on_click_action=OpenURLAction(
56 url="https://pywa.readthedocs.io/",
57 ),
58 ),
59 OptIn(
60 label="I agree to the terms.",
61 name="T&Cs",
62 on_click_action=OpenURLAction(
63 url="https://pywa.readthedocs.io/",
64 ),
65 ),
66 Footer(
67 label="Footer",
68 on_click_action=CompleteAction(),
69 ),
70 ],
71 ),
72 )
73 ],
74)
75
76update_data = FlowJSON(
77 version="6.0",
78 screens=[
79 Screen(
80 id="ADDRESS_SELECTION",
81 title="Address selection",
82 terminal=True,
83 success=True,
84 data=[
85 state_visibility := ScreenData(
86 key="state_visibility",
87 example=False,
88 ),
89 pincode_visibility := ScreenData(
90 key="pincode_visibility",
91 example=False,
92 ),
93 states := ScreenData(
94 key="states",
95 example=[DataSource(id="1", title="USA")],
96 ),
97 pincode := ScreenData(
98 key="pincode",
99 example=[DataSource(id="M6B2A9", title="M6B2A9")],
100 ),
101 countries := ScreenData(
102 key="countries",
103 example=[
104 DataSource(
105 id="1",
106 title="USA",
107 on_select_action=UpdateDataAction(
108 payload=[
109 states.update(
110 new_value=[
111 DataSource(
112 id="new_york",
113 title="New York",
114 on_unselect_action=UpdateDataAction(
115 payload=[
116 pincode_visibility.update(
117 new_value=False
118 )
119 ],
120 ),
121 on_select_action=UpdateDataAction(
122 payload=[
123 pincode.update(
124 new_value=[
125 DataSource(
126 id="10001",
127 title="10001",
128 ),
129 DataSource(
130 id="10005",
131 title="10005",
132 ),
133 ]
134 ),
135 pincode_visibility.update(
136 new_value=True
137 ),
138 ],
139 ),
140 ),
141 DataSource(
142 id="california",
143 title="California",
144 on_unselect_action=UpdateDataAction(
145 payload=[
146 pincode_visibility.update(
147 new_value=False
148 )
149 ],
150 ),
151 on_select_action=UpdateDataAction(
152 payload=[
153 pincode.update(
154 new_value=[
155 DataSource(
156 id="90019",
157 title="90019",
158 ),
159 DataSource(
160 id="93504",
161 title="93504",
162 ),
163 ]
164 ),
165 pincode_visibility.update(
166 new_value=True
167 ),
168 ],
169 ),
170 ),
171 ]
172 ),
173 state_visibility.update(new_value=True),
174 ],
175 ),
176 on_unselect_action=UpdateDataAction(
177 payload=[
178 state_visibility.update(new_value=False),
179 pincode_visibility.update(new_value=False),
180 ],
181 ),
182 ),
183 DataSource(
184 id="2",
185 title="Canada",
186 on_select_action=UpdateDataAction(
187 payload=[
188 states.update(
189 new_value=[
190 DataSource(
191 id="ontario",
192 title="Ontario",
193 on_unselect_action=UpdateDataAction(
194 payload=[
195 pincode_visibility.update(
196 new_value=False
197 )
198 ],
199 ),
200 on_select_action=UpdateDataAction(
201 payload=[
202 pincode.update(
203 new_value=[
204 DataSource(
205 id="L4K",
206 title="L4K",
207 ),
208 DataSource(
209 id="M3C",
210 title="M3C",
211 ),
212 ]
213 ),
214 pincode_visibility.update(
215 new_value=True
216 ),
217 ],
218 ),
219 ),
220 DataSource(
221 id="quebec",
222 title="Quebec",
223 on_unselect_action=UpdateDataAction(
224 payload=[
225 pincode_visibility.update(
226 new_value=False
227 )
228 ],
229 ),
230 on_select_action=UpdateDataAction(
231 payload=[
232 pincode.update(
233 new_value=[
234 DataSource(
235 id="M6B2A9",
236 title="M6B2A9",
237 ),
238 DataSource(
239 id="M5V",
240 title="M5V",
241 ),
242 ]
243 ),
244 pincode_visibility.update(
245 new_value=True
246 ),
247 ],
248 ),
249 ),
250 ]
251 ),
252 state_visibility.update(new_value=True),
253 ],
254 ),
255 on_unselect_action=UpdateDataAction(
256 payload=[
257 state_visibility.update(new_value=False),
258 pincode_visibility.update(new_value=False),
259 ],
260 ),
261 ),
262 ],
263 ),
264 ],
265 layout=Layout(
266 type=LayoutType.SINGLE_COLUMN,
267 children=[
268 RadioButtonsGroup(
269 name="select_country",
270 label="Select country:",
271 data_source=countries.ref,
272 ),
273 RadioButtonsGroup(
274 name="select_states",
275 label="Select state:",
276 visible=state_visibility.ref,
277 data_source=states.ref,
278 ),
279 RadioButtonsGroup(
280 name="pincode",
281 label="Select pincode:",
282 visible=pincode_visibility.ref,
283 data_source=pincode.ref,
284 ),
285 Footer(
286 label="Complete",
287 on_click_action=CompleteAction(),
288 ),
289 ],
290 ),
291 )
292 ],
293)
294
295
296math_operators = FlowJSON(
297 version="6.0",
298 screens=[
299 Screen(
300 id="DEMO_SCREEN",
301 title="Demo Screen",
302 terminal=True,
303 success=True,
304 data=[
305 number_1 := ScreenData(
306 key="number_1",
307 example=10,
308 ),
309 number_2 := ScreenData(
310 key="number_2",
311 example=20,
312 ),
313 ],
314 layout=Layout(
315 type=LayoutType.SINGLE_COLUMN,
316 children=[
317 TextBody(
318 text=[
319 FlowStr(
320 "The sum of {num1} and {num2} is {sum}",
321 num1=number_1.ref,
322 num2=number_2.ref,
323 sum=number_1.ref + number_2.ref,
324 ),
325 FlowStr(
326 "The difference of {num1} and {num2} is {diff}",
327 num1=number_1.ref,
328 num2=number_2.ref,
329 diff=number_1.ref - number_2.ref,
330 ),
331 FlowStr(
332 "The product of {num1} and {num2} is {prod}",
333 num1=number_1.ref,
334 num2=number_2.ref,
335 prod=number_1.ref * number_2.ref,
336 ),
337 FlowStr(
338 "The division of {num1} by {num2} is {div}",
339 num1=number_1.ref,
340 num2=number_2.ref,
341 div=number_1.ref / number_2.ref,
342 ),
343 ]
344 ),
345 Footer(
346 label="Static footer label",
347 on_click_action=CompleteAction(),
348 ),
349 ],
350 ),
351 ),
352 ],
353)
354
355visible_condition = FlowJSON(
356 version="6.0",
357 screens=[
358 Screen(
359 id="DEMO_SCREEN",
360 title="Demo Screen",
361 terminal=True,
362 success=True,
363 layout=Layout(
364 type=LayoutType.SINGLE_COLUMN,
365 children=[
366 number := TextInput(
367 label="Enter a number",
368 input_type=InputType.NUMBER,
369 name="number",
370 ),
371 TextBody(
372 text="You choose the right number!",
373 visible=number.ref == 42,
374 ),
375 Footer(
376 label="Static footer label",
377 on_click_action=CompleteAction(),
378 ),
379 ],
380 ),
381 )
382 ],
383)
v5.1 Examples#
1from pywa.types.flows import * # noqa: F403
2
3rich_text = FlowJSON(
4 version="5.1",
5 screens=[
6 Screen(
7 id="FIRST_SCREEN",
8 title="Welcome",
9 terminal=True,
10 layout=Layout(
11 type=LayoutType.SINGLE_COLUMN,
12 children=[
13 TextCaption(
14 markdown=True,
15 text=[
16 "This is a markdown example inside **TextCaption**. You can combine **different** *formatting* ~~***styles***~~",
17 "You can also add [links](https://whatsapp.com) to external web-sites",
18 ],
19 ),
20 TextBody(
21 markdown=True,
22 text=[
23 "This is a markdown example inside **TextCaption**. You can combine **different** *formatting* ~~***styles***~~.",
24 "You can also add [links](https://whatsapp.com) to external web-sites",
25 "And use **Ordered** and **Unordered** lists:",
26 "1. List item",
27 "2. List item",
28 ],
29 ),
30 OptIn(
31 name="toc",
32 required=True,
33 label="RichText can be used to render large static or dynamic texts.",
34 on_click_action=NavigateAction(
35 next=Next(name="TOC"),
36 ),
37 ),
38 Footer(
39 label="Proceed",
40 on_click_action=CompleteAction(),
41 ),
42 ],
43 ),
44 ),
45 Screen(
46 id="TOC",
47 title="Terms of Service",
48 layout=Layout(
49 type=LayoutType.SINGLE_COLUMN,
50 children=[
51 RichText(
52 text=[
53 "This is a mock-up of ToC demonstrating the supported syntax of RichText components",
54 "# Terms of Service",
55 "## 1. Acceptance of Terms",
56 'By using our services, you *agree* to a these lol **Terms of Service** (*"Terms"*). If you do not *agree*, please do not use our services.',
57 "**Here is image example:**",
58 '""',
59 "We are not **liable** for:",
60 "1. *indirect* including the ones that happens all the time in normal life, I just need to make this text slightly longer",
61 "2. *incidental*,",
62 "3. *special*,",
63 "4. *punitive* damages",
64 "including loss of:",
65 "+ *profits*,",
66 "+ *data*",
67 "+ *use*.",
68 "## 2. Modifications to Terms",
69 'We *reserve* the right to **modify** these *Terms* at any time. Changes will be indicated by the **"Last Updated"** date. Continued use after changes constitutes acceptance.',
70 "## 3. Use of Services",
71 "**Eligibility:** You must be at least *18 years old*. By using our services, you *confirm* you meet this requirement.",
72 "**Account Responsibilities:** You are **responsible** for your account confidentiality and activities.",
73 "## 4. User Conduct",
74 "You *agree* not to **violate** laws, **infringe** rights, or transmit *objectionable* content.",
75 "## 5. Termination",
76 "We may **terminate** or *suspend* your access immediately, without notice, for any reason, including **breach** of *Terms*.",
77 "## 6. Disclaimer of Warranties",
78 'Services are provided ***"AS IS"*** and ***"AS AVAILABLE"***. We disclaim all **warranties**, express or implied, including *merchantability* and *fitness for a particular purpose*.',
79 "## 7. Limitation of Liability",
80 "We are not **liable** for:",
81 "1. *indirect* including the ones that happens all the time in normal life, I just need to make this text slightly longer",
82 "2. *incidental*,",
83 "3. *special*,",
84 "4. *punitive* damages",
85 "including loss of:",
86 "+ *profits*,",
87 "+ *data*",
88 "+ *use*.",
89 "## 8. Governing Law",
90 "| Column with extended width | Column with extended width | Column with extended width |",
91 "| -------- | -------- |",
92 "| It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. | Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.| Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum |",
93 "| It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. | Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.| Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum |",
94 "## 9. Contact Information",
95 "For questions, contact us at **[your email address]**.",
96 "Alternatively please go to our [Fancy web-site](https://www.whatsapp.com) to learn more about our services.",
97 "**Last Updated:** ***[Date]***",
98 ]
99 )
100 ],
101 ),
102 ),
103 ],
104)
v5.0 Examples#
1import datetime
2
3from pywa.types.flows import * # noqa: F403
4
5
6radio_buttons_with_pics = FlowJSON(
7 version="5.0",
8 screens=[
9 Screen(
10 id="TRAVEL_PACKAGES",
11 layout=Layout(
12 type=LayoutType.SINGLE_COLUMN,
13 children=[
14 RadioButtonsGroup(
15 name="packages",
16 required=True,
17 data_source=[
18 DataSource(
19 id="1",
20 title="Tropical Beach Vacation",
21 description="Enjoy 7 nights and 8 days at a luxury beach resort in Bali. Including flights and stays",
22 alt_text="beach vacation",
23 image="iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=",
24 ),
25 DataSource(
26 id="2",
27 title="Mountain Adventure",
28 description="Embark on a 5-day guided trek in the Swiss Alps. Package includes flights and stays",
29 image="iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=",
30 ),
31 DataSource(
32 id="3",
33 title="City Break",
34 description="Explore the sights and sounds of New York City with our 4 nights and 5 days package",
35 image="iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=",
36 ),
37 DataSource(
38 id="4",
39 title="Historical Tour",
40 description="Take a 7-day historical tour of Rome, Italy. Package includes flights and stays",
41 image="iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=",
42 ),
43 ],
44 label="Explore our exciting packages",
45 ),
46 Footer(
47 label="Continue",
48 on_click_action=CompleteAction(),
49 ),
50 ],
51 ),
52 title="Travel Packages",
53 terminal=True,
54 ),
55 ],
56)
57
58date_picker_dates_obj = FlowJSON(
59 version="5.0",
60 data_api_version="3.0",
61 routing_model={},
62 screens=[
63 Screen(
64 id="DEMO_SCREEN",
65 terminal=True,
66 title="Demo screen",
67 layout=Layout(
68 type=LayoutType.SINGLE_COLUMN,
69 children=[
70 date := DatePicker(
71 name="date",
72 label="Date",
73 min_date=datetime.date(2024, 10, 21),
74 max_date=datetime.date(2024, 11, 12),
75 unavailable_dates=[
76 datetime.date(2024, 10, 28),
77 datetime.date(2024, 11, 1),
78 ],
79 on_select_action=DataExchangeAction(
80 payload={"date": ComponentRef("date")},
81 ),
82 ),
83 Footer(
84 label="Continue",
85 on_click_action=DataExchangeAction(),
86 ),
87 ],
88 ),
89 )
90 ],
91)
v4.0 Examples#
1from pywa.types.flows import * # noqa: F403
2
3switch = FlowJSON(
4 version="4.0",
5 screens=[
6 Screen(
7 id="SCREEN",
8 title="Welcome",
9 terminal=True,
10 success=True,
11 data=[ScreenData(key="value", example="cat")],
12 layout=Layout(
13 children=[
14 animal := TextInput(
15 name="animal",
16 label="Animal",
17 helper_text="Type: cat, dog or anything else",
18 ),
19 Switch(
20 value=animal.ref,
21 cases={
22 "cat": [TextHeading(text="It is a cat")],
23 "dog": [TextHeading(text="It is a dog")],
24 "default": [
25 TextHeading(text="It is neither a cat nor a dog")
26 ],
27 },
28 ),
29 Footer(
30 label="Complete",
31 on_click_action=CompleteAction(),
32 ),
33 ]
34 ),
35 )
36 ],
37)
38
39if_ = FlowJSON(
40 version="4.0",
41 screens=[
42 Screen(
43 id="SCREEN",
44 title="Welcome",
45 terminal=True,
46 success=True,
47 data=[value := ScreenData(key="value", example=True)],
48 layout=Layout(
49 children=[
50 animal := TextInput(
51 name="animal",
52 label="Animal",
53 helper_text="Type: cat",
54 ),
55 If(
56 condition=value.ref & (animal.ref == "cat"),
57 then=[TextHeading(text="It is a cat")],
58 else_=[TextHeading(text="It is not a cat")],
59 ),
60 Footer(
61 label="Complete",
62 on_click_action=CompleteAction(),
63 ),
64 ]
65 ),
66 )
67 ],
68)
69
70photo_picker = FlowJSON(
71 version="4.0",
72 routing_model={"FIRST": []},
73 data_api_version="3.0",
74 screens=[
75 Screen(
76 id="FIRST",
77 title="Photo Picker Example",
78 terminal=True,
79 data={},
80 layout=Layout(
81 type=LayoutType.SINGLE_COLUMN,
82 children=[
83 Form(
84 name="flow_path",
85 children=[
86 photo_picker := PhotoPicker(
87 name="photo_picker",
88 label="Upload photos",
89 description="Please attach images about the received items",
90 photo_source="camera_gallery",
91 min_uploaded_photos=1,
92 max_uploaded_photos=10,
93 max_file_size_kb=10240,
94 ),
95 Footer(
96 label="Submit",
97 on_click_action=DataExchangeAction(
98 payload={"images": photo_picker.ref},
99 ),
100 ),
101 ],
102 )
103 ],
104 ),
105 )
106 ],
107)
108
109doc_picker = FlowJSON(
110 version="4.0",
111 routing_model={"SECOND": []},
112 data_api_version="3.0",
113 screens=[
114 Screen(
115 id="SECOND",
116 terminal=True,
117 title="Document Picker Example",
118 data={},
119 layout=Layout(
120 type=LayoutType.SINGLE_COLUMN,
121 children=[
122 Form(
123 name="flow_path",
124 children=[
125 document_picker := DocumentPicker(
126 name="document_picker",
127 label="Contract",
128 description="Attach the signed copy of the contract",
129 min_uploaded_documents=1,
130 max_uploaded_documents=1,
131 max_file_size_kb=1024,
132 allowed_mime_types=[
133 "image/jpeg",
134 "application/pdf",
135 ],
136 ),
137 Footer(
138 label="Submit",
139 on_click_action=CompleteAction(
140 payload={"documents": document_picker.ref},
141 ),
142 ),
143 ],
144 )
145 ],
146 ),
147 )
148 ],
149)
150
151
152date_picker_dates_str = FlowJSON(
153 version="4.0",
154 data_api_version="3.0",
155 routing_model={},
156 screens=[
157 Screen(
158 id="DEMO_SCREEN",
159 terminal=True,
160 title="Demo screen",
161 layout=Layout(
162 type=LayoutType.SINGLE_COLUMN,
163 children=[
164 Form(
165 name="form_name",
166 children=[
167 DatePicker(
168 name="date",
169 label="Date",
170 min_date="1693569600000",
171 max_date="1767182400000",
172 unavailable_dates=[
173 "1694779200000",
174 "1697371200000",
175 ],
176 on_select_action=DataExchangeAction(
177 payload={"date": ComponentRef("date")},
178 ),
179 ),
180 Footer(
181 label="Continue",
182 on_click_action=DataExchangeAction(),
183 ),
184 ],
185 )
186 ],
187 ),
188 )
189 ],
190)
191
192global_fields = FlowJSON(
193 version="4.0",
194 screens=[
195 screen_one := Screen(
196 data=[
197 field2 := ScreenData(key="field2", example="data"),
198 ],
199 id="SCREEN_ONE",
200 layout=Layout(
201 type=LayoutType.SINGLE_COLUMN,
202 children=[
203 field1 := TextInput(name="field1", label="Enter your name"),
204 Footer(
205 label="CTA",
206 on_click_action=NavigateAction(
207 next=Next(name="SCREEN_TWO"),
208 ),
209 ),
210 ],
211 ),
212 title="Screen 1",
213 ),
214 Screen(
215 id="SCREEN_TWO",
216 terminal=True,
217 layout=Layout(
218 type=LayoutType.SINGLE_COLUMN,
219 children=[
220 Footer(
221 label="Complete",
222 on_click_action=CompleteAction(
223 payload={
224 "field1": screen_one / field1.ref,
225 "field2": screen_one / field2.ref,
226 },
227 ),
228 ),
229 ],
230 ),
231 title="Screen 2",
232 data={},
233 ),
234 ],
235)
236
237
238forward_refs = FlowJSON(
239 version="4.0",
240 routing_model={"SELECT_SERVICES": ["SELECT_INSURANCE"]},
241 screens=[
242 select_insurance_screen := Screen(
243 id="SELECT_INSURANCE",
244 title="Select insurance",
245 layout=Layout(
246 type=LayoutType.SINGLE_COLUMN,
247 children=[
248 insurance := RadioButtonsGroup(
249 name="insurance",
250 label="Please select your coverage",
251 data_source=[
252 basic := DataSource(id="basic", title="Basic"),
253 standard := DataSource(id="standard", title="Standard"),
254 full := DataSource(id="full", title="Premium"),
255 ],
256 )
257 ],
258 ),
259 ),
260 Screen(
261 terminal=True,
262 id="SELECT_SERVICES",
263 title="Select services",
264 layout=Layout(
265 type=LayoutType.SINGLE_COLUMN,
266 children=[
267 TextSubheading(text="Select insurance type"),
268 If(
269 condition=select_insurance_screen / insurance.ref != "",
270 then=[
271 Switch(
272 value=select_insurance_screen / insurance.ref,
273 cases={
274 "basic": [
275 TextBody(
276 text="You've selected a basic insurance"
277 )
278 ],
279 "standard": [
280 TextBody(
281 text="You've selected a standard insurance"
282 )
283 ],
284 "full": [
285 TextBody(
286 text="You've selected a comprehensive insurance"
287 )
288 ],
289 },
290 )
291 ],
292 else_=[
293 TextBody(text="You haven't selected any insurance type")
294 ],
295 ),
296 EmbeddedLink(
297 text="Choose insurance type",
298 on_click_action=NavigateAction(
299 next=Next(type=NextType.SCREEN, name="SELECT_INSURANCE"),
300 ),
301 ),
302 Footer(
303 label="Complete",
304 on_click_action=CompleteAction(
305 payload={
306 "selected_insurance_type": select_insurance_screen
307 / insurance.ref
308 },
309 ),
310 ),
311 ],
312 ),
313 ),
314 ],
315)
v2.1 Examples#
1from pywa.types.flows import * # noqa: F403
2
3customer_satisfaction_survey = FlowJSON(
4 version="2.1",
5 screens=[
6 Screen(
7 id="RECOMMEND",
8 title="Feedback 1 of 2",
9 data={},
10 layout=Layout(
11 type=LayoutType.SINGLE_COLUMN,
12 children=[
13 Form(
14 name="form",
15 children=[
16 TextSubheading(text="Would you recommend us to a friend?"),
17 recommend_radio := RadioButtonsGroup(
18 name="recommend_radio",
19 label="Choose one",
20 data_source=[
21 DataSource(id="0", title="Yes"),
22 DataSource(id="1", title="No"),
23 ],
24 required=True,
25 ),
26 TextSubheading(text="How could we do better?"),
27 comment_text := TextArea(
28 name="comment_text",
29 label="Leave a comment",
30 required=False,
31 ),
32 Footer(
33 label="Continue",
34 on_click_action=NavigateAction(
35 next=Next(name="RATE"),
36 payload={
37 "recommend_radio": recommend_radio.ref,
38 "comment_text": comment_text.ref,
39 },
40 ),
41 ),
42 ],
43 )
44 ],
45 ),
46 ),
47 Screen(
48 id="RATE",
49 title="Feedback 2 of 2",
50 data=[
51 recommend_radio := ScreenData(key="recommend_radio", example="Example"),
52 comment_text := ScreenData(key="comment_text", example="Example"),
53 ],
54 terminal=True,
55 layout=Layout(
56 type=LayoutType.SINGLE_COLUMN,
57 children=[
58 Form(
59 name="form",
60 children=[
61 TextSubheading(text="Rate the following: "),
62 purchase_rating := Dropdown(
63 name="purchase_rating",
64 label="Purchase experience",
65 required=True,
66 data_source=[
67 DataSource(id="0", title="★★★★★ • Excellent (5/5)"),
68 DataSource(id="1", title="★★★★☆ • Good (4/5)"),
69 DataSource(id="2", title="★★★☆☆ • Average (3/5)"),
70 DataSource(id="3", title="★★☆☆☆ • Poor (2/5)"),
71 DataSource(id="4", title="★☆☆☆☆ • Very Poor (1/5)"),
72 ],
73 ),
74 delivery_rating := Dropdown(
75 name="delivery_rating",
76 label="Delivery and setup",
77 required=True,
78 data_source=[
79 DataSource(id="0", title="★★★★★ • Excellent (5/5)"),
80 DataSource(id="1", title="★★★★☆ • Good (4/5)"),
81 DataSource(id="2", title="★★★☆☆ • Average (3/5)"),
82 DataSource(id="3", title="★★☆☆☆ • Poor (2/5)"),
83 DataSource(id="4", title="★☆☆☆☆ • Very Poor (1/5)"),
84 ],
85 ),
86 cs_rating := Dropdown(
87 name="cs_rating",
88 label="Customer service",
89 required=True,
90 data_source=[
91 DataSource(id="0", title="★★★★★ • Excellent (5/5)"),
92 DataSource(id="1", title="★★★★☆ • Good (4/5)"),
93 DataSource(id="2", title="★★★☆☆ • Average (3/5)"),
94 DataSource(id="3", title="★★☆☆☆ • Poor (2/5)"),
95 DataSource(id="4", title="★☆☆☆☆ • Very Poor (1/5)"),
96 ],
97 ),
98 Footer(
99 label="Done",
100 on_click_action=CompleteAction(
101 payload={
102 "purchase_rating": purchase_rating.ref,
103 "delivery_rating": delivery_rating.ref,
104 "cs_rating": cs_rating.ref,
105 "recommend_radio": recommend_radio.ref,
106 "comment_text": comment_text.ref,
107 },
108 ),
109 ),
110 ],
111 )
112 ],
113 ),
114 ),
115 ],
116)
117
118load_re_engagement = FlowJSON(
119 version="2.1",
120 screens=[
121 Screen(
122 id="SIGN_UP",
123 title="Finish Sign Up",
124 terminal=True,
125 data={},
126 layout=Layout(
127 type=LayoutType.SINGLE_COLUMN,
128 children=[
129 Form(
130 name="form",
131 children=[
132 first_name := TextInput(
133 name="firstName",
134 label="First Name",
135 input_type=InputType.TEXT,
136 required=True,
137 visible=True,
138 ),
139 last_name := TextInput(
140 name="lastName",
141 label="Last Name",
142 input_type=InputType.TEXT,
143 required=True,
144 visible=True,
145 ),
146 email := TextInput(
147 name="email",
148 label="Email Address",
149 input_type=InputType.EMAIL,
150 required=True,
151 visible=True,
152 ),
153 Footer(
154 label="Done",
155 enabled=True,
156 on_click_action=CompleteAction(
157 payload={
158 "firstName": first_name.ref,
159 "lastName": last_name.ref,
160 "email": email.ref,
161 },
162 ),
163 ),
164 ],
165 )
166 ],
167 ),
168 )
169 ],
170)
171
172costumer_engagement = FlowJSON(
173 version="2.1",
174 screens=[
175 Screen(
176 id="QUESTION_ONE",
177 title="Question 1 of 3",
178 data={},
179 layout=Layout(
180 type=LayoutType.SINGLE_COLUMN,
181 children=[
182 Form(
183 name="form",
184 children=[
185 TextHeading(
186 text="You've found the perfect deal, what do you do next?"
187 ),
188 question1_checkbox := CheckboxGroup(
189 name="question1Checkbox",
190 label="Choose all that apply:",
191 required=True,
192 data_source=[
193 DataSource(id="0", title="Buy it right away"),
194 DataSource(
195 id="1", title="Check reviews before buying"
196 ),
197 DataSource(
198 id="2", title="Share it with friends + family"
199 ),
200 DataSource(
201 id="3", title="Buy multiple, while its cheap"
202 ),
203 DataSource(id="4", title="None of the above"),
204 ],
205 ),
206 Footer(
207 label="Continue",
208 on_click_action=NavigateAction(
209 next=Next(
210 type=NextType.SCREEN, name="QUESTION_TWO"
211 ),
212 payload={
213 "question1Checkbox": question1_checkbox.ref
214 },
215 ),
216 ),
217 ],
218 )
219 ],
220 ),
221 ),
222 Screen(
223 id="QUESTION_TWO",
224 title="Question 2 of 3",
225 data=[
226 question1_checkbox := ScreenData(
227 key="question1Checkbox", example=["Example", "Example2"]
228 ),
229 ],
230 layout=Layout(
231 type=LayoutType.SINGLE_COLUMN,
232 children=[
233 Form(
234 name="form",
235 children=[
236 TextHeading(
237 text="Its your birthday in two weeks, how might you prepare?"
238 ),
239 question2_radio_buttons := RadioButtonsGroup(
240 name="question2RadioButtons",
241 label="Choose all that apply:",
242 required=True,
243 data_source=[
244 DataSource(id="0", title="Buy something new"),
245 DataSource(id="1", title="Wear the same, as usual"),
246 DataSource(id="2", title="Look for a deal online"),
247 ],
248 ),
249 Footer(
250 label="Continue",
251 on_click_action=NavigateAction(
252 next=Next(
253 type=NextType.SCREEN,
254 name="QUESTION_THREE",
255 ),
256 payload={
257 "question2RadioButtons": question2_radio_buttons.ref,
258 "question1Checkbox": question1_checkbox.ref,
259 },
260 ),
261 ),
262 ],
263 )
264 ],
265 ),
266 ),
267 Screen(
268 id="QUESTION_THREE",
269 title="Question 3 of 3",
270 data=[
271 question2_radio_buttons := ScreenData(
272 key="question2RadioButtons", example="Example"
273 ),
274 question1_checkbox := ScreenData(
275 key="question1Checkbox", example=["Example", "Example2"]
276 ),
277 ],
278 terminal=True,
279 layout=Layout(
280 type=LayoutType.SINGLE_COLUMN,
281 children=[
282 Form(
283 name="form",
284 children=[
285 TextHeading(text="What's the best gift for a friend?"),
286 question3_checkbox := CheckboxGroup(
287 name="question3Checkbox",
288 label="Choose all that apply:",
289 required=True,
290 data_source=[
291 DataSource(id="0", title="A gift voucher"),
292 DataSource(id="1", title="A new outfit "),
293 DataSource(id="2", title="A bouquet of flowers"),
294 DataSource(id="3", title="A meal out together"),
295 ],
296 ),
297 Footer(
298 label="Done",
299 on_click_action=CompleteAction(
300 payload={
301 "question1Checkbox": question1_checkbox.ref,
302 "question2RadioButtons": question2_radio_buttons.ref,
303 "question3Checkbox": question3_checkbox.ref,
304 },
305 ),
306 ),
307 ],
308 )
309 ],
310 ),
311 ),
312 ],
313)
314
315support_request = FlowJSON(
316 version="2.1",
317 screens=[
318 Screen(
319 id="DETAILS",
320 title="Get help",
321 data={},
322 terminal=True,
323 layout=Layout(
324 type=LayoutType.SINGLE_COLUMN,
325 children=[
326 Form(
327 name="form",
328 children=[
329 name := TextInput(
330 name="name",
331 label="Name",
332 input_type=InputType.TEXT,
333 required=True,
334 ),
335 order_number := TextInput(
336 label="Order number",
337 name="orderNumber",
338 input_type=InputType.NUMBER,
339 required=True,
340 helper_text="",
341 ),
342 topic_radio := RadioButtonsGroup(
343 label="Choose a topic",
344 name="topicRadio",
345 data_source=[
346 DataSource(id="0", title="Orders and payments"),
347 DataSource(id="1", title="Maintenance"),
348 DataSource(id="2", title="Delivery"),
349 DataSource(id="3", title="Returns"),
350 DataSource(id="4", title="Other"),
351 ],
352 required=True,
353 ),
354 desc := TextArea(
355 label="Description of issue",
356 required=False,
357 name="description",
358 ),
359 Footer(
360 label="Done",
361 on_click_action=CompleteAction(
362 payload={
363 "name": name.ref,
364 "orderNumber": order_number.ref,
365 "topicRadio": topic_radio.ref,
366 "description": desc.ref,
367 },
368 ),
369 ),
370 ],
371 )
372 ],
373 ),
374 )
375 ],
376)
377
378communication_preferences = FlowJSON(
379 version="2.1",
380 screens=[
381 Screen(
382 id="PREFERENCES",
383 title="Update Preferences",
384 data={},
385 terminal=True,
386 layout=Layout(
387 type=LayoutType.SINGLE_COLUMN,
388 children=[
389 Form(
390 name="form",
391 children=[
392 communication_types := CheckboxGroup(
393 label="Communication types",
394 required=True,
395 name="communicationTypes",
396 data_source=[
397 DataSource(
398 id="0", title="Special offers and promotions"
399 ),
400 DataSource(
401 id="1", title="Changes to my subscription"
402 ),
403 DataSource(id="2", title="News and events"),
404 DataSource(id="3", title="New products"),
405 ],
406 ),
407 contact_prefs := CheckboxGroup(
408 label="Contact Preferences",
409 required=False,
410 name="contactPrefs",
411 data_source=[
412 DataSource(id="0", title="Whatsapp"),
413 DataSource(id="1", title="Email"),
414 DataSource(id="2", title="SMS"),
415 ],
416 ),
417 Footer(
418 label="Done",
419 on_click_action=CompleteAction(
420 payload={
421 "communicationTypes": communication_types.ref,
422 "contactPrefs": contact_prefs.ref,
423 },
424 ),
425 ),
426 ],
427 )
428 ],
429 ),
430 )
431 ],
432)
433
434register_for_an_event = FlowJSON(
435 version="2.1",
436 screens=[
437 Screen(
438 id="SIGN_UP",
439 title="Sign Up",
440 data={},
441 layout=Layout(
442 type=LayoutType.SINGLE_COLUMN,
443 children=[
444 Form(
445 name="form",
446 children=[
447 TextHeading(text="Join our next webinar!"),
448 TextBody(text="First, we'll need a few details from you."),
449 first_name := TextInput(
450 name="firstName",
451 label="First Name",
452 input_type=InputType.TEXT,
453 required=True,
454 ),
455 last_name := TextInput(
456 label="Last Name",
457 name="lastName",
458 input_type=InputType.TEXT,
459 required=True,
460 ),
461 email := TextInput(
462 label="Email Address",
463 name="email",
464 input_type=InputType.EMAIL,
465 required=True,
466 ),
467 Footer(
468 label="Continue",
469 on_click_action=NavigateAction(
470 next=Next(type=NextType.SCREEN, name="SURVEY"),
471 payload={
472 "firstName": first_name.ref,
473 "lastName": last_name.ref,
474 "email": email.ref,
475 },
476 ),
477 ),
478 ],
479 )
480 ],
481 ),
482 ),
483 Screen(
484 id="SURVEY",
485 title="Thank you",
486 data=[
487 first_name := ScreenData(key="firstName", example="Example"),
488 last_name := ScreenData(key="lastName", example="Example"),
489 email := ScreenData(key="email", example="Example"),
490 ],
491 terminal=True,
492 layout=Layout(
493 type=LayoutType.SINGLE_COLUMN,
494 children=[
495 Form(
496 name="form",
497 children=[
498 TextHeading(text="Before you go"),
499 TextBody(text="How did you hear about us?"),
500 source := RadioButtonsGroup(
501 name="source",
502 label="Choose one",
503 required=False,
504 data_source=[
505 DataSource(id="0", title="Friend's recommendation"),
506 DataSource(id="1", title="TV advertisement"),
507 DataSource(id="2", title="Search engine"),
508 DataSource(id="3", title="Social media"),
509 ],
510 ),
511 Footer(
512 label="Done",
513 on_click_action=CompleteAction(
514 payload={
515 "source": source.ref,
516 "firstName": first_name.ref,
517 "lastName": last_name.ref,
518 "email": email.ref,
519 },
520 ),
521 ),
522 ],
523 )
524 ],
525 ),
526 ),
527 ],
528)
529
530sign_in = FlowJSON(
531 version="2.1",
532 data_api_version="3.0",
533 data_channel_uri="https://example.com",
534 routing_model={
535 "SIGN_IN": ["SIGN_UP", "FORGOT_PASSWORD"],
536 "SIGN_UP": ["TERMS_AND_CONDITIONS"],
537 "FORGOT_PASSWORD": [],
538 "TERMS_AND_CONDITIONS": [],
539 },
540 screens=[
541 Screen(
542 id="SIGN_IN",
543 title="Sign in",
544 terminal=True,
545 data={},
546 layout=Layout(
547 type=LayoutType.SINGLE_COLUMN,
548 children=[
549 Form(
550 name="sign_in_form",
551 children=[
552 email := TextInput(
553 name="email",
554 label="Email address",
555 input_type=InputType.EMAIL,
556 required=True,
557 ),
558 password := TextInput(
559 name="password",
560 label="Password",
561 input_type=InputType.PASSWORD,
562 required=True,
563 ),
564 EmbeddedLink(
565 text="Don't have an account? Sign up",
566 on_click_action=NavigateAction(
567 next=Next(type=NextType.SCREEN, name="SIGN_UP"),
568 ),
569 ),
570 EmbeddedLink(
571 text="Forgot password",
572 on_click_action=NavigateAction(
573 next=Next(
574 type=NextType.SCREEN,
575 name="FORGOT_PASSWORD",
576 ),
577 payload={"body": "Example"},
578 ),
579 ),
580 Footer(
581 label="Sign in",
582 on_click_action=DataExchangeAction(
583 payload={
584 "email": email.ref,
585 "password": password.ref,
586 },
587 ),
588 ),
589 ],
590 )
591 ],
592 ),
593 ),
594 Screen(
595 id="SIGN_UP",
596 title="Sign up",
597 data={},
598 layout=Layout(
599 type=LayoutType.SINGLE_COLUMN,
600 children=[
601 Form(
602 name="sign_up_form",
603 children=[
604 first_name := TextInput(
605 name="first_name",
606 label="First Name",
607 input_type=InputType.TEXT,
608 required=True,
609 ),
610 last_name := TextInput(
611 name="last_name",
612 label="Last Name",
613 input_type=InputType.TEXT,
614 required=True,
615 ),
616 email := TextInput(
617 name="email",
618 label="Email address",
619 input_type=InputType.EMAIL,
620 required=True,
621 ),
622 password := TextInput(
623 name="password",
624 label="Set password",
625 input_type=InputType.PASSWORD,
626 required=True,
627 ),
628 confirm_password := TextInput(
629 name="confirm_password",
630 label="Confirm password",
631 input_type=InputType.PASSWORD,
632 required=True,
633 ),
634 terms_agreement := OptIn(
635 name="terms_agreement",
636 label="I agree with the terms.",
637 required=True,
638 on_click_action=NavigateAction(
639 next=Next(
640 type=NextType.SCREEN,
641 name="TERMS_AND_CONDITIONS",
642 ),
643 ),
644 ),
645 offers_acceptance := OptIn(
646 name="offers_acceptance",
647 label="I would like to receive news and offers.",
648 ),
649 Footer(
650 label="Continue",
651 on_click_action=DataExchangeAction(
652 payload={
653 "first_name": first_name.ref,
654 "last_name": last_name.ref,
655 "email": email.ref,
656 "password": password.ref,
657 "confirm_password": confirm_password.ref,
658 "terms_agreement": terms_agreement.ref,
659 "offers_acceptance": offers_acceptance.ref,
660 },
661 ),
662 ),
663 ],
664 )
665 ],
666 ),
667 ),
668 Screen(
669 id="FORGOT_PASSWORD",
670 title="Forgot password",
671 terminal=True,
672 data=[
673 body := ScreenData(
674 key="body",
675 example=(
676 "Enter your email address for your account and we'll send a reset link. "
677 "The single-use link will expire after 24 hours."
678 ),
679 ),
680 ],
681 layout=Layout(
682 type=LayoutType.SINGLE_COLUMN,
683 children=[
684 Form(
685 name="forgot_password_form",
686 children=[
687 TextBody(text=body.ref),
688 email := TextInput(
689 name="email",
690 label="Email address",
691 input_type=InputType.EMAIL,
692 required=True,
693 ),
694 Footer(
695 label="Sign in",
696 on_click_action=DataExchangeAction(
697 payload={"email": email.ref},
698 ),
699 ),
700 ],
701 )
702 ],
703 ),
704 ),
705 Screen(
706 id="TERMS_AND_CONDITIONS",
707 title="Terms and conditions",
708 data={},
709 layout=Layout(
710 type=LayoutType.SINGLE_COLUMN,
711 children=[
712 TextHeading(text="Our Terms"),
713 TextSubheading(text="Data usage"),
714 TextBody(
715 text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae odio dui. Praesent ut nulla tincidunt, scelerisque augue malesuada, volutpat lorem. Aliquam iaculis ex at diam posuere mollis. Suspendisse eget purus ac tellus interdum pharetra. In quis dolor turpis. Fusce in porttitor enim, vitae efficitur nunc. Fusce dapibus finibus volutpat. Fusce velit mi, ullamcorper ac gravida vitae, blandit quis ex. Fusce ultrices diam et justo blandit, quis consequat nisl euismod. Vestibulum pretium est sem, vitae convallis justo sollicitudin non. Morbi bibendum purus mattis quam condimentum, a scelerisque erat bibendum. Nullam sit amet bibendum lectus."
716 ),
717 TextSubheading(text="Privacy policy"),
718 TextBody(
719 text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae odio dui. Praesent ut nulla tincidunt, scelerisque augue malesuada, volutpat lorem. Aliquam iaculis ex at diam posuere mollis. Suspendisse eget purus ac tellus interdum pharetra. In quis dolor turpis. Fusce in porttitor enim, vitae efficitur nunc. Fusce dapibus finibus volutpat. Fusce velit mi, ullamcorper ac gravida vitae, blandit quis ex. Fusce ultrices diam et justo blandit, quis consequat nisl euismod. Vestibulum pretium est sem, vitae convallis justo sollicitudin non. Morbi bibendum purus mattis quam condimentum, a scelerisque erat bibendum. Nullam sit amet bibendum lectus."
720 ),
721 ],
722 ),
723 ),
724 ],
725)
726
727register = FlowJSON(
728 version="2.1",
729 data_api_version="3.0",
730 data_channel_uri="https://example.com",
731 routing_model={"REGISTER": ["TERMS_AND_CONDITIONS"], "TERMS_AND_CONDITIONS": []},
732 screens=[
733 Screen(
734 id="REGISTER",
735 title="Register for an account",
736 terminal=True,
737 data=[
738 error_messages := ScreenData(
739 key="error_messages",
740 example={"confirm_password": "Passwords don't match."},
741 ),
742 ],
743 layout=Layout(
744 type=LayoutType.SINGLE_COLUMN,
745 children=[
746 Form(
747 name="register_form",
748 error_messages=error_messages.ref,
749 children=[
750 first_name := TextInput(
751 name="first_name",
752 required=True,
753 label="First name",
754 input_type="text",
755 ),
756 last_name := TextInput(
757 name="last_name",
758 required=True,
759 label="Last name",
760 input_type="text",
761 ),
762 email := TextInput(
763 name="email",
764 required=True,
765 label="Email address",
766 input_type="email",
767 ),
768 password := TextInput(
769 name="password",
770 required=True,
771 label="Set password",
772 input_type="password",
773 ),
774 confirm_password := TextInput(
775 name="confirm_password",
776 required=True,
777 label="Confirm password",
778 input_type="password",
779 ),
780 terms_agreement := OptIn(
781 name="terms_agreement",
782 label="I agree with the terms.",
783 required=True,
784 on_click_action=NavigateAction(
785 next=Next(
786 type=NextType.SCREEN,
787 name="TERMS_AND_CONDITIONS",
788 ),
789 ),
790 ),
791 offers_acceptance := OptIn(
792 name="offers_acceptance",
793 label="I would like to receive news and offers.",
794 ),
795 Footer(
796 label="Continue",
797 on_click_action=DataExchangeAction(
798 payload={
799 "first_name": first_name.ref,
800 "last_name": last_name.ref,
801 "email": email.ref,
802 "password": password.ref,
803 "confirm_password": confirm_password.ref,
804 "terms_agreement": terms_agreement.ref,
805 "offers_acceptance": offers_acceptance.ref,
806 },
807 ),
808 ),
809 ],
810 )
811 ],
812 ),
813 ),
814 Screen(
815 id="TERMS_AND_CONDITIONS",
816 title="Terms and conditions",
817 data={},
818 layout=Layout(
819 type=LayoutType.SINGLE_COLUMN,
820 children=[
821 TextHeading(text="Our Terms"),
822 TextSubheading(text="Data usage"),
823 TextBody(
824 text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae odio dui. Praesent ut nulla tincidunt, scelerisque augue malesuada, volutpat lorem. Aliquam iaculis ex at diam posuere mollis. Suspendisse eget purus ac tellus interdum pharetra. In quis dolor turpis. Fusce in porttitor enim, vitae efficitur nunc. Fusce dapibus finibus volutpat. Fusce velit mi, ullamcorper ac gravida vitae, blandit quis ex. Fusce ultrices diam et justo blandit, quis consequat nisl euismod. Vestibulum pretium est sem, vitae convallis justo sollicitudin non. Morbi bibendum purus mattis quam condimentum, a scelerisque erat bibendum. Nullam sit amet bibendum lectus."
825 ),
826 TextSubheading(text="Privacy policy"),
827 TextBody(
828 text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae odio dui. Praesent ut nulla tincidunt, scelerisque augue malesuada, volutpat lorem. Aliquam iaculis ex at diam posuere mollis. Suspendisse eget purus ac tellus interdum pharetra. In quis dolor turpis. Fusce in porttitor enim, vitae efficitur nunc. Fusce dapibus finibus volutpat. Fusce velit mi, ullamcorper ac gravida vitae, blandit quis ex. Fusce ultrices diam et justo blandit, quis consequat nisl euismod. Vestibulum pretium est sem, vitae convallis justo sollicitudin non. Morbi bibendum purus mattis quam condimentum, a scelerisque erat bibendum. Nullam sit amet bibendum lectus."
829 ),
830 ],
831 ),
832 ),
833 ],
834)
835book_a_table = FlowJSON(
836 version="2.1",
837 data_api_version="3.0",
838 data_channel_uri="https://example.com",
839 routing_model={
840 "BOOK_TABLE": ["BOOKING_DETAILS"],
841 "BOOKING_DETAILS": ["BOOKING_CONFIRMATION"],
842 "BOOKING_CONFIRMATION": ["TERMS_AND_CONDITIONS"],
843 "TERMS_AND_CONDITIONS": [],
844 },
845 screens=[
846 Screen(
847 id="BOOK_TABLE",
848 title="Book a table",
849 data=[
850 min_date := ScreenData(key="min_date", example="1696892400000"),
851 max_date := ScreenData(key="max_date", example="1760050800000"),
852 unavailable_dates := ScreenData(
853 key="unavailable_dates", example=["1760310000000"]
854 ),
855 time := ScreenData(
856 key="time",
857 example=[
858 DataSource(id="1", title="12:30"),
859 DataSource(id="2", title="13:30"),
860 DataSource(id="3", title="18:30"),
861 DataSource(id="4", title="19:30"),
862 DataSource(id="5", title="20:30"),
863 ],
864 ),
865 people := ScreenData(
866 key="people",
867 example=[
868 DataSource(id="1", title="1"),
869 DataSource(id="2", title="2"),
870 DataSource(id="3", title="3"),
871 DataSource(id="4", title="4"),
872 DataSource(id="5", title="5"),
873 DataSource(id="6", title="6"),
874 DataSource(id="7+", title="7+"),
875 ],
876 ),
877 location_data := ScreenData(
878 key="location",
879 example=[
880 DataSource(id="1", title="Shorty Heights, Light City, 59923")
881 ],
882 ),
883 ],
884 layout=Layout(
885 type=LayoutType.SINGLE_COLUMN,
886 children=[
887 Form(
888 name="book_table_form",
889 children=[
890 location := Dropdown(
891 label="Location",
892 name="location",
893 data_source=location_data.ref,
894 required=True,
895 on_select_action=DataExchangeAction(
896 payload={"location": ComponentRef("location")},
897 ),
898 ),
899 people_form := Dropdown(
900 label="People",
901 name="people",
902 data_source=people.ref,
903 required=True,
904 on_select_action=DataExchangeAction(
905 payload={"people": ComponentRef("people")},
906 ),
907 ),
908 date := DatePicker(
909 name="date",
910 label="Date",
911 min_date=min_date.ref,
912 max_date=max_date.ref,
913 unavailable_dates=unavailable_dates.ref,
914 required=True,
915 on_select_action=DataExchangeAction(
916 payload={"date": ComponentRef("date")},
917 ),
918 ),
919 time_form := Dropdown(
920 label="Time",
921 name="time",
922 data_source=time.ref,
923 required=True,
924 ),
925 Footer(
926 label="Continue",
927 on_click_action=NavigateAction(
928 next=Next(
929 type=NextType.SCREEN,
930 name="BOOKING_DETAILS",
931 ),
932 ),
933 ),
934 ],
935 )
936 ],
937 ),
938 ),
939 Screen(
940 id="BOOKING_DETAILS",
941 title="Booking details",
942 data={},
943 layout=Layout(
944 type=LayoutType.SINGLE_COLUMN,
945 children=[
946 Form(
947 name="booking_details_form",
948 children=[
949 name := TextInput(label="Name", name="name", required=True),
950 special_occasion := Dropdown(
951 label="Special occasion",
952 name="special_occasion",
953 data_source=[
954 DataSource(id="1", title="Birthday"),
955 DataSource(id="2", title="Anniversary"),
956 DataSource(id="3", title="Engagement"),
957 DataSource(id="4", title="Graduation"),
958 DataSource(id="5", title="Other"),
959 ],
960 required=False,
961 ),
962 requirements := TextArea(
963 label="Requirements",
964 name="requirements",
965 helper_text="e.g. Dietary or accessibility",
966 required=False,
967 ),
968 Footer(
969 label="Continue",
970 on_click_action=DataExchangeAction(
971 payload={
972 "name": name.ref,
973 "special_occasion": special_occasion.ref,
974 "requirements": requirements.ref,
975 },
976 ),
977 ),
978 ],
979 )
980 ],
981 ),
982 ),
983 Screen(
984 id="BOOKING_CONFIRMATION",
985 title="Booking confirmation",
986 terminal=True,
987 data=[
988 date := ScreenData(key="date", example="Date: Saturday, June 7 2023"),
989 time := ScreenData(key="time", example="Time: 19:30"),
990 people := ScreenData(key="people", example="People: 4"),
991 location := ScreenData(
992 key="location",
993 example="Location: Shorty Heights, Light City, 59923",
994 ),
995 name := ScreenData(key="name", example="Name: John Doe"),
996 special_occasion := ScreenData(
997 key="special_occasion", example="Special Occasion: Birthday"
998 ),
999 ],
1000 layout=Layout(
1001 type=LayoutType.SINGLE_COLUMN,
1002 children=[
1003 Form(
1004 name="confirmation_form",
1005 children=[
1006 TextBody(text=date.ref),
1007 TextBody(text=time.ref),
1008 TextBody(text=people.ref),
1009 TextBody(text=location.ref),
1010 TextBody(text=name.ref),
1011 TextBody(text=special_occasion.ref),
1012 privacy_policy := OptIn(
1013 name="privacy_policy",
1014 label="Accept our Privacy Policy",
1015 required=True,
1016 on_click_action=NavigateAction(
1017 next=Next(
1018 type=NextType.SCREEN,
1019 name="TERMS_AND_CONDITIONS",
1020 ),
1021 ),
1022 ),
1023 Footer(
1024 label="Confirm booking",
1025 on_click_action=DataExchangeAction(),
1026 ),
1027 ],
1028 )
1029 ],
1030 ),
1031 ),
1032 Screen(
1033 id="TERMS_AND_CONDITIONS",
1034 title="Terms and conditions",
1035 data={},
1036 layout=Layout(
1037 type=LayoutType.SINGLE_COLUMN,
1038 children=[
1039 TextHeading(text="Our Terms"),
1040 TextSubheading(text="Data usage"),
1041 TextBody(
1042 text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae odio dui. Praesent ut nulla tincidunt, scelerisque augue malesuada, volutpat lorem. Aliquam iaculis ex at diam posuere mollis. Suspendisse eget purus ac tellus interdum pharetra. In quis dolor turpis. Fusce in porttitor enim, vitae efficitur nunc. Fusce dapibus finibus volutpat. Fusce velit mi, ullamcorper ac gravida vitae, blandit quis ex. Fusce ultrices diam et justo blandit, quis consequat nisl euismod. Vestibulum pretium est sem, vitae convallis justo sollicitudin non. Morbi bibendum purus mattis quam condimentum, a scelerisque erat bibendum. Nullam sit amet bibendum lectus.",
1043 ),
1044 TextSubheading(text="Privacy policy"),
1045 TextBody(
1046 text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae odio dui. Praesent ut nulla tincidunt, scelerisque augue malesuada, volutpat lorem. Aliquam iaculis ex at diam posuere mollis. Suspendisse eget purus ac tellus interdum pharetra. In quis dolor turpis. Fusce in porttitor enim, vitae efficitur nunc. Fusce dapibus finibus volutpat. Fusce velit mi, ullamcorper ac gravida vitae, blandit quis ex. Fusce ultrices diam et justo blandit, quis consequat nisl euismod. Vestibulum pretium est sem, vitae convallis justo sollicitudin non. Morbi bibendum purus mattis quam condimentum, a scelerisque erat bibendum. Nullam sit amet bibendum lectus.",
1047 ),
1048 ],
1049 ),
1050 ),
1051 ],
1052)
1053
1054get_a_quote = FlowJSON(
1055 version="2.1",
1056 data_api_version="3.0",
1057 data_channel_uri="https://example.com",
1058 routing_model={
1059 "DETAILS": ["COVER"],
1060 "COVER": ["QUOTE"],
1061 "QUOTE": ["TERMS_AND_CONDITIONS"],
1062 "TERMS_AND_CONDITIONS": [],
1063 },
1064 screens=[
1065 Screen(
1066 id="DETAILS",
1067 title="Your details",
1068 data=[
1069 city := ScreenData(
1070 key="city", example=[DataSource(id="1", title="Light City, SO")]
1071 ),
1072 ],
1073 layout=Layout(
1074 type=LayoutType.SINGLE_COLUMN,
1075 children=[
1076 Form(
1077 name="details_form",
1078 children=[
1079 name := TextInput(
1080 label="Your name",
1081 input_type=InputType.TEXT,
1082 name="name",
1083 required=True,
1084 ),
1085 address := TextInput(
1086 label="Street address",
1087 input_type=InputType.TEXT,
1088 name="address",
1089 required=True,
1090 ),
1091 city := Dropdown(
1092 label="City, State",
1093 name="city",
1094 data_source=city.ref,
1095 required=True,
1096 ),
1097 zip_code := TextInput(
1098 label="Zip code",
1099 input_type=InputType.TEXT,
1100 name="zip_code",
1101 required=True,
1102 ),
1103 country_region := TextInput(
1104 label="Country/Region",
1105 input_type=InputType.TEXT,
1106 name="country_region",
1107 required=True,
1108 ),
1109 Footer(
1110 label="Continue",
1111 on_click_action=DataExchangeAction(
1112 payload={
1113 "name": name.ref,
1114 "address": address.ref,
1115 "city": city.ref,
1116 "zip_code": zip_code.ref,
1117 "country_region": country_region.ref,
1118 },
1119 ),
1120 ),
1121 ],
1122 )
1123 ],
1124 ),
1125 ),
1126 Screen(
1127 id="COVER",
1128 title="Your cover",
1129 data=[
1130 options := ScreenData(
1131 key="options",
1132 example=[
1133 DataSource(
1134 id="1",
1135 title="Fire and theft",
1136 description="Cover your home against incidents of theft or accidental fires",
1137 ),
1138 DataSource(
1139 id="2",
1140 title="Natural disaster",
1141 description="Protect your home against disasters including earthquakes, floods and storms",
1142 ),
1143 DataSource(
1144 id="3",
1145 title="Liability",
1146 description="Protect yourself from legal liabilities that occur from accidents on your property",
1147 ),
1148 ],
1149 ),
1150 ],
1151 layout=Layout(
1152 type=LayoutType.SINGLE_COLUMN,
1153 children=[
1154 Form(
1155 name="cover_form",
1156 children=[
1157 options_form := CheckboxGroup(
1158 name="options",
1159 data_source=options.ref,
1160 label="Options",
1161 required=True,
1162 ),
1163 Footer(
1164 label="Continue",
1165 on_click_action=DataExchangeAction(
1166 payload={"options": options_form.ref},
1167 ),
1168 ),
1169 ],
1170 )
1171 ],
1172 ),
1173 ),
1174 Screen(
1175 id="QUOTE",
1176 title="Your quote",
1177 terminal=True,
1178 data=[
1179 excess := ScreenData(
1180 key="excess", example=[DataSource(id="1", title="$250")]
1181 ),
1182 total := ScreenData(key="total", example="$47.98 per month"),
1183 ],
1184 layout=Layout(
1185 type=LayoutType.SINGLE_COLUMN,
1186 children=[
1187 Form(
1188 name="quote_form",
1189 children=[
1190 Dropdown(
1191 label="Excess",
1192 name="excess",
1193 data_source=excess.ref,
1194 on_select_action=DataExchangeAction(
1195 payload={"excess": ComponentRef("excess")},
1196 ),
1197 required=True,
1198 ),
1199 RadioButtonsGroup(
1200 name="payment_options",
1201 label="Payment options",
1202 data_source=[
1203 DataSource(id="1", title="Monthly"),
1204 DataSource(id="2", title="Annually (Save $115)"),
1205 ],
1206 on_select_action=DataExchangeAction(
1207 payload={
1208 "payment_options": ComponentRef(
1209 "payment_options"
1210 )
1211 },
1212 ),
1213 required=True,
1214 init_value="1",
1215 ),
1216 TextHeading(text=total.ref),
1217 privacy_policy := OptIn(
1218 name="privacy_policy",
1219 label="Accept our Privacy Policy",
1220 required=True,
1221 on_click_action=NavigateAction(
1222 next=Next(
1223 type=NextType.SCREEN,
1224 name="TERMS_AND_CONDITIONS",
1225 ),
1226 ),
1227 ),
1228 Footer(
1229 label="Choose quote",
1230 on_click_action=DataExchangeAction(
1231 payload={
1232 "privacy_policy": privacy_policy.ref,
1233 },
1234 ),
1235 ),
1236 ],
1237 )
1238 ],
1239 ),
1240 ),
1241 Screen(
1242 id="TERMS_AND_CONDITIONS",
1243 title="Terms and conditions",
1244 data={},
1245 layout=Layout(
1246 type=LayoutType.SINGLE_COLUMN,
1247 children=[
1248 TextHeading(text="Our Terms"),
1249 TextSubheading(text="Data usage"),
1250 TextBody(
1251 text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae odio dui. Praesent ut nulla tincidunt, scelerisque augue malesuada, volutpat lorem. Aliquam iaculis ex at diam posuere mollis. Suspendisse eget purus ac tellus interdum pharetra. In quis dolor turpis. Fusce in porttitor enim, vitae efficitur nunc. Fusce dapibus finibus volutpat. Fusce velit mi, ullamcorper ac gravida vitae, blandit quis ex. Fusce ultrices diam et justo blandit, quis consequat nisl euismod. Vestibulum pretium est sem, vitae convallis justo sollicitudin non. Morbi bibendum purus mattis quam condimentum, a scelerisque erat bibendum. Nullam sit amet bibendum lectus."
1252 ),
1253 TextSubheading(text="Privacy policy"),
1254 TextBody(
1255 text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae odio dui. Praesent ut nulla tincidunt, scelerisque augue malesuada, volutpat lorem. Aliquam iaculis ex at diam posuere mollis. Suspendisse eget purus ac tellus interdum pharetra. In quis dolor turpis. Fusce in porttitor enim, vitae efficitur nunc. Fusce dapibus finibus volutpat. Fusce velit mi, ullamcorper ac gravida vitae, blandit quis ex. Fusce ultrices diam et justo blandit, quis consequat nisl euismod. Vestibulum pretium est sem, vitae convallis justo sollicitudin non. Morbi bibendum purus mattis quam condimentum, a scelerisque erat bibendum. Nullam sit amet bibendum lectus."
1256 ),
1257 ],
1258 ),
1259 ),
1260 ],
1261)