Write your first flow
Write complex business logic with basic flow code.
Remove unused files
Let's do a bit of clean up first.
- Open your app in the Meya Console.
- Select the Flows page.
- Delete the following flow files:
welcome.yamlhi.yamlcatchall.yaml
- Select the Components page.
- Delete:
welcome.py
Update the welcome message
Your initial message to the user should give them an indication of what they can do with your app. Let's encourage the user to create an order by giving them a quick reply button.
- Select the Flows page.
- Open the
open_page.yamlfile in the code editor and paste the following BFML code, click Save (you can ignore the error message for now, this will be fixed when adding the other flows):
triggers:
- type: page_open
- keyword: start
steps:
- say: Hi, I'm Pizza Bot! I can help you order a pizza.
quick_replies:
- text: Order
action:
flow: flow.order
transfer: true
composer:
visibility: hide
WhitespaceFlow code is written in Bot Flow Markup Language, which is based on YAML. This means that whitespace, including indentation, is very important. You'll get errors if your flow code is not indented properly. Make sure your flow code looks like the above code example.
Lines 8-10: When the user clicks the quick reply, it will launch the yet-to-be-created order.yaml file. transfer: true means that we don't want to return to the open_page.yaml flow when the order.yaml flow completes (check the Flows guide for a detailed explanation of the flow component).
Lines 11-12: Since our bot is going to be menu-driven, we don't want to expose the composer, which let's the user enter any text they want. As an extension of this project you could try adding the Dialogflow integration so your app can understand your user's free text, but for now, let's continue with a menu-only bot.
Create the order flow
- Select the Flows page.
- Click the Create flow button.
- Rename the flow from
new_flow.yamltoorder.yaml. - Paste the following code into the code editor, and click Save (ignore the error message for now):
steps:
- ask: What size of pizza would you like?
quick_replies:
- text: Small
data:
size: small
price: 6
- text: Medium
data:
size: medium
price: 10
- text: Large
data:
size: large
price: 14
- text: Cancel order
action:
jump: cancel
composer:
visibility: hide
- flow_set:
ingredients: []
message: What ingredients you like to add
- (add ingredients)
- ask: (@ flow.message )
quick_replies:
- text: Pepperoni
result: pepperoni
- text: Olives
result: olives
- text: Chicken
result: chicken
- text: Hot peppers
result: hot peppers
- text: Feta cheese
result: feta
- text: Green pepper
result: green pepper
- text: Onion
result: onion
- text: Done
action:
jump: get user info
- text: Cancel order
action:
jump: cancel
composer:
visibility: hide
- flow_set:
ingredients: (@ flow.ingredients + [flow.result] )
- flow_set:
message: |
**Added: (@ flow.ingredients | join(", ") )**
What else?
- jump: add ingredients
- (get user info)
- flow: flow.get_user_info
- tiles:
- title: Your order
rows:
- - cell: Size
value: (@ flow.size )
- - cell: Ingredients
value: (@ flow.ingredients | join(", ") )
- - cell: For delivery?
value: (@ flow.is_delivery )
- - cell: Address
value: (@ user.home_address )
- - cell: Payment method
value: (@ flow.payment_method )
- - cell: Total
value: $(@ flow.price ) + tax
ask: Here's a summary of your order.
quick_replies:
- text: Submit order
action: next
- text: Cancel
action:
jump: cancel
- type: component.submit
api_token: (@ vault.api_token )
size: (@ flow.size )
ingredients: (@ flow.ingredients )
address: (@ user.home_address )
payment_method: (@ flow.payment_method )
is_delivery: (@ flow.is_delivery )
- if: (@ flow.result )
then:
say: >
Your order is submitted and will be
(%- if flow.is_delivery %)
delivered
(%- else %)
ready for pickup
(%- endif %)
in 20 minutes.
else:
say: I wasn't able to place your order. To place your order, please give us
a call at 1-800-123-4567.
- flow: flow.open_page
transfer: true
- (cancel)
- say: Okay, I've cancelled your order.
- flow: flow.open_page
transfer: trueLet's take a minute to understand what's going on here.
Lines 3-18: When the user clicks on one of these quick reply buttons, the size and price of the pizza will be stored on flow scope at flow.size and flow.price, respectively.
Lines 22-24: Next, we initialize a list of ingredients and a message we'll use to prompt the user for their selection.
Lines 51-57: After the user selects an ingredient, we add it to the list and update our message to include the list of selected ingredients. Note that we need to use two flow_set components so that the message variable has the latest version of the ingredients list.
Line 58: We use the jump component to jump back to the add ingredients label so the user can keep selecting ingredients.
Once the user clicks the Done quick reply, they'll jump to the get user info label.
Lines 62-83: We use a tile component to summarize the order details.
Lines 85-91: In a future step, we'll build a custom component to actually place the order. you can see from this BFML, though, that we'll provide it with an API key and the order details.
Lines 92-104: Depending on whether the custom component returns true or false, we'll display a final message to the user.
Vizualize the flow
- Open the
order.yamlflow in the code editor. - Click on the Visual button.
Create the user info flow
Although we could include this code in the order.yaml flow, it makes sense to split this out into another flow so that each flow has a specific purpose: The previous flow is for customizing the pizza; this flow is for providing user info, such as payment method and delivery address.
- Select the Flows page.
- Click the Create flow button.
- Rename the flow from
new_flow.yamltoget_user_info.yaml. - Paste the following code into the code editor, and click Save (ignore the error message for now):
steps:
- ask: How will you be paying?
quick_replies:
- Cash
- Credit/debit
composer:
visibility: hide
- flow_set: payment_method
- ask: Is this for take-out, or delivery?
quick_replies:
- text: Take-out
result: false
- text: Delivery
result: true
- text: Cancel order
action:
jump: cancel
composer:
visibility: hide
- flow_set: is_delivery
- if: (@ flow.is_delivery )
then: next
else:
jump: end
- if: (@ user.home_address | default(false) )
then:
jump: end
else: next
- ask: What is your address?
- user_set: home_address
- (end)
- end:
payment_method: (@ flow.payment_method )
is_delivery: (@ flow.is_delivery )
- (cancel)
- say: Okay, I've cancelled your order.
- flow: flow.open_page
transfer: trueHaving already written the order.yaml flow, this flow will probably make sense pretty quickly:
- We ask a series of questions about the user,
- offer them quick reply buttons to make the process as easy as possible, and
- save the results to either
floworuserscope.
userscopeLine 33: We're using
userscope here because this piece of data (the user's home address) is unlikely to change often. By saving it touserscope, we ensure that the user won't need to type it again when they order pizza from us in the future.
Lines 36-38: The end component ends the flow and returns the user to the parent flow, which in this case is order.yaml. Since payment_method and is_delivery are stored on flow scope, they'll disappear as soon as we leave the get_user_info.yaml flow. The end component lets us specify a YAML dictionary of data we want to pass back to the order.yaml flow's flow scope so we can keep working with it. (Check the Flows guide for more detailed info on the end component).
Vizualize the flow
- Open the
get_user_info.yamlflow in the code editor. - Click on the Visual button.
(Optional) Local IDE
Remove files
Remove the following files:
flow/welcome.yamlflow/hi.yamlflow/catchall.yamlcomponent/welcome.py
Update bot config
Open bot/default.yaml and update name to Pizza Bot.
Let's also change the default bot avatar to this pizza slice icon: icon
Here's what your file should look like:
type: meya.bot.element
name: Pizza Bot
avatar:
image: https://images.vexels.com/media/users/3/157209/isolated/preview/725aa2473489db2e550656210c557f18-cheesy-pizza-icon-by-vexels.png
markdown: trueCreate new files
Create the following files in your IDE:
flow/order.yaml: paste the content of theorder.yamlfile above.flow/get_user_info.yaml: paste the content of theget_user_info.yamlfile above.
Update the following files in your IDE:
flow/open_page.yaml: paste the content of theopen_page.yamlfile above.
Updated 5 months ago
Next, we'll add the component.order.submit component referenced in the order.yaml flow.
