How make Dialogflow generate a random number? - dialogflow-es

I am trying to create a bank chatbot. For creating a new bank account for the user I want it to generate a random number and make it display to the user. How to do it?

I think there are two possibility to do that. Using inline editor(cloud functions) or seperate webhooks. But as you don't need to store the account number in the session parameters then I think cloud functions will help you the most here.
Here I have create a Account intent and mapped the generateRandom function with that intent.
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": "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",
"uuid-int": "3.1.0"
}
}
index.js
'use strict';
const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Suggestion} = require('dialogflow-fulfillment');
const UUID = require('uuid-int');
process.env.DEBUG = 'dialogflow:debug'; // enables lib debugging statements
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
const agent = new WebhookClient({ request, response });
function generateRandom() {
const accountNumber =String(UUID(10).uuid()).slice(-10);
agent.add(`Your account number is ` +accountNumber);
console.log(accountNumber);
// So here we haven't stored the account number in the parameter so we can use it for the same intent only.
}
let intentMap = new Map();
intentMap.set('Account', generateRandom);
agent.handleRequest(intentMap);
});
Let me know if you face any issue.
Thanks

Related

Tell me a fix for ER_BAD_NULL_ERROR in Node.js, mysql crud operation

I am an absolute novice at Node.js. So, as I'm learning, I ran into this problem.
I am adding codes from backend for CRUD (This index.js may seem incomplete, because I faced the problem halfway and then started seeking the solution.)
package.json
{
"name": "backend",
"version": "1.0.0",
"description": "",
"main": "index.js",
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "nodemon index.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.18.2",
"mysql": "^2.18.1",
"nodemon": "^2.0.20"
}
}
index.js
import express from 'express';
import mysql from "mysql";
const app = express();
const db = mysql.createConnection({
host: "localhost",
user: "root",
password: "akdkfjdkfj;a",
database: "online_sustainability_db"
});
app.use(express.json());
app.get("/", (req, res) =>{
res.json("Hello. You are connected to backend.");
});
app.get("/data", (req, res) =>{
const query = "SELECT * FROM online_sustainability_db.idea_proposers";
db.query(query, (err, data)=>{
if(err)
return res.json(err);
else
return res.json(data);
})
});
app.post("/data", (req, res)=>{
const q = "INSERT INTO idea_proposers (`last_name`, `first_name`, `account_no`, `github_repository_link`, `submission_id`) VALUES (?, ?, ?, ?, ?)";
const last_name = req.body.last_name;
const first_name = req.body.first_name;
const account_no = req.body.account_no;
const github_link = req.body.github_repository_link;
const submission_id = req.body.submission_id;
db.query(q, [last_name, first_name, account_no, github_link, submission_id], (err, data)=>{
if(err)
return res.json(err);
else
return res.json("Provided data were recorded successfully.");
});
});
app.listen(8800, ()=>{
console.log("Connected to backend!");
});
The following image is from postman application. This is the error I am getting. Please, help me fixing it.
This is the description of the table I am trying to post the data in.
I tried doing some syntactical change and running the code several times. Well, it didn't work. I even looked for resources online, but I couldn't find any similar.
Kindly select the JSON from Postman whenever you want to send the JSON data. currently, you're sending data as a text.

Webhooks Directus 9 - send an email when user create a record in a table

I created the "mission" collection. I want to send an email to a personalized recipient for each new recording on the mission table.
According to the Directus documentation, I saw that this is possible via webHooks.
enter link description here
However, I don't quite understand the logic. Especially since in the Directus administration interface, there is a page to add webhooks and link them to the collection concerned.
Can you tell me where I should start to achieve my POC.
I also put some screenshots on the architecture of my app, you can tell me if this is really how it should be or not. I have doubts.
{
"name": "test1-directus",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "directus start"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"directus": "^9.0.0-rc.91",
"mysql": "^2.18.1",
"nodemailer": "^6.6.3"
}
}
I created a project with the command: npx create-directus-project test1directus
My project is running on port 8055 with a reverse proxy setting on nginx.
Is everything OK or did I miss a step?
Thank you in advance for your help.
I found this example to put in: extensions / hooks / sync-with-external / index.js
After several modifications, this error persists on my writing:
An error was thrown while executing hook "items.create"
Cannot destructure property 'mission' of 'undefined' as it is undefined.
The console.log doesn't show me anything.
const axios = require("axios");
module.exports = function registerHook({ services, exceptions }) {
const { MailService } = services;
const { ServiceUnavailableException, ForbiddenException } = exceptions;
return {
// Force everything to be admin-only at all times
"items.*": async function ({ item, accountability }) {
if (accountability.admin !== true) throw new ForbiddenException();
},
// Sync with external recipes service, cancel creation on failure
"items.create": async function (input, { mission, schema }) {
console.log(items);
if (mission !== "recipes") return input;
const mailService = new MailService({ schema });
try {
await axios.post("https://example.com/items", input);
await mailService.send({
to: "pseudo.pseudo#gmail.com",
template: {
name: "item-created",
data: {
collection: mission,
},
},
});
} catch (error) {
throw new ServiceUnavailableException(error);
}
input[0].syncedWithExample = true;
return input;
},
};
};
You can now use Directus Flows from Settings > Flows.
Read the docs here: https://docs.directus.io/configuration/flows

Nodemailer SMTP not working on production server

I am having issues sending email via nodemailer - SMTP(from another host) on production
i uploaded my API on a server(Scaleway Dev), i'm using Ubuntu Bionic and while testing noticed it is not sending emails(which i need for verification of a user).
at first i thought the request isn't getting to the server, but when i tried logging in i got a "confirm your password" response, i check the mongoDB database and the user is there, but still no confirmation email.
I tried checking it on localhost, thinking it might be the dotenv dependency, but it works there, what gives?
node version on my server is 8.10.0
and on my personal computer 11.12.0
these are my dependencies
enter code here
"dependencies": {
"bcrypt": "^3.0.6",
"body-parse": "^0.1.0",
"client-sessions": "^0.8.0",
"connect": "^3.6.6",
"cookie-parser": "~1.4.4",
"cors": "^2.8.5",
"debug": "~2.6.9",
"dotenv": "^8.0.0",
"express": "~4.16.1",
"express-session": "^1.16.1",
"express-validator": "^5.3.1",
"http-errors": "~1.6.3",
"moment": "^2.24.0",
"mongoose": "^5.5.8",
"morgan": "~1.9.1",
"nodemailer": "^6.1.1",
"nodemon": "^1.19.0",
"passport": "^0.4.0",
"pug": "2.0.0-beta11",
"randomstring": "^1.1.5",
"session": "^0.1.0",
"session-mongoose": "^0.5.2"
}
these options used are specified by the host that i'm using
//this is my transporter constant
const transporter = nodemailer.createTransport({
host: '*different host from the server*',
port: 465,
secure: true,
auth: {
user: my used email(hardcoded),
pass: process.env.EMAILPASS
},
tls: {
rejectUnauthorized: false
}
});
//my email options
let mailOptions ={
from: '"Company Name <noreply#*different host DNS*>',
to: req.body.email,
subject: *subject*
html: `Email Content with confirmation token`
}
//emailing the message itself
transporter.sendMail(mailOptions, (err, info) => {
if(err){
return console.log(err);
}
console.log("message sent");
});
i'm using this email generator(https://generator.email/) for fast throwaway emails. the mailing starts after i save the user.
I'm perplexed as to what should i do... any and all help is appreciated
I have had issues with nodemailer in the past. I'm using mailgun (https://www.mailgun.com/) to send my emails. They offer 10,000 emails a month for free. Here is a code that works with mailgun:
dependencies:
"express": "4.16.4",
"config": "3.0.1",
"nodemailer": "5.1.1",
"nodemailer-mailgun-transport": "1.4.0"
code (it is wrapped inside an express router) :
const config = require('config');
const nodemailer = require('nodemailer');
const mg = require('nodemailer-mailgun-transport');
const express = require('express');
const router = express.Router();
router.post('/', async (req, res) => {
//the data has to be an array. It will send as many emails as the number of items in the array
var emailsList = ["test#test.com"];
emailsList[0].name = "Test Name";
var auth = {
auth: {
api_key: config.get('mailgunApiKey'),
domain: config.get('mailgunDomain')
}
};
transporter = nodemailer.createTransport(mg(auth)),
EmailTemplate = require('email-templates').EmailTemplate,
path = require('path'),
Promise = require('bluebird');
function sendEmail (obj) {
return transporter.sendMail(obj);
}
function loadTemplate (templateName, contexts) {
let template = new EmailTemplate(path.join(__dirname, '../templates', templateName));
return Promise.all(contexts.map((context) => {
return new Promise((resolve, reject) => {
template.render(context, (err, result) => {
if (err) reject(err);
else resolve({
email: result,
context,
});
});
});
}));
}
loadTemplate('dailyReferralEmail', emailsList).then((results) => {
return Promise.all(results.map((result) => {
sendEmail({
to: result.context.email,
from: 'Your Name <your-email#test.com>',
'h:Reply-To': 'your-email#test.com',
subject: result.email.subject,
html: result.email.html,
text: result.email.text,
});
}));
}).then(() => {
var response = {
text: "Email sent"
}
JSON.stringify(response);
res.status(200).send(response);
});
});
module.exports = router;
As a template generator, I'm using HBS. So you must have a templates folder in the root folder of your project, with this tree:
You can use your variables inside your email with {{ }}.
Inside html.hbs:
<p>Hello {{name}}</p>
Inside subject.hbs
Subject of your email
Inside text.hbs
Preview text of your email
Hope this helps!

Firebase function for nodemailer deployed but no logs and not working correctly with database

I have setup a firebase-function with nodemailer to grab the input from my
firebase-database connected to my contact form and email it to my email.
I have successfully deployed the function and can see the function showing up in my firebase console, however i do not receive any errors in the console nor see any logs or information in the function section of the console. And it just simply doesn't work right now.
This is the first time i am doing this, and i have looked at almost all other similar questions on SO but none of them have given me any clues as to what i am doing wrong.
This is my functions package.json:
{
"name": "functions",
"description": "Cloud Functions for Firebase",
"scripts": {
"lint": "eslint .",
"serve": "firebase serve --only functions",
"shell": "firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"engines": {
"node": "8"
},
"dependencies": {
"firebase-admin": "~7.0.0",
"firebase-functions": "^2.3.0",
"nodemailer": "^6.1.1"
},
"devDependencies": {
"eslint-plugin-promise": "^4.0.1",
"firebase-functions-test": "^0.1.6"
},
"private": true
}
and this is the index.js code inside the functions-folder:
const functions = require("firebase-functions");
const admin = require("firebase-admin");
const nodemailer = require("nodemailer");
const gmailEmail = "k****l#gmail.com";
const gmailPassword = functions.config().gmail.pass;
admin.initializeApp();
var goMail = function(message) {
const transporter = nodemailer.createTransport({
service: "gmail",
auth: {
user: gmailEmail,
pass: gmailPassword
}
});
const mailOptions = {
from: gmailEmail, // sender address
to: "****l#gmail.com", // list of receivers
subject: "!", // Subject line
text: "!" + message, // plain text body
html: "!" + message // html body
};
const getDeliveryStatus = function(error, info) {
if (error) {
return console.log(error);
}
console.log("Message sent: %s", info.messageId);
};
transporter.sendMail(mailOptions, getDeliveryStatus);
};
exports.onDataAdded = functions.database
.ref("/messages/{messageId}")
.onCreate(function(snap, context) {
const createdData = snap.val();
var name = createdData.name;
var email = createdData.email;
var number = createdData.number;
var message = createdData.message;
goMail(name, email, number, message);
});
I'm not sure if my setup is wrong or if I'm doing something wrong with the nodemailer code in index.js.
Thanks for the help in advance.
As explained in the comment, since your Cloud Function is triggered by a background event, you must return a promise to indicate that the asynchronous tasks are finished.
So in the goMail function you should return the promise returned by the sendMail() method with:
...
return transporter.sendMail(mailOptions); //Remove the callback
And you should return, in the Cloud Function itself, the promise returned by the goMail function with:
return goMail(...)

How can I use SSML in Dialogflow Fullfilment (Dutch language)

is there a simple way to use SSML in the Fullfilment section using Actions-on-google functions. I tried all sorts of coding, but no good results. I'm using Dutch as default language.
In below example, Google Assistant is spelling each '<' etc.:
// Handle the Dialogflow intent named 'favorite color'.
// The intent collects a parameter named 'color'.
app.intent('favoriete kleur', (conv, {color}) => {
const luckyNumber = color.length;
const audioSound = 'https://www.example.com/MY_MP3_FILE.mp3'; // AoG currently only supports MP3!
if (conv.user.storage.userName) {
conv.ask(`<speak>${conv.user.storage.userName}, je geluksnummer is ${luckyNumber}<audio src="${audioSound}"><desc>Geluid wordt afgespeeld</desc></audio></speak>`); // Audio should have description
conv.ask(new Suggestions('Paars', 'Geel', 'Oranje'));
} else {
conv.ask(`<speak>Je geluksnummer is ${luckyNumber}<audio src="${audioSound}"><desc>Geluid wordt afgespeeld</desc></audio></speak>`);
conv.ask(new Suggestions('Paars', 'Geel', 'Oranje'));
}
});
Please find below the environment settings:
Index.js initiation settings:
'use strict';
// Import the Dialogflow module and response creation dependencies
// from the Actions on Google client library.
const {
dialogflow,
BasicCard,
Permission,
Suggestions,
Carousel,
MediaObject,
SimpleResponse,
Table,
Button
// Image,
} = require('actions-on-google');
// Import the firebase-functions package for deployment.
const functions = require('firebase-functions');
// Instantiate the Dialogflow client.
const app = dialogflow({debug: true});
package.json:
{
"name": "codelab-level-three",
"description": "Actions on Google Codelab Level 3",
"author": "Google Inc",
"private": true,
"scripts": {
"lint": "eslint .",
"serve": "firebase serve --only functions",
"shell": "firebase experimental:functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"dependencies": {
"actions-on-google": "^2.0.0",
"firebase-admin": "~5.8.1",
"firebase-functions": "^0.8.1",
"i18n": "^0.8.3"
},
"devDependencies": {
"eslint": "^4.19.0",
"eslint-config-google": "^0.9.1"
}
}
The produced payload looks like this:
"status": 200,
"headers": {
"content-type": "application/json;charset=utf-8"
},
"body": {
"payload": {
"google": {
"expectUserResponse": true,
"richResponse": {
"items": [
{
"simpleResponse": {
"textToSpeech": "<speak>Paul, je geluksnummer is 5<audio src=\"https://www.example.com/MY_MP3_FILE.mp3\"><desc>Geluid wordt afgespeeld</desc></audio></speak>"
}
}
],
"suggestions": [
{
"title": "Paars"
},
{
"title": "Geel"
},
{
"title": "Oranje"
}
]
}
}
}
}
}
The most likely issue is that you're not including a closing </speak> tag. So you should probably write it as something like
conv.ask(`<speak>Je geluksnummer is ${luckyNumber}.` +
`<audio src="${audioSound}"></audio></speak>`);
The answer to my problem was easy: just read the f...ing manual. :-) Although both .OGG as also .MP3 are supported the website should provide HTTPS. Website which are not secured (like HTTP) are not supported. Below you can find the example function how you can test:
app.intent('favoriete muziek', conv => {
const Optie = conv.parameters.optie;
//Taalspecifieke meldingen
const SoundLib =
{
'1': {
description : 'Simple sound using .ogg',
audiosound : 'https://actions.google.com/sounds/v1/alarms/alarm_clock.ogg',
audiotext : 'You should hear an audio alarm signal',
},
'2': {
description : 'Music MP3 via HTTP',
audiosound : 'http://storage.googleapis.com/automotive-media/Jazz_In_Paris.mp3',
audiotext : 'You should hear a Jazz record called "Jazz in Paris" ',
},
'3': {
description : 'Longer MP3 file via HTTP',
audiosound : 'http://www.navyband.navy.mil/anthems/anthems/netherlands.mp3',
audiotext : 'You should hear now the Dutch National Anthem',
},
'4': {
description : 'short MP3 audio via HTTPS',
audiosound : 'https://ia802508.us.archive.org/5/items/testmp3testfile/mpthreetest.mp3',
audiotext : 'You should hear a short spoken intro text',
},
};
const Sound = SoundLib[Optie];
var spraakzin = "<speak>This text is using <say-as interpret-as='verbatim'>SSML</say-as> followed by an audio file in a SimpleResponse box: <audio src='" + Sound.audiosound + "'>The audio file could not be processed</audio></speak>";
if (!conv.surface.capabilities.has("actions.capability.MEDIA_RESPONSE_AUDIO")) {
conv.ask("Media response via audio is not supported on this device.");
return;
}
conv.ask(new SimpleResponse({
speech: spraakzin,
text: Sound.audiotext,
}));
});
More info can be found here: SSML examples - look at prerequisites of AUDIO
to add up to what Prisoner already said, there are some other problems.
app.intent('favoriete kleur', (conv, {color}) => {
const luckyNumber = color.length;
const audioSound = 'https://actions.google.com/sounds/v1/cartoon/clang_and_wobble.mp3'; // AoG currently only supports MP3!
if (conv.user.storage.userName) {
conv.ask(`<speak>${conv.user.storage.userName}, je geluksnummer is <audio src="${audioSound}"><desc>${luckyNumber}</desc></audio></speak>`); // Audio should have description
conv.ask(new Suggestions('Paars', 'Geel', 'Oranje'));
} else {
conv.ask(`<speak>Je geluksnummer is <audio src="${audioSound}"><desc>${luckyNumber}</desc></audio></speak>`);
conv.ask(new Suggestions('Paars', 'Geel', 'Oranje'));
}
});
AoG currently only support MP3 as audio format. See https://developers.google.com/actions/assistant/responses#media_responses Sorry, I was wrong. This only goes for Media Responses, NOT for embedded audio in SSML.
I removed concatenations in the code above. That's contraproductive and makes things more difficult to read than necessary. (Opinionated)
Audio output - when not only outputting a soundeffect, but text - should contain a description which will also be printed on the screen. The example in the code supplied should be okay.
But yes, what's the cause of your original problem is, is that you're not closing the audio tags. Actions on Google are pretty unforgiving concerning unclosed tags.
Hope that helped.

Resources