I am new to voice agents and particularly to Javascript. However, I am in need to develop a voice agent in the Google Actions Console.
The most critical part of my agent is that I need to read data from a google spreadsheet which I figure out I can use SheetDB, a web service, to stream the data from the spreadsheet to the web. Right now the stream is running on the following link: https://sheetdb.io/api/v1/n3ol4hwmfsmqd
I am also setting up a webhook to retrieve the data from the stream through cloud functions in firebase. This is the cloud function as I have it right now:
const { conversation } = require('@assistant/conversation'); const functions = require('firebase-functions'); const axios = require('axios'); const app = conversation({debug: true}); app.handle('getItem', conv => { getItem(); conv.add("This test to see if we are accessing the webhook"); }); function getData() { return axios.get('https://sheetdb.io/api/v1/n3ol4hwmfsmqd'); } function getItem() { getData().then(res => { console.log(res.data); }); } exports.ActionsOnGoogleFulfillment = functions.https.onRequest(app);
What I am trying to do here is that in the conversation, I call the getItem() function which basically, read the data and print it to the console. the getData() function uses axios plugin to read from SheetDB.
However, when I run the agent and the data is read from my function the data is split into multiple log messages. THis is the console log in cloud function:
2:04:27.925 PM cf-hfyNV-ZVWlECkylj8TUN1w-name Function execution took 378 ms, finished with status code: 200 2:04:30.645 PM cf-hfyNV-ZVWlECkylj8TUN1w-name [ { Item: 'Beam B-1', 2:04:30.645 PM cf-hfyNV-ZVWlECkylj8TUN1w-name Level: '2', 2:04:30.645 PM cf-hfyNV-ZVWlECkylj8TUN1w-name Zone: 'A', 2:04:30.645 PM cf-hfyNV-ZVWlECkylj8TUN1w-name Location: 'Beam B-1 is located on Level 2 in zone A', 2:04:30.645 PM cf-hfyNV-ZVWlECkylj8TUN1w-name Responsible: 'Contractor' }, 2:04:30.645 PM cf-hfyNV-ZVWlECkylj8TUN1w-name { Item: 'Column C-2', 2:04:30.645 PM cf-hfyNV-ZVWlECkylj8TUN1w-name Level: '3', 2:04:30.645 PM cf-hfyNV-ZVWlECkylj8TUN1w-name Zone: 'A', 2:04:30.645 PM cf-hfyNV-ZVWlECkylj8TUN1w-name Location: 'Column C-2 is located on Level 3 in zone A', 2:04:30.645 PM cf-hfyNV-ZVWlECkylj8TUN1w-name Responsible: 'Kiewit' }, 2:04:30.645 PM cf-hfyNV-ZVWlECkylj8TUN1w-name { Item: 'Window B', 2:04:30.645 PM cf-hfyNV-ZVWlECkylj8TUN1w-name Level: '2', 2:04:30.645 PM cf-hfyNV-ZVWlECkylj8TUN1w-name Zone: 'B', 2:04:30.645 PM cf-hfyNV-ZVWlECkylj8TUN1w-name Location: 'Window B is located on Level 2 in zone B', 2:04:30.645 PM cf-hfyNV-ZVWlECkylj8TUN1w-name Responsible: 'Tech' } ]
The complete data looks like this:
[{"Item":"Beam B-1","Level":"2","Zone":"A","Location":"Beam B-1 is located on Level 2 in zone A","Responsible":"Contractor"},{"Item":"Column C-2","Level":"3","Zone":"A","Location":"Column C-2 is located on Level 3 in zone A","Responsible":"Kiewit"},{"Item":"Window B","Level":"2","Zone":"B","Location":"Window B is located on Level 2 in zone B","Responsible":"Tech"}]
The problem is that I need to read the data at once, in other words, should be printed in a single log to be able to parse it and retrieve the piece of data I need.
I have struggled with this for some time so I hope anybody can help me. Please let me know if you need more details.
Advertisement
Answer
Your code looks a bit correct, although you need to consider how you are using Promises. They are asynchronous, which means that code below the async operation can run even before the first operation is done.
So when you run getItem()
and then conv.add
, you aren’t guaranteed to have completed your DB operation. This is where async
/await
keywords are used, which can make it a bit easier to manage asynchronous operations in a sequential way.
Another issue is more directly related to your logging. By default Firebase Functions will break up results into separate lines as you see. There is more documentation on how to use their own logging SDK or how to fix the logging issue directly.
With these two in mind, here’s a slightly updated version of your code which should run as expected.
const { conversation } = require('@assistant/conversation'); const functions = require('firebase-functions'); require('firebase-functions/lib/logger/compat'); // console.log compat const axios = require('axios'); const app = conversation({debug: true}); app.handle('getItem', async conv => { const data = await getItem(); conv.add("This test to see if we are accessing the webhook"); }); function getData() { // This returns a Promise return axios.get('https://sheetdb.io/api/v1/n3ol4hwmfsmqd'); } async function getItem() { const res = await getData() console.log(res.data); return data // To use in your Action's response } exports.ActionsOnGoogleFulfillment = functions.https.onRequest(app);