Skip to content
Advertisement

While developing a voice agent, I am using axios to get data from a spreadsheet. However, I cannot get all data at once

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);
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement