Я построил бота в диалоговом потоке и следовал указаниям по его интеграции с базой данных BigQuery, описанным в Деконструкция чат-ботов , Документация BigQuery по параметризованным запросам с Node.JS и Чат службы поддержки с BigQuery
Вызов BigQuery осуществляется в рамках асинхронной c функции ' queryParamsArrays () ', которая, по-видимому, является проблемой, основанной на журналах Firebase. ,
Я обновил пакет. json, указав "engine: 8" и / * jshint esversion: 8 * / в файле индекса, чтобы переопределить ошибку. Отходя от документации BigQuery, я подумал, что это может сработать. Желаемое поведение состоит в том, что список вин извлекается из базы данных и представляется случайным образом конечному пользователю. Вместо этого я вижу сгенерированный текст запроса SQL, и функция list_wines (которая вызывает asyn c) завершается без подстановки каких-либо значений в.
Я собираюсь попробовать переписать asyn c как обещание функция. Может кто-нибудь сказать мне, если я на правильном пути? Я новичок в javascript и пытаюсь пройти через него sh.
index. js
// See https://github.com/dialogflow/dialogflow-fulfillment-nodejs
// for Dialogflow fulfillment library docs, samples, and to report issues
'use strict';
/* jshint esversion: 8 */
const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Suggestion} = require('dialogflow-fulfillment');
const {google} = require('googleapis');
const BIGQUERY = require('@google-cloud/bigquery');
process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statements
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
const agent = new WebhookClient({ request, response });
console.log('Dialogflow Request headers: ' + JSON.stringify(request.headers));
console.log('Dialogflow Request body: ' + JSON.stringify(request.body));
console.log("Parameters", agent.parameters);
function getPair(agent) {
// Return wines that pair well with the food or meet other user specified params
const results= list_wines(agent);
agent.add('${results[0].name} is a good choice for ${results[0].food_pairing}. A ${results[1].variety} like ${results[1].name} also works!');
}
// Run the proper function handler based on the matched Dialogflow intent name
let intentMap = new Map();
intentMap.set('findPair', getPair);
agent.handleRequest(intentMap);
});
function list_wines(agent) {
// Search the database for parameters
// Actual values have been removed for presentation
const projectId = 'my_project_id';
const datasetId = "my_dataset_id";
const tableId = "my_table_id";
const bigquery = new BIGQUERY({
projectId: projectId
});
const params= agent.parameters;
const excluded= agent.excluded;
const name = agent.parameters.label;
const variety = agent.parameters.variety;
const food_pairing = agent.parameters.foods;
const conditions = agent.parameters.conditions;
// Map param columns to those in the BigQuery database
const SQL_COLUMN_LABELS={label:'name', variety:'variety', foods:'food_pairing', conditions:'food_pairing'};
var txt = "SELECT *, RANK() OVER(PARTITION BY food_pairing ORDER BY variety) as cat_count FROM \'my_project_id.my_dataset_id.my_table_id\'";
var x;
var filters=[];
// Loop through params to add search params to the SQL query removing blank arrays and empty text
// Also handles arrays with a single value or multiple values
for (x in params) {
// Correctly checking for Array
if(!Array.isArray(params[x]) & params[x].length>1 ){
// If the value is text we can reference it in the query with @
filters = filters.concat(SQL_COLUMN_LABELS[x] + "= @" + x);
} else{
switch(params[x].length) {
default:
// Array with more than one value
filters=filters.concat(SQL_COLUMN_LABELS[x] + " IN UNNEST(@" + x +")");
break;
case 1:
// Array with one value - get the actual value
filters = filters.concat(SQL_COLUMN_LABELS[x] + "= '" + params[x] +"'");
break;
case 0:
// Empty Array
break;
}
}
}
txt += " WHERE " + filters.join(" AND ");
// Prints output(the SQL query) to console
console.log(txt);
// This async function is supposed to query the database but it doesn't get called.
// list_wines completes and returns text without results
async function queryParamsArrays() {
console.log('calling queryParamsArrays');
const sqlQuery = txt +';';
console.log("SQL Query", sqlQuery);
const options = {
query: sqlQuery,
// Location must match that of the dataset(s) referenced in the query.
location: 'US',
params: params,
};
try{
// Run the query returning an array of objects
const [rows] = await bigquery.query(options);
console.log('Rows:');
rows.forEach(row => {
console.log(row)
});
// Pick ten results at random by shuffling rows
const shuffled = rows.sort(() => 0.5 - Math.random());
// Get sub-array of first 10 elements after shuffled
let selected = shuffled.slice(0, 10);
// Return selected
return selected;
} catch(e) {
console.log(e);
}
}
}
package. json
{
"name": "dialogflowFirebaseFulfillment",
"description": "This is the default fulfillment for a Dialogflow agents using Cloud Functions for Firebase",
"version": "0.0.1",
"private": true,
"license": "Apache Version 2.0",
"author": "Google Inc.",
"engines": {
"node": "8"
},
"scripts": {
"start": "firebase serve --only functions:dialogflowFirebaseFulfillment",
"deploy": "firebase deploy --only functions:dialogflowFirebaseFulfillment"
},
"dependencies": {
"actions-on-google": "^2.2.0",
"firebase-admin": "^5.13.1",
"firebase-functions": "^2.0.2",
"dialogflow": "^0.6.0",
"dialogflow-fulfillment": "^0.5.0",
"@google-cloud/bigquery": "^0.12.0"
}
}