Amazon Alexa skill integration for creating voice controlled Bubble apps

Has anyone tried to build an Alexa skill (https://developer.amazon.com/alexa-skills-kit) to add voice control for your Bubble app?
Can you please share a basic “hello world” working example for this?

2 Likes

I went ahead and started building a simple Alexa skill “Hello Bubble”. However, when I tested it, I am getting an error " The remote endpoint could not be called, or the response it returned was invalid."

Any advice from Bubble experts would be much appreciated!

Here is a link to my bubble app editor / api workflow:

Here is a snapshot of my configurations on the Alexa end:




1 Like

If you try to run the workflow in Postman or Curl, are you having the right response?

1 Like

No. It looks like the object-ids are returned in the response, instead of a formatted json.
I was expecting something like this:

{
“version”: “1.0”,
“sessionAttributes”: {
“supportedHoriscopePeriods”: {
“daily”: true,
“weekly”: false,
“monthly”: false
}
},
“response”: {
“outputSpeech”: {
“type”: “PlainText”,
“text”: “Today will provide you a new learning opportunity. Stick with it and the possibilities will be endless. Can I help you with anything else?”
},
“card”: {
“type”: “Simple”,
“title”: “Horoscope”,
“content”: “Today will provide you a new learning opportunity. Stick with it and the possibilities will be endless.”
},
“reprompt”: {
“outputSpeech”: {
“type”: “PlainText”,
“text”: “Can I help you with anything else?”
}
},
“shouldEndSession”: false
}
}

Here is the response from Postman:

Made some progress. I checked the “return as plain text” option and manually constructed the json. Now Postman sees the json response that I expect it to see. However, Alexa is still complaining about “The remote endpoint could not be called, or the response it returned was invalid.”

Here is the Bubble end:

Here is Postman:

Here is Alexa:

More progress. I was able to resolve the issue where Alexa was complaining about “The remote endpoint could not be called, or the response it returned was invalid.” This was because of the SSL setting/configuration. The snapshot below, shows the SSL config that worked:

I am now able to see the response from Bubble in Alexa:

Now I need to figure out how to do the same with user authentication.

4 Likes

I was able to successfully link a Bubble user account with Alexa. However, I have run into this roadblock, for which I do not have a solution - and would appreciate some help from Bubble experts.

The Alexa service calls my Bubble API endpoint with the token. However, the token is sent in the body of the request, as a nested parameter See below:

My understanding is that Bubble expects:

  • the token to be in the header (and not the body)
  • it has to be in the format Authorization: Bearer

I cannot force Amazon/Alexa to put their token in the header like how Bubble wants it. Is there any other way to authenticate my workflow, using the access token in the body of the request (instead of expecting it in the header)?

“user”: {
“userId”: “amzn1.ask.accountxyz”,
“accessToken”: “1479328196354x69962207484059003”
}

you can have the api_token in body of the request.

Its great news if the api_token can be in the body of the request. Unfortunately, I am not able to get it to work and would appreciate your help.
Amazon/Alexa sends the api_token as a key/value pair with the key “accessToken”, that is nested within the “user” object.

This is what Amazon/Alexa sends in the body of the request:

“user”: {
“userId”: “amzn1.ask.accountxyz”,
“accessToken”: “1479328196354x69962207484059003”
}

This is what Bubble responds (when I test in Postman):
{
“statusCode”: 401,
“message”: “You must authenticate to call this method”
}

It looks like Bubble is unable to look inside a nested JSON to extract the token.
This appears to be the last missing piece for the Amazon/Alexa integration and would appreciate any help to get it resolved. Thank you.

The endpoint is:
https://support.bubbleapps.io/version-test/api/1.0/wf/gethoroscope

The workflow is here:

Did some more tests/debugging on this. It looks like it does not work even in the un-nested/flattened case, when the api_token is in the body. The only scenario where it works, is if it is in the header - and that too in the specific format: “Authorization”: “Bearer api_token”.

Here are the details with snapshots from Postman.

  1. If the body has “accessToken”: api_token, it does not work. See below.

  1. If the body has “Authorization”: " Bearer api_token", it does not work. See below:

  1. If the header has: “Authorization”: “Bearer api_token”, then it works. See below:
1 Like

Which key are you using? When i look at the support app I see this one…

840d16bd7a23d448f0ad041ba1646865

quite different from yours

I am not using the key (840d16bd7a23d448f0ad041ba1646865) from the settings tab.
I am using the token generated by the loginsignup workflow: https://support.bubbleapps.io/version-test/api/1.0/wf/loginsignup

The Amazon Alexa user will be redirected to login page in the support app, where they can enter their email and password to login. This will trigger the above loginsignup workflow (I am using the API connector to call this workflow), and this will return the token back to Alexa. Alexa will use this token for all subsequent communication.

great! awesome topic. :relieved:

Oh sorry my bad. That doesn’t help with the nested body unfortunately. We looked into it, it’s doable but it’s not a small project (kind of a reverse API connector tool). We’ll see what we can do in the coming months but we can’t promise a quick turnaround there. Does Zapier has a way to flatten things?

1 Like

There are 2 missing items from Bubble to support this:

  1. the ability to authenticate a token sent in the body of the request.
  2. the ability to look into a nested json to get the token (or any other field, for that matter)

I will look into Zapier and see if they can help with the flattening, in the interim. That will help with (2). How about (1)?

1 Like

Made progress. I was able to successfully use Zapier, to extract the token sent by Alexa, and insert it into the header of the post request sent to Bubble. Bubble is able to authenticate the token, and I am able to determine Bubble’s CurrentUser based on that.

The flow is like this:

Alexa -->Zapier—>Bubble

Now, how do I make Bubble to send the response directly to Alexa, instead of sending it to Zapier?
It looks like Zapier can be used only for 1-way communication.

Here are screenshots from my Zap:

This one extracts the accessToken, from the nested JSON sent by Alexa:

This one puts the token in the header like Bubble expects, and calls my Bubble workflow:

For that you’ll need to use the API connector and define the calls to Alexa

Isn’t API connector used to connect to a http server (and not client)? Or can it also be used to send a response to client? In our case here, Alexa is the client and the Bubble app is the server. The client (Alexa) has sent Bubble a request via Zapier. Now we need to send a response back to the client (Alexa). In order to send a response back to Alexa(client), we need to know the client’s IP address/port number/socket etc. All API docs publish only the server endpoints/URLs and do not give any information about the client.

How do I find out this client info, so that it can be used as the URL to send the response back, using API connector?

I’m not an Alexa expert, but if they provide some endpoints to send back some info an API http request seems like the way to go.

The problem is that they do not provide an endpoint (atleast, I am not able to find it - yet).
It is understandable why they do not provide this endpoint because, Alexa functions as a http client (like a web browser). This Alexa http client calls (sends http request to) our Bubble app’s service endpoint (our API workflow). We need to send a http response back to the client that sent the http request. Since Zapier sits between Alexa and Bubble, Bubble does not know about the client. Zapier should know about the client, but unfortunately they do not expose this client info through their UI.

Blocked on this for now.