Overview
Data can be stored in various "scopes" that help you organize your app's data.
In this guide you’ll learn about the five data scopes and how to use them.
Available Scopes
Your Meya app has five data scopes you can use to store and access data in your app:
flow
thread
user
config
vault
In following sections, you’ll learn about the five scopes including when and how to use them.
Flow
The
flow
scope contains ephemeral data, which means that as soon as the flow ends any data stored onflow
scope is no longer available.
You can read and write values to the flow
scope using the methods described in How to Store Scope Data.
flow.result
flow.result
is a special case of flow data that gets automatically written to by Meya’s platform. Triggers and components that output data will get stored in this special location: flow.result
.
If you need this value to persist after the flow is complete save it to the thread
or user
scopes using the methods described in How to Store Scope Data.
Example 1
In this example, we’ll ask the user for two numbers together and add them together.
In your app’s flow
folder, create a new file called add.yaml
and copy this code into it:
triggers:
- keyword: add
steps:
- ask: Enter a number.
- flow_set:
a: (@ flow.result | int )
- ask: Enter another number
- flow_set:
b: (@ flow.result | int )
- say: The sum is (@ flow.a + flow.b )
Since the user’s input will be considered a string by default, we use the Jinja2 int
filter to convert their input to and integer on lines 7
and 10
. If we hadn’t, the app would have concatenated the inputs on line 11
, instead of adding them.
Save the file and push it to the Grid:
meya format
meya push
Run the flow and enter two numbers. You should see the result of the addition output to the simulator.
Example 2
The previous example showed how to move data from flow.result
to another location on flow
scope. In this example, we’ll demonstrate the ephemeral nature of flow
scope. Specifically, we’ll use an if
statement at the beginning of the flow to check if flow.a
and flow.b
still exist. If not, we’ll ask the user for input.
- Update
add.yaml
with this code:
triggers:
- keyword: add
steps:
- (check)
- if: (@ flow.a | default(false) and flow.b | default(false) )
then:
jump: sum
else: next
- ask: Enter a number.
- flow_set:
a: (@ flow.result | int )
- ask: Enter another number
- flow_set:
b: (@ flow.result | int )
- (sum)
- say: The sum is (@ flow.a + flow.b )
In the
if
statement on line6
,flow.a
andflow.b
will be truthy if they exist. Unfortunately, if they don’t exist, we’ll get an error and the app won’t continue! To guard against this, we use the Jinja2 default filter to provide adefault
value offalse
if the variables don’t exist.
Save the file and push it to the Grid:
meya format
meya push
Try running the flow a few times. Notice the if
statement does not detect values at flow.a
and flow.b
, which is what we would expect since those values disappeared once the previous run ended.
Thread
The
thread
scope contains data related to a particular conversational thread. A user may have more than one thread.
You can read and write values to the thread
scope using the methods described in How to Store Scope Data.
Example 1
-
thread_set
-
read thread value
-
clear thread set
-
Create a flow called
voice.yaml
and copy this code into it:
triggers:
- type: meya.session.trigger.chat.open
when: (@ thread.voice )
- keyword: voice
steps:
- if: (@ thread.voice )
then: next
else:
jump: text
- (voice)
- say: I can see that you're on a voice-enabled device.
- end
- (text)
- say: I can see you're using a text-enabled device.
Save the file and push it to the Grid using these commands in your terminal:
meya format
meya push
Test it out in the chat simulator:
User
The
user
scope is perfect for storing data that relates to the user and should persist across flows and conversation threads, like their name, email address, age, or an ID you use in your own system to identify the user.
You can read and write values to the user
scope using the methods described in How to Store Scope Data.
Example
In this example, we ask the user their name, which is then stored at flow.result
. The value is moved to user.name
using the user_set
component, which means we won’t have to ask for their name again, even in a different conversation thread.
- Create a new flow called
user.yaml
and copy this code into it:
triggers:
- keyword: name
steps:
- if: (@ user.name | default(false) )
then:
jump: say_hi
else: next
- (ask_name)
- ask: What's your name?
- user_set: name
- (say_hi)
- say: Nice to meet you, (@ user.name )!
Save the file and push it to the Grid:
meya format
meya push
Test the flow a couple of times in the chat simulator. The first time through, it will ask you for a name, but on future runs it will skip directly to the say_hi
label because the user.name
value persists.
Config
The
config
scope is stored at the app level, meaning it is the same for all users. This scope is for non-secret information. If you need to store secret values, like API keys, use the vault scope.
Values in config
scope are set during development. Your app can read config
values, but not write them.
Example
In this example, we’ll define a set of icons that we want to use throughout our app code.
- In your app’s root folder, create a file called
config.yaml
, if it doesn’t already exist. Copy this code into it:
icon:
bird: streamline-regular/33-pets-animals/12-wild birds/wild-bird.svg
cat: streamline-regular/33-pets-animals/04-cats/cat-sitting.svg
dog: streamline-regular/33-pets-animals/03-dogs/dog.svg
phone: streamline-light/07-work-office-companies/03-video-meetings/meeting-smartphone-hold-1.svg
person: streamline-light/21-messages-chat-smileys/01-messages-people/messages-people-person-bubble-oval-1.svg
- Next, we’ll create a flow that uses one of those icons. In your app’s
flow
folder, create a new file calledicon.yaml
and copy this code into it:
triggers:
- keyword: icon
steps:
- ask_form: Name?
icon: (@ config.icon.person )
- flow_set: name
- Save the files and push them to the Grid:
meya format
meya push
Trigger the flow in the chat simulator to see the result:
Vault
The
vault
is used to store secret information that shouldn’t be committed to version control. API keys are a perfect example of something you should store in the vault. You can also use it to store values that differ between environments, like flags and URLs.
Values in the vault
are set during development. Your app code can read vault
values, but not write them.
vault.yaml
Most apps will have a vault.yaml
file in their root folder. This file is committed to version control. Its purpose is to show developers what keys are stored in the vault without revealing their values. A typical vault.yaml
file looks like this:
sunshine_conversations.app_id: xxx
sunshine_conversations.api_key_id: xxx
sunshine_conversations.api_secret: xxx
vault.secret.yaml
The vault.secret.yaml
file looks very similar to vault.yaml
except it has the actual secret values. It should not be committed to version control.
While you can call this file whatever you want, the
.gitignore
file contains an entry for this filename by default.
sunshine_conversations.app_id: APP_ID
sunshine_conversations.api_key_id: API_KEY_ID
sunshine_conversations.api_secret: API_SECRET
One common mistake is to update
vault.secret.yaml
, but forget to upload the file to the Grid after saving the changes.Every time you update
vault.secret.yaml
run this command in your terminal:meya vault upload --file vault.secret.yaml
Example
In this example, we use the Calendly component to allow the user to book a meeting. The event link is read from the vault.
This example will only work if you have a Calendly account and have set up the Calendly integration.
The key takeaway is that you can access vault values using the syntax
(@ vault.<variable> )
.
triggers:
- keyword: calendly
steps:
- calendly: (@ vault.calendly.event_link )
title: Book a demo date
description: Click "Schedule time" below to setup a face-to-face meeting.
Updated about 2 years ago