Make API Calls from an Alexa Skill and Action on Google

Make API Calls from Alexa and Google Actions

No Alexa Skill or Action on Google lives in the vacuum. The more interesting voice application you have in mind, the more likely it is that you need to request some external data.

Learn how to build a task management voice application that can call Trello Rest API to read, create, update, and delete Trello cards with voice.


Table of Contents


Watch the video tutorial here:


What you’ll build

Before we start building any Alexa Skill or Google action, it’s a good idea to take a minute or two and write a sample dialogue first.

This dialogue depicts a happy path - when the interaction between a voice assistant and a user runs perfectly:

User: Hey Alexa / Google, open Task Manager

Assistant: Here is what you need to do today. [LIST OF TASKS]

User: Create a new task called “Walk the dog tonight”.

Assistant: Creating a new task: “Walk the dog tonight”.

User: Move the last task from TO DO into DOING.

Assistant: Moving “Walk the dog tonight” to “DOING”.

User: Delete the last task from “DONE”.

Assistant: Deleted “Record YouTube Video” from “DONE”

Do you want to take a listen? Just click on the Run button in front of Happy Path:

The cool thing is, the voice application we’re building interacts with the Trello API. Moreover, you can see the results of your voice commands on your screen - in your Trello board.

Let’s get started!


Requesting Trello API key and Token

First of all, head over to the Trello Developer Documentation. This page is your primary source of information regarding the API of Trello.

To make any API calls to Trello from your Alexa Skill or Google Action, you need to take 2 steps:

  1. Get a Developer API Key
  2. Generate a token

Get a Developer API Key

You get an API key by heading to this URL:

https://trello.com/app-key

You need to agree to the terms to generate a Trello API Key:

Trello Developer API Generation Screen

Generate a token

Now that you have your API Key, you need to generate a token.

You do that by requesting the following URL in your browser (copy and paste it):

https://trello.com/1/authorize?expiration=never&name=VoiceTaskManagerTutorial&scope=read,write&response_type=token&key={YourAPIKey}

NOTE: Replace {YourAPIKEY} with the actual key you received in the previous step.

Trello Requestion Developer Token


Understanding Trello Rest API

If you never worked with Trello Rest API before, one thing can be tricky at the beginning. On the web, Trello uses short-URLs, but for the API you’re going to need IDs for about everything: your boards, columns, cards.

However, there is a small trick you can apply. Head over to the Trello board:

Trello Board Example

With the short URL your address bar looks something like that:

https://trello.com/b/AVBxcRE/voice-task-manager

Take that URL and add .json to the end as follows:

https://trello.com/b/AVBxcRE/voice-task-manager

You now have all the information needed - including the IDs of this board - in a nicely formatted JSON:

Trello Board JSON

Trello has interactive API documentation - you can test any API call right in your browser. Let’s test getting the board information based on the board ID.

  1. Head over to the Trello API Documentation
  2. Enter the id of the board in the filed id
  3. Press the button Try it to see the authorization popup, where you need to provide your API key and token

Testing API key and Token

The result of the API call looks something like that:

The result of api call in Trello Api docs


List the cards in the TODO column with GET

After creating a new scenario in BotTalk, the first thing we want to do is to make a voice assistant - Amazon Alexa or Google Assistant - to read to the user all the tasks in the TODO column (list).

We do that by calling the GET /lists/{id}/cards API in Trello.

To get the ID of the TODO list, you add the .json to the URL of your board in the browser and study the JSON:

ID of the TODO List in Trello Board

In BotTalk you use the http.get action to make an API call, and the result of this call are stored in http_response variable:

    - name: Read Cards in TODO List
      actions:
        - http.get:
            url: 'https://api.trello.com/1/lists/5cb87630d107633274494541/cards?key=YOUR_KEY_HERE&token=YOUR_TOKEN_HERE'
        - sendText: >
            Here is what you need to do today.
            {% for card in http_response %}
              {{card.name}}.
            {% endfor %}

To list the cards from the http_response array in our Alexa Skill / Google Action, we use very handy TWIG for tag that works excellent in BotTalk.

To test the result of the API call, head over to the Test tab in the BotTalk editor and run the Random Walker Test. You can see and hear the results right there in the browser:

Testing Trello API Call in BotTalk


Create a new card with POST

Let’s create a new Trello card using nothing but your voice! Well, almost nothing. There is a lot to be done in the background, but for the user, “it just works”.

First thing you need to do is to ask a user if she wants to create a new task. We do that with an intent.

You can learn all about intents and slots in our Introductory Voice Development Course.

Add the following code in the Scenario section in BotTalk:

    - name: Read Cards in TODO List
      actions:
        - http.get:
            url: 'https://api.trello.com/1/lists/5cb87630d107633274494541/cards?key=YOUR_KEY_HERE&token=YOUR_TOKEN_HERE'
        - sendText: >
            Here is what you need to do today.
            {% for card in http_response %}
              {{card.name}}.
            {% endfor %}
        - sendText: >
            To create a new task, say "Create a new task called" followed by a task name.
        - getInput:
      next:
        Create_Task: Create a New Task

    - name: Create a New Task
      actions:
        - sendText: 'Creating a new task {{new_task_name}}'

In the code above, you ask a user to execute a command, and then link Create_Task intent with Create a New Task step.

In the Intents section of the BotTalk editor add the following:

---
intents:
  ok_great:
    - 'OK'
    - 'Great'
  Create_Task:
    - 'create a new task called {new_task_name}'
    - 'create {new_task_name} as a new task'

Finally, in the Slots section define a built-in Amazon SearchQuery Slot:

---
slots:

  new_task_name: 'AMAZON.SearchQuery'

Deploy a scenario as an Alexa Skill so you can test it in the Alexa Simulator:

Running the first test in the Alexa Simulator

Great! Your Alexa Skill now captures the name of the task a user wants to create in Trello.

To create this task on the Trello board, all you need to do is to send a POST request to /cards, including the name of the task and the ID of the list (idList).

Edit Create a New Task step and add the http.post action:

{% raw %}

    - name: Create a New Task
      actions:
        - sendText: 'Creating a new task: {{new_task_name}}.'
        - http.post:
            url: 'https://api.trello.com/1/cards'
            headers: ["Content-Type: application/json"]
            payload: >
              {
                "name": "{{new_task_name}}",
                "idList": "5cb87630d107633274494541",
                "key": "YOUR_KEY_HERE",
                "token": "YOUR_TOKEN_HERE"
              }
      next: Read Cards in TODO List

Let’s test it out in Alexa developer console simulator:

Adding a new task in Trello with Alexa Simulator

If we check the Trello board, the new task indeed has been added to the TODO list:

Trello board with the new task added via Alexa


Move a card from DOING to DONE with PUT

Now that we know how to read tasks from Trello board, and even create new tasks, let’s dig even deeper. Wouldn’t it be great to move the tasks between list using nothing but your voice?

As in the previous steps, we’re splitting this task into two steps:

  1. Testing in Trello API Playground
  2. Implementing in BotTalk

Testing in Trello API Playground

To change the list the card is on (to move the card from one “column” to another), we’re sending PUT request to the /cards/{id} endpoint.

Looking at this documentation, we realize, that if we provide the idList parameter, then the card should move to that list:

Trello documentation for putting a card into the list by id

Let’s try it out. First, let’s find out what ID does the list DOING have? To do this, we head over to the JSON.

Remember, yours should look something like that:

https://trello.com/b/AVBxcRE/voice-task-manager.json

By copying and pasting this URL, and then using the search inside your browser, you can easily find the ID of the list we need:

Getting the id of the Trello list from JSON

The same way we can search for the id of the card we want to move. Let’s try moving the last card we added: “walk the dog”.

Now we have all the information we need to make a request:

  • ID of the card to move
  • ID of the list to move the card to

Let’s make a PUT request inside of the Trello Docs playground:

Making API request inside of the Trello Playground

Indeed we just moved that card programmatically using Trello API:

Results of moving a card to a list with playground


Implementing in BotTalk

All that’s left to do is actually to convert this into BotTalk code so that we can move cards around with our voice!

That’s what we think the ideal conversation (happy path) could look like:

User: Move the last task from TO DO list to DOING.

Assistant: Moved “walk my dog tonight” to DOING.

In order to implement this dialogue as an Alexa Skill / Google Action, we need to make the following changes in our Intents in BotTalk:

---
intents:
  ok_great:
    - 'OK'
    - 'Great'
  Create_Task:
    - 'create a new task called {new_task_name}'
    - 'create {new_task_name} as a new task'
  Move_Task:
    - 'move the {task_order} task from {source_list_name} to {destination_list_name}'

Of course, we also need to add task_order and list_name to our Slots:

---
slots:

  new_task_name: 'AMAZON.SearchQuery'
  
  task_order:
    - first
    - last
    - second
    - third
    - fourth
    - fifth
    
  source_list_name:
    - TO DO
    - DOING
    - DONE
  destination_list_name:
    - TO DO
    - DOING
    - DONE

To debug that an assistant can understand our intent, we adjust the scenario accordingly:


    - name: Read Cards in TODO List
      actions:
        - http.get:
            url: 'https://api.trello.com/1/lists/5cb87630d107633274494541/cards?key=YOUR_KEY_HERE&token=YOUR_TOKEN_HERE'
        - sendText: >
            Here is what you need to do today. 
            {% for card in http_response %}
              {{card.name}}. 
            {% endfor %}
        - sendText: >
            To create a new task, say "Create a new task called" followed by a task name.
            To move a card, say "Move the last task from TO DO to DOING".
        - getInput:
      next:
        Create_Task: Create a New Task
        Move_Task: Move Task
        
    - name: Move Task
      actions:
        - sendText: >
            Debugging. Moving {{task_order}} task from {{source_list_name}} to {{destination_list_name}}

Because we changed Intents and Slots sections, we need to redeploy the scenario in BotTalk, before we can run the skill in Alexa simulator:

Debugging move task intent in Alexa simulator

Now that we’re sure that Alexa can understand our Move_Task intent, we can implement some logic.

For this tutorial, we’ll be implementing only one case: moving the last card from the list. However, feel free to experiment and come up with your own solution.

If you ever hit a roadblock, our Facebook Community is super friendly - and we’ll help you out straight away!

As we discussed earlier, to move a task from one list to another, we need both the task ID and list ID.

Let’s start with list ID.

We introduce the additional step that sets some variables that help us determine the id of the list based on the list name. This step is the first step in our Scenario:


    - name: Set Vars
      actions:
        - set: >
            list_id = {
              'to do': '5cb87630d107633274494541',
              'doing': '5cb876346c19663346a58289',
              'done': '5cb87636cd20710df9370d24'
            }
      next: Read Cards in TODO List

To determine the id of the list based on the user input, we need to use the source_list_name or destination_list_name. Here is how we debug if our mapping works:


    - name: Move Task
      actions:
        - sendText: >
            Debugging. Moving {{task_order}} task from {{source_list_name}} to {{destination_list_name}}.
            ID of the destination list is: {{ list_id[destination_list_name] }}.

Debugging mapping of list names to ids

Finally, we need the id of the card as well. That’s how we do it.

We already receive the list of cards from the Trello API (as we discussed in the previous section.

We save this list in the variable cards_in_list and then use the last TWIG filter to get the last card from that list:

{% raw %}


    - name: Read Cards in TODO List
      actions:
        - http.get:
            url: 'https://api.trello.com/1/lists/5cb87630d107633274494541/cards?key=YOUR_KEY_HERE&token=YOUR_TOKEN_HERE'
        - set: 'cards_in_list = http_response'
        - sendText: >
            Here is what you need to do today. 
            {% for card in http_response %}
              {{card.name}}. 
            {% endfor %}
        - sendText: >
            To create a new task, say "Create a new task called" followed by a task name.
            To move a card, say "Move the last task from TO DO to DOING".
        - getInput:
      next:
        Create_Task: Create a New Task
        Move_Task: Move Task
        
    - name: Move Task
      actions:
        - set: 'last_card = cards_in_list | last'
        - sendText: >
            Debugging. Moving {{task_order}} task from {{source_list_name}} to {{destination_list_name}}.
            ID of the destination list is: {{ list_id[destination_list_name] }}.
            ID of the last card is: {{ last_card.id }}
            Name of the last card is {{ last_card.name }}

One last run of the Alexa Simulator to debug everything and to be sure that both ID of the card and ID of the list are correct:

Alexa simulator debugging for card and list ids

Enough debugging, let’s finally make that PUT request already using BotTalk’s http.put action:


    - name: Move Task
      actions:
        - set: 'last_card = cards_in_list | last'
        - sendText: >
             Moving "{{ last_card.name }}" to "{{ destination_list_name }}".
        - http.put:
            url: 'https://api.trello.com/1/cards/{{ last_card.id }}'
            headers: ["Content-Type: application/json"]
            payload: >
              {
                "idList": "{{ list_id[destination_list_name] }}",
                "key": "YOUR_KEY_HERE",
                "token": "YOUR_TOKEN_HERE"
              }

After running the skill in the Alexa Simulator once again, we can check the trello board for the results!!!

The final result of moving cards in Trello with Alexa Simulator

Delete a card with DELETE

Deleting a Trello task with voice works the similar way as moving it. Just follow these three steps:

  1. Create a new Intent
  Delete_Task:
    - 'delete the {task_order} task from {source_list_name}'
  1. Create a new step
  2. Use http.delete action to make a DELETE request to /cards/{id} Trello API endpoint

Here is how our Intents section looks like now:

---
intents:
  ok_great:
    - 'OK'
    - 'Great'
  Create_Task:
    - 'create a new task called {new_task_name}'
    - 'create {new_task_name} as a new task'
  Move_Task:
    - 'move the {task_order} task from {source_list_name} to {destination_list_name}'
  Delete_Task:
    - 'delete the {task_order} task from {source_list_name}'

This is the new step that deletes the Trello card:


    - name: Delete Task
      actions:
        # Get the cards in the list the user mentioned
        - http.get:
            url: 'https://api.trello.com/1/lists/{{ list_id[source_list_name] }}/cards?key=YOUR_KEY_HERE&token=YOUR_TOKEN_HERE'
        - set: 'cards_in_list = http_response'
        # Delete the last card from this list
        - set: 'last_card = cards_in_list | last'
        - http.delete:
            url: 'https://api.trello.com/1/cards/{{ last_card.id }}'
            headers: ["Content-Type: application/json"]
            payload: >
              {
                "idList": "{{ list_id[source_list_name] }}",
                "key": "YOUR_KEY_HERE",
                "token": "YOUR_TOKEN_HERE"
              }
        - sendText: 'Deleted {{ last_card.name }} from {{ source_list_name }}'

Redeploy the scenario in BotTalk, and then head over to Alexa simulator to launch the command:

Deleting a Trello card with voice using Alexa Simulator

Final check of our Trello board, to make sure that all is working and the card has been deleted:

Checking Trello board for deleted card

Great! You’ve made it! Congrats!


Source Code

You can find the complete source code for this tutorial in our GitHub Repository.


Final Words

Did you like this tutorial? Please spread the world and share it on Facebook, Twitter, Reddit - whatever.

Thank you so much!

🤖


Written by Andrey Esaulov on 18 April 2019

Updated on 20 May 2019