Magic Links

Launch flows from email and SMS with authenticated links

If you've ever signed up for a platform—including Meya—you've probably seen a magic link. Magic links allow users to login without using a password. The link includes information that's used to authenticate the user. Once the user clicks the link, they're redirected back to the app.

On the Meya platform you can use magic links to:

  • enforce two-factor authentication
  • launch a flow from a marketing email. You can include contextual information so you know what marketing campaign the user responded to.
  • securely transfer the user's Orb session to another device.

Here's a video demonstration of how magic links work: Magic links

Read the docs for a complete reference to magic links.

Keep reading to learn how to use magic links in your app.

📘

Github

Don't forget to check out the demo-app repo. It's a great resource you can use to learn about Meya features. Check out the magic link flows here: Magic link flows

Start a flow with context

Let's say a user has been chatting with your app on their desktop, and now they'd like to continue the session on their mobile device. Normally, engaging with the app on a new device would result in a separate user and session being created, but with magic links, we can seamlessly authenticate the user and continue the same session on their other device.

Magic link flow

Let's create a flow that will send the magic link to the user. First, open your app's flow folder and create a new folder called magic_links. Inside the new folder, create a flow called transfer_session.yaml and copy this code into it:

triggers:
  - keyword: magic

steps:
  - magic_link: (@ thread.page_open.url )
    integration: integration.orb
    button_id: false
    single_use: false
  - flow_set: magic_link
  - say: Here's your secret magic link (@ flow.magic_link )

Line 5: We're using the Orb's magic_link component and telling it to use the current page URL as the link.

Lines 6-7: You'll see an example of a button ID and single use button in the next example. For now, just leave them set to false.

📘

If you have an email or SMS integration set up, you can change this flow so that it emails or messages the link to you. For this example, though, we'll just print the link to the screen.

Save page URL flow

Since our magic_links.yaml flow requires a value for (@ thread.page_open.url ), let's make sure a value is saved there when a page_open event occurs.

In your flow folder, create a new file called page_open.yaml and copy this code into it:

triggers:
  - type: page_open

steps:
  - thread_set:
      page_open: (@ flow.event.data.context )

The page_open event's context data includes the current page URL, so our other flow will be able to access it.

🚧

If you already have a flow that uses the page_open trigger, you can add the thread_set step to that flow instead of creating this one.

Save your files and upload the changes to the Grid with these commands in your terminal:

meya format
meya push

Test it out

We're ready to test our new flows.

  1. Open the Simulator. This will trigger the page_open event.
  2. Type the word magic and verify that you receive a magic link.
  3. Open the link in an incognito window and confirm that you can continue the same session with the app, like in the GIF below.

👍

Awesome! You've learned how to transfer a session to another device.

Two-factor authentication

For the 2FA flow, we'll make an invisible button that can only be "clicked" by using the magic link sent to the user via email or SMS. Buttons like this are called dynamic buttons. You can use them to prevent the flow from continuing until the user has authenticated themselves with the magic link. Let's see how it works.

Create the 2FA flow

In your app's flow/magic_links folder, create a new flow called 2fa.yaml and copy this code into it:

triggers:
  - keyword: 2fa

steps:
  - say: You must authenticate to continue!
  - magic_link: (@ thread.page_open.url )
    integration: integration.orb
    button_id: true
    single_use: true
  - flow_set: magic_link
  - say: Here's your secret magic link (@ flow.magic_link )
  - ask: Please click the magic link
    buttons:
      - button_id: (@ flow.button_id )
        action: next
  - say: Great, you're in!

Line 8: This time we'll tell the magic_link component to generate a random ID that can be used to identify this button. This is how the app will be able to tell that the dynamic button was clicked.

Line 9: Since we're using this button for authentication, it makes sense that the user should only be able to use it once.

🚧

Line 11: In a real world scenario, you wouldn't display the magic link to the user in the chat. Instead, you would send it via email or SMS. If you have an email or SMS integration set up, feel free to try that. For this demonstration, however, we'll just display the magic link in the text.

Lines 12-15: The ask component creates a button with a button ID matching the one in our magic link. This means when the user clicks the link, the app will treat it as if the user had clicked this button. Without the link, there is no way to continue the flow.

Save the file and upload it using these commands in your terminal:

meya format
meya push

Test it out

  1. In your app's simulator, type 2fa to trigger the flow.
  2. Copy the magic link into an incognito tab. Notice how the flow continues in both windows. That's because they both are sharing the same session.

👍

Great! You can now perform 2FA with your app.

Passing context with magic links

The magic_link component also supports the context property, which let's you send data to flow scope. This contextual data could include the ID for a marketing campaign, the SKU of the product the user was looking at, and much more.

Try updating the flows in the examples above to include context data.

triggers:
  - keyword: magic context

steps:
  - magic_link: (@ thread.page_open.url )
    integration: integration.orb
    button_id: false
    single_use: false
    context:
        foo: bar
  - flow_set: magic_link
  - say: Here's your secret magic link (@ flow.magic_link )

Launching flows with magic links

Did you know you can trigger a flow with a button ID? With the button trigger, you can.

For this to work, you'll need to specify an ID in the magic_link component, instead of letting the platform randomly generate one. Here's an example.

triggers:
  - keyword: magic static

steps:
  - magic_link: (@ thread.page_open.url )
    integration: integration.orb
    button_id: my_static_id
    single_use: false
  - flow_set: magic_link
  - say: Here's your secret magic link (@ flow.magic_link )

And here's what the button trigger would look like:

triggers:
  - button_id: my_static_id

steps:
  - say: It worked!