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 on flow 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.

  1. 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 line 6, flow.a and flow.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 a default value of false 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

  1. thread_set

  2. read thread value

  3. clear thread set

  4. 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:

509

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.

  1. 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.

  1. 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
  1. Next, we’ll create a flow that uses one of those icons. In your app’s flow folder, create a new file called icon.yaml and copy this code into it:
triggers:
  - keyword: icon

steps:
  - ask_form: Name?
    icon: (@ config.icon.person )
  - flow_set: name
  1. Save the files and push them to the Grid:
meya format
meya push

Trigger the flow in the chat simulator to see the result:

461

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.