My Dialogflow chatbot refuses to deploy JavaScript fulfillment code - javascript

Dialogflow, and Google Cloud Console, refuses to publish my fulfillment code that I made on the Inline Editor.
Here is a code snippet from my index.js file:
'use strict';
const functions = require('firebase-functions');
const {google} = require('googleapis');
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Suggestion} = require('dialogflow-fulfillment');
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));
function Weather(agent) {
const state = agent.parameters['geo-state-us'];
const city = agent.parameters['geo-city-us'];
agent.add(`The weather in ${city}, ${state} is fine and mild.`);
}
let intentMap = new Map();
intentMap.set('AskCity', Weather);
agent.handleRequest(intentMap);
});
function welcome(agent) {
agent.add(`Welcome to my agent!`);
}
function fallback(agent) {
agent.add(`I didn't understand`);
agent.add(`I'm sorry, can you try again?`);
}
// // Uncomment and edit to make your own intent handler
// // uncomment `intentMap.set('your intent name here', yourFunctionHandler);`
// // below to get this function to be run when a Dialogflow intent is matched
// function yourFunctionHandler(agent) {
// agent.add(`This message is from Dialogflow's Cloud Functions for Firebase editor!`);
// agent.add(new Card({
// title: `Title: this is a card title`,
// imageUrl: 'https://developers.google.com/actions/images/badges/XPM_BADGING_GoogleAssistant_VER.png',
// text: `This is the body text of a card. You can even use line\n breaks and emoji! 💁`,
// buttonText: 'This is a button',
// buttonUrl: 'https://assistant.google.com/'
// })
// );
// agent.add(new Suggestion(`Quick Reply`));
// agent.add(new Suggestion(`Suggestion`));
// agent.setContext({ name: 'weather', lifespan: 2, parameters: { city: 'Rome' }});
// }
// // Uncomment and edit to make your own Google Assistant intent handler
// // uncomment `intentMap.set('your intent name here', googleAssistantHandler);`
// // below to get this function to be run when a Dialogflow intent is matched
// function googleAssistantHandler(agent) {
// let conv = agent.conv(); // Get Actions on Google library conv instance
// conv.ask('Hello from the Actions on Google client library!') // Use Actions on Google library
// agent.add(conv); // Add Actions on Google library responses to your agent's response
// }
// // See https://github.com/dialogflow/fulfillment-actions-library-nodejs
// // for a complete Dialogflow fulfillment library Actions on Google client library v2 integration sample
// Run the proper function handler based on the matched Dialogflow intent name
let intentMap = new Map();
intentMap.set('Default Welcome Intent', welcome);
intentMap.set('Default Fallback Intent', fallback);
// intentMap.set('your intent name here', yourFunctionHandler);
// intentMap.set('your intent name here', googleAssistantHandler);
agent.handleRequest(intentMap);
});
And here is my package.json file:
{
"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": "10"
},
"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"
}
}
Whenever I edit the code, and I try to deploy it, it says "error happened during Cloud Functions deployment". When I tried to download it, it said this:
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<Error>
<Code>NoSuchKey</Code>
<Message>The specified key does not exist.</Message>
<Details>No such object: gcf-sources-647212949737-us-central1/dialogflowFirebaseFulfillment-37ed71f1-69e0-4830-8ada-26d947fa10b3/version-10/function-source.zip</Details>
</Error>
I can't figure out why, I have tried many times to figure out how to edit it on Google Cloud Console, and there appear to be no guides that know how to fix this problem.
Update: Dialogflow still refuses to deploy code after more necessary updates are attempted to be installed to JavaScript fulfillment code to be able to run other functions and commands.
Update: I tried to get Dialogflow to integrate from Firebase using a webhook. Firebase refuses to deploy code, will not even publish a new file under a different name and configuration. Maybe it has something to do with billing issues, though I did not remove any of my billing information.
Update: Disabled billing information, attempted to force Firebase and Google Cloud to reinitialize billing. Still refuses to deploy code.
Update: As of now, my outlook for deploying code seems pretty hopeless. I cannot make Dialogflow, Firebase, and Google Cloud Console deploy the code which allows me to manipulate the bot I am trying to make.
Update: As I cannot deploy code, I cannot do the new functions that I am trying to implement. They are necessary for a new function of the bot, and, because I cannot deploy fulfillment code, it has made it impossible to use and make that new function.
Update: My ignorant self didn't realize that part of the problem was the execution point. It was not executing from the function dialgflowFirebaseFulfillment and thus refused to deploy because it was not detecting an executable function within the code. Problem was resolved by deleting code and creating a whole new fulfillment file.
Thanks to all those out there that helped me resolve this issue!

This might help you from markussvensson`s answer on a similar issue.
Adding a hint for the next soul running into this problem. It seems to be caused by missing/inaccessible file in the restore/rollback process.
I was successfully removing the problem by simply:
Deleting my functions using the web firebase console.
Deploying normally again >firebase deploy

Related

unable to deploy functions to Firebase

I am trying to deploy Firebase Functions from xcode using this tutorial - https://firebase.google.com/docs/functions/get-started. This is my index.js -
'use-strict'
// The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
const functions = require('firebase-functions');
// The Firebase Admin SDK to access Firestore.
const admin = require('firebase-admin');
admin.initializeApp();
// Take the text parameter passed to this HTTP endpoint and insert it into
// Firestore under the path /messages/:documentId/original
exports.addMessage = functions.https.onRequest(async (req, res) => {
// Grab the text parameter.
const original = req.query.text;
// Push the new message into Firestore using the Firebase Admin SDK.
const writeResult = await admin.firestore().collection('messages').add({original: original});
// Send back a message that we've successfully written the message
res.json({result: `Message with ID: ${writeResult.id} added.`});
});
// Listens for new messages added to /messages/:documentId/original and creates an
// uppercase version of the message to /messages/:documentId/uppercase
exports.makeUppercase = functions.firestore.document('/messages/{documentId}')
.onCreate((snap, context) => {
// Grab the current value of what was written to Firestore.
const original = snap.data().original;
// Access the parameter `{documentId}` with `context.params`
functions.logger.log('Uppercasing', context.params.documentId, original);
const uppercase = original.toUpperCase();
// You must return a Promise when performing asynchronous tasks inside a Functions such as
// writing to Firestore.
// Setting an 'uppercase' field in Firestore document returns a Promise.
return snap.ref.set({uppercase}, {merge: true});
});
After I run either of the commands "firebase deploy --only functions" or "firebase deploy --only functions:addMessage", it shows message -
"✔ Deploy complete!
I don't see the functions deployed in the firebase console and it shows message - Project Console: https://console.firebase.google.com/project/testpro-92351/overview
Apples-MacBook-Air:Fireupgoodsa apple$".
but I expect to see "Function URL (addMessage): https://us-central1-MY_PROJECT.cloudfunctions.net/addMessage".
Note that:-
My app name is "Fireupgoodsa" under the project "testpro-92351".
I have activated the blaze plan.
Firestore is working fine.
What am I missing out on ?
I have also other question, slightly related - I am trying to link Firestore to Stripe-Payments Is it necessary to deploy functions to Firebase ?
Thanks,

Firestore function deployment error when using Twilio

I'm trying to integrate Twilio into a triggered Firestore function. The problem I'm having is when I add this code, I am unable to deploy ANY functions. As far as I know this is how to use twilio inside a cloud function. At the top I have this and I think firebase doesn't like something here because ALL functions stop deploying with this code.
// Used to send text messages
const twilio = require('twilio')
// const accountSid = functions.config().twilio.sid
// const authToken = functions.config().twilio.token
/* eslint new-cap: ["error", { "newIsCap": false }] */
const client = new twilio('ACblahblahblah', 'ccblahblahblah') // sid and token
const twilioNumber = '+13344714571' // your twilio phone number
Within the triggered function I have this. But I don't think the issue is here:
return client.messages.create({
to: someNumber,
from: twilioNumber,
body: 'Some message.'
}).then((data) => {
console.log(data)
}).catch((error) => {
console.log(error)
})
I have a valid Twilio account set up. The function logs don't tell me much other than that the function cannot be initialized. What am I missing? Seems like this has worked for others.
Figured it out about 5 minutes after posting the question. I had not installed twilio in the functions folder but rather the root of the project. Once I executed
npm install twilio
in the functions folder, the functions started deploying. Too bad there was no error in the logs that said something like "required package is missing" or something like that.

sending push notification using firebase functions every time a new child is added in firebase realtime database is not working

I am trying to send a push notification every time a child is created with no success.
I am creating a child with 2 token names with a question mark between them and trying to send to those tokens the notification.
to get the tokens from the phones I am using
new FirebaseMessaging().getToken() .
here is the firebase functions code
`
// // Create and Deploy Your First Cloud Functions
// // https://firebase.google.com/docs/functions/write-firebase-functions
//
// exports.helloWorld = functions.https.onRequest((request, response) => {
// response.send("Hello from Firebase!");
// });
// The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
const functions = require('firebase-functions');
// The Firebase Admin SDK to access Cloud Firestore.
const admin = require('firebase-admin');
admin.initializeApp();
exports.onNewMessage = functions.database.
ref('/messages/{pushId}')
.onCreate((snapShot,context)=>{
var str = snapShot.key();
var res = str.split("?");
// Notification details.
const payload = {
notification: {
title: 'title!',
body: `body!`,
click_action: 'FLUTTER_NOTIFICATION_CLICK'
}
};
// Send notifications to all tokens.
admin.messaging().sendToDevice(res[0], payload);
admin.messaging().sendToDevice(res[1], payload);
});` .
This may have many if-thens, but I will describe here the most common sources of errors
1) Did not grant permissions for notifications for iOS/Android platform. For Android it is fine, and relatively easy to receive notifications, but for iOS you need Developer account to do that (on December 2019 it was 99$ per year)
2) I would recommend using topic subscription instead of tokenization (i.e. .getToken()) as it removes burden of following every single sent message manually
For example:
final fbmsg = FirebaseMessaging();
fbmsg.requestNotificationPermissions();
fbmsg.configure(onMessage: (msg) {
print(msg);
return;
}, onLaunch: (msg) {
print(msg);
return;
}, onResume: (msg) {
print(msg);
return;
});
fbmsg.subscribeToTopic('chats');
You can configure onLaunch, onResume, and onMessage behaviors on your own demand
For (1) and (2), a great place to start is following documentation of firebase_messaging library
3) I am not sure about this, but I think a better way to use index.js file could be using the snapshot that you receive (or at least try console.log() of whatever you get to check validity). But if it works for you, just ignore this step :) Below I attach the code from my app with working notifications
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
exports.myFunction = functions.firestore
.document('chats/{message}')
.onCreate((snapshot, context) => {
return admin.messaging().sendToTopic('chats', {
notification: {
title: snapshot.data().username,
body: snapshot.data().text,
clickAction: 'FLUTTER_NOTIFICATION_CLICK'
},
});
});
4) I had hard time with establishing this Firebase Functions feature, also check installation steps for them as well
5) Check how you are trying to send the notification, first try to simulate it from the console, make sure that receiving part works, and then try to create an automated one
Hope it helped!

Firebase function says deployed but won't show up in Firebase Console

I'm trying to add a notification feature to my app so that once a user makes a post anyone subscribed to them will be notified. Currently I'm trying to write a cloud function to accomplish this.
However, writing a small test fails to be deployed to my project.
Note:If anyone has links for how to accomplish something like this for Flutter it would be greatly appreciated.
I've looked at the few examples I could find and the trend has been something wrong in the js code but I can't see any.
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
exports.sendNotification =
functions.firestore.document('Orders/{resturantId}/Orders')
.onWrite((change, context) =>{
const notificationContent = {
notification:{
title: "/*App name */",
body: "You have a new Comment!",
icon: "default",
click_action: "/*Package */_TARGET_NOTIFICATION"
}
};
return admin.messaging().sendToTopic("-LV_05ip0wf1dFEg45wx", notificationContent)
.then(result => {
console.log("Notification sent!");
return;
});
});
Being unfamiliar with the environment I didn't realize I selected type script when initializing the firebase function. So instead of index.js I should've been using index.ts.
Furthermore, a correct function deploy actually looks like this.

nodejs-dialogflow library returning TypeError: dialogflow.SessionsClient is not a constructor

I am trying to make a script that takes input from the user, runs it through Dialogflow, then returns it back to the user. The platform I am taking input from only supports Node.js. I am hosting the bot through glitch.com, but I don't think that's what's causing the issue. I wanted to check on here before I submit a bug report onto the GitHub repo.
var bot = 'the platform i use to accept inputs and send outputs'
bot.on("message", async message => {
console.log(message.content); // Log chat to console for debugging/testing
if (message.content.indexOf(config.prefix) === 0) { // Message starts with your prefix
let msg = message.content.slice(config.prefix.length); // slice of the prefix on the message
let args = msg.split(" "); // break the message into part by spaces
let cmd = args[0].toLowerCase(); // set the first word as the command in lowercase just in case
args.shift(); // delete the first word from the args
// You can find your project ID in your Dialogflow agent settings
const projectId = process.env.PROJECT_ID; //https://dialogflow.com/docs/agents#settings
const sessionId = 'quickstart-session-id';
var query = msg;
const languageCode = 'en-US';
// Instantiate a DialogFlow client.
const dialogflow = require('dialogflow');
const sessionClient = new dialogflow.SessionsClient();
// Define session path
const sessionPath = sessionClient.sessionPath(projectId, sessionId);
// The text query request.
const request = {
session: sessionPath,
queryInput: {
text: {
text: query,
languageCode: languageCode,
},
},
};
// Send request and log result
sessionClient
.detectIntent(request)
.then(responses => {
console.log('Detected intent');
const result = responses[0].queryResult;
console.log(` Query: ${result.queryText}`);
console.log(` Response: ${result.fulfillmentText}`);
if (result.intent) {
console.log(` Intent: ${result.intent.displayName}`);
} else {
console.log(` No intent matched.`);
}
})
.catch(err => {
console.error('ERROR:', err);
});
}
return;
});
That is the relevant part of the code. For those wondering, the process.env.PROJECT_ID is something glitch.com uses for anything private. Because I don't want random people getting their hands on my project id, I hide it in there and glitch hides it from anyone I don't explicitly invite.
Every time I execute this and try to query the bot, it returns an error Uncaught Promise Error: TypeError: dialogflow.SessionsClient is not a constructor.
If someone can direct me to what I'm missing, or what the problem is, that would be great!
As per #google-cloud/dialogflow - npm
IMPORTANT NOTE
Version 2.0.0 renames dialogflow to #google-cloud/dialogflow on npm, along with introducing TypeScript types.
So to update the dialogflow to use latest version, first uninstall dialogflow and then install with following command:
npm uninstall dialogflow
npm i #google-cloud/dialogflow
Also, if you were using older version 1.2.0 of dialogflow before then in code, make following changes as per their sample or refer the sample from above link (in require and to get the sessionPath):
const dialogflow = require('#google-cloud/dialogflow');
const sessionPath = sessionClient.projectAgentSessionPath(
projectId,
sessionId
);
It worked fine for me after doing this without any errors.
I figured it out. After many many refreshes, I decided to look at the npm documentation for it. Turns out some idiot listed the earliest version as 4.0.3, and the latest version as 0.7.0. I needed to explicitly tell it to use version 0.7.0 in order for it to work. Thank goodness!
Mine worked by reinstalling the dialogflow package
npm uninstall dialogflow
npm install dialogflow --save
put the code inside try and catch block. In my case by doing this, this error was removed.

Categories

Resources