Update Dialogflow "Transfer Call" field from backend ( Node.js ) - dialogflow-es

I try to update phone number in "Transfer Call" field under "Responses" tab ("TELEPHONY" -> "ADD RESPONSES" button ) for given intent using Node.js but I cannot.
New update removes old "Transfer Call" field with the old phone number (which I created by hand in console for testing purposes)
Please help
Here is example code:
const dialogflow = require('dialogflow')
const intentsClient = new dialogflow.IntentsClient({ keyFilename: 'key.json' })
const fulfillmentMessages = [ { platform: 'TELEPHONY',
telephonySynthesizeSpeech: { text: 'Hello World' } },
{ platform: 'TELEPHONY',
telephonyTransferCall: { phoneNumber: '+12132954242' } },
{ text: { text: [ '' ] } } ]
const intent = {
name: 'projects/example/agent/intents/2ef3e0b6-6cd7-4d5b-a8ca-ce11111125e019',
displayName: 'Test',
fulfillmentMessages: fulfillmentMessages
}
const updateIntentRequest = { intent: intent }
intentsClient.updateIntent(updateIntentRequest).then((data) =>{ console.log(data)}, (e) => {
console.log(e) })

Detailed response can be found here however heres the correct code sample (tested and working)
const dialogflow = require('dialogflow');
const intentsClient = new dialogflow.v2beta1.IntentsClient({ keyFilename: 'key.json' }) //Note that dialogflow will be using v2beta1 api
const message_to_set = [
{
platform: 10,
telephonySynthesizeSpeech: {
text : 'Hello World'
},
telephonyTransferCall: {
phoneNumber: '+12132954242'
}
}
]
const intent = {
name: 'projects/example/agent/intents/2ef3e0b6-6cd7-4d5b-a8ca-ce11111125e019',
displayName: 'Forward',
messages: message_to_set //Note parameter was switched from fulfillmentMessages to messages
}
const updateIntentRequest = { intent: intent }
intentsClient.updateIntent(updateIntentRequest).then((data) =>{ console.log(data)}, (e) => { console.log(e) })

Related

How to pass additional params to Stripe Custom Flow?

Following Stripes official tutorial to create payment form with apple pay support: https://stripe.com/docs/payments/quickstart#collect-billing-address-details
But on thank you page, i need to know: user email and stripe customer id. How i can pass these parameters to thank you page?
My code for prepare.php:
$productID = $request['items'][0]['id'];
$customer = \Stripe\Customer::create();
$paymentIntent = \Stripe\PaymentIntent::create([
'customer' => $customer->id,
'setup_future_usage' => 'off_session',
'amount' => config('app.PRICE_TNT6WEEK') * 100, //6week program
'currency' => 'usd',
'automatic_payment_methods' => [
'enabled' => true,
],
'description' => $productID,
]);
$output = [
'clientSecret' => $paymentIntent->client_secret,
];
\Log::debug(['<pre>'.print_r($request->toArray(), true).'</pre>', $productID, $output]);
return response()->json($output);
My checkout.js:
// This is your test publishable API key.
const stripe = Stripe('{{config('app.STRIPE_KEY')}}');
// The items the customer wants to buy
const items = [{ id: "{{$productName}}"}];
let elements;
initialize();
checkStatus();
document
.querySelector("#payment-form")
.addEventListener("submit", handleSubmit);
// Fetches a payment intent and captures the client secret
async function initialize() {
const { clientSecret } = await fetch("{{route('prepare.product', [$slug, $slugVersion])}}", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ items }),
}).then((r) => r.json());
elements = stripe.elements({ clientSecret });
const paymentElementOptions = {
layout: "tabs",
};
const paymentElement = elements.create("payment", paymentElementOptions);
paymentElement.mount("#payment-element");
// Create and mount the Address Element in billing mode
const addressElement = elements.create("address", {
mode: "billing",
defaultValues: {
name: 'Your Full Name...',
address: {
line1: 'Address...',
city: 'City...',
state: 'CA',
postal_code: '',
country: 'US',
},
},
fields: {
phone: 'always',
},
});
addressElement.mount("#address-element");
}
async function handleSubmit(e) {
e.preventDefault();
setLoading(true);
//--- There we should make an additional ajax request with user data
const { error } = await stripe.confirmPayment({
elements,
confirmParams: {
// Make sure to change this to your payment completion page
return_url: "{{route('upsell.show', [$slug, $slugVersion])}}",
payment_method_data: {
billing_details: {
name: document.getElementById("full_name").value,
email: document.getElementById("email").value,
phone: document.getElementById("phone").value,
}
},
},
});
// This point will only be reached if there is an immediate error when
// confirming the payment. Otherwise, your customer will be redirected to
// your `return_url`. For some payment methods like iDEAL, your customer will
// be redirected to an intermediate site first to authorize the payment, then
// redirected to the `return_url`.
if (error.type === "card_error" || error.type === "validation_error") {
showMessage(error.message);
} else {
showMessage("An unexpected error occurred.");
}
setLoading(false);
}
// Fetches the payment intent status after payment submission
async function checkStatus() {
const clientSecret = new URLSearchParams(window.location.search).get(
"payment_intent_client_secret"
);
if (!clientSecret) {
return;
}
const { paymentIntent } = await stripe.retrievePaymentIntent(clientSecret);
switch (paymentIntent.status) {
case "succeeded":
showMessage("Payment succeeded!");
break;
case "processing":
showMessage("Your payment is processing.");
break;
case "requires_payment_method":
showMessage("Your payment was not successful, please try again.");
break;
default:
showMessage("Something went wrong.");
break;
}
}
// ------- UI helpers -------
function showMessage(messageText) {
const messageContainer = document.querySelector("#payment-message");
messageContainer.classList.remove("hidden");
messageContainer.textContent = messageText;
setTimeout(function () {
messageContainer.classList.add("hidden");
messageText.textContent = "";
}, 4000);
}
// Show a spinner on payment submission
function setLoading(isLoading) {
if (isLoading) {
// Disable the button and show a spinner
document.querySelector("#submit").disabled = true;
document.querySelector("#spinner").classList.remove("hidden");
document.querySelector("#button-text").classList.add("hidden");
} else {
document.querySelector("#submit").disabled = false;
document.querySelector("#spinner").classList.add("hidden");
document.querySelector("#button-text").classList.remove("hidden");
}
}
After collecting billing details with either the Address Element, or supplying the payment_method_data[billing_details], that information will be available on Payment Method billing_details (API ref). You can get this by either retrieving the Payment Method, or by retrieving the associated Payment Intent and using expansion to include the full Payment Method object with expand[]=payment_method

How to make kuzzle-device-manager plugin API actions works?

I successfully installed and loaded kuzzle-device-manager in the backend file:
import { Backend } from 'kuzzle';
import { DeviceManagerPlugin } from 'kuzzle-device-manager';
const app = new Backend('playground');
console.log(app.config);
const deviceManager = new DeviceManagerPlugin();
const mappings = {
updatedAt: { type: 'date' },
payloadUuid: { type: 'keyword' },
value: { type: 'float' }
}
deviceManager.devices.registerMeasure('humidity', mappings)
app.plugin.use(deviceManager)
app.start()
.then(async () => {
// Interact with Kuzzle API to create a new index if it does not already exist
console.log(' started!');
})
.catch(console.error);
But when i try to use controllers from that plugin for example device-manager/device with create action i get an error output.
Here is my "client" code in js:
const { Kuzzle, WebSocket } = require("kuzzle-sdk")
const kuzzle = new Kuzzle(
new WebSocket('KUZZLE_IP')
)
kuzzle.on('networkError', error => {
console.error('Network Error: ', error);
})
const run = async () => {
try {
// Connects to the Kuzzle server
await kuzzle.connect();
// Creates an index
const result = await kuzzle.query({
index: "nyc-open-data",
controller: "device-manager/device",
action: "create",
body: {
model: "model-1234",
reference: "reference-1234"
}
}, {
queuable: false
})
console.log(result)
} catch (error) {
console.error(error.message);
} finally {
kuzzle.disconnect();
}
};
run();
And the result log:
API action "device-manager/device":"create" not found
Note: The nyc-open-data index exists and is empty.
We apologize for this mistake in the documentation, the device-manager/device:create method is not available because the plugin is using auto-provisioning until the v2.
You should send a payload to your decoder, the plugin will automatically provision the device if it does not exists https://docs.kuzzle.io/official-plugins/device-manager/1/guides/decoders/#receive-payloads

How to intergrate lex with lambda in amazon aws?

I have a simple bot with the following logic.
Bot: select one of the following item your interested
(response card)
-ecommerce
-travel etc
Human : clicks eg travel
Bot: response card
-marketing
-digital
Here is what I have in my lambda function
'use strict';
exports.handler = (event, context, callback) => {
const sessionAttributes = event.sessionAttributes;
const slots = event.currentIntent.slots;
const videommerceType = slots.videommerceType;
// predefined list of available pizza
const validData = ['ecommerce', 'startup', 'lead generation', 'crm', 'travel'];
// negative check: if valid slot value is not obtained, inform lex that user is expected
// respond with a slot value
if (videommerceType && !(videommerceType === "") && validData.indexOf(videommerceType.toLowerCase()) === -1) {
let response = {
sessionAttributes: event.sessionAttributes,
dialogAction: {
type : "'ElicitSlot",
message: {
contentType: "PlainText or SSML",
content: "Message to convey to the user. For example, Thanks, your pizza has been ordered."
},
responseCard: {
version: "1",
contentType: "application/vnd.amazonaws.card.generic",
genericAttachments: [{
title: "card-title",
subTitle: "card-sub-title",
imageUrl: "URL of the image to be shown",
attachmentLinkUrl: "URL of the attachment to be associated with the card",
buttons: [{
text: "button-text",
value: "Value sent to server on button click"
}]
}]
}
}
}
callback(null, response);
}
let response = {
sessionAttributes: sessionAttributes,
dialogAction: {
type: "Delegate",
slots: event.currentIntent.slots
}
}
callback(null, response);
};
Unfortunately this not working, on lex bot I get the following error
Intent videommerceIntent is ReadyForFulfillment: name:jim videommerceType:ecommerce
What is wrong with my code? any help or similar working demo would be appreciated , thanks

How to export and import functions for telegrams bot?

I'm create a bot telegram with two buttons. On each button I want to hang the action. I want to transfer these actions to another file. How can I do that?
const Telegraf = require("telegraf");
const session = require("telegraf/session");
const Composer = require('telegraf/composer');
const bot = new Telegraf('Token')
const first = require('./command/first');
bot.command('start', (ctx) => {
const markdown = `
Hi! Click on the button 1 or 2!`;
ctx.telegram.sendMessage(ctx.message.chat.id, markdown, {
parse_mode: 'Markdown',
reply_markup: {
keyboard: [
['1', '2'],
],
resize_keyboard: true
},
disable_notification: false
});
});
bot.use(session());
bot.use(Telegraf.log())
bot.on('1', first.hears()) ///myfunction command
bot.startPolling();
console.log(Telegraf.log());
and file ./command/first
module.exports = {
hears: function () {
console.log("debug 1");
bot.action('1', (ctx) => {
const markdown = ` Type some text...`;
ctx.telegram.sendMessage(ctx.message.chat.id, markdown, {
parse_mode: 'Markdown',
reply_markup: {
keyboard: [
['🔙 Back'],
],
resize_keyboard: true
},
disable_notification: false
});
})
}
};
but nothing works. When starting the bot writes immediately debug 1
And nothing.. Help me please!
Firstly Change:
bot.on('1', first.hears()) // on is for events
to
bot.hears('1', first.hears()) // hears listens for the specified string from bot
Then rewrite the module in /command/first to:
module.exports = {
hears: function (ctx) {
console.log("debug 1");
// Added markdown formatting
const message = `*Bold text* and _italic text_`;
ctx.telegram.sendMessage(ctx.message.chat.id, message, {
parse_mode: 'Markdown',
reply_markup: JSON.stringify({ // You also missed JSON.stringify()
keyboard: [
['🔙 Back'],
],
resize_keyboard: true
}),
disable_notification: false
});
}
}
This should work. I hope this helps.

How could I detect an Intent with a context ? (node.js SDK for Dialogflow API V2)

How could I detect an Intent with a context ?
I defined an Intent "Book" with an input Context "Activity", then trained my bot with "Book this activity in my schedule".
I don't want to use dialog flow to manage context flow because it may evolve from other inputs in my app. So I want pass it as a parameter for each intent detection.
I use node.js SDK for Dialogflow API V2.
I precise it works fine with REST API v1 ... I think i'm stuck with API v2 Contexts :)
I'm looking to do exactly the same as the following code with API v2
//code below is working fine
import apiai from 'apiai';// Dialogflow SDK v1
import uuidv4 from 'uuid/v4';
const sessionId = uuidv4();
const api = apiai('myToken');
const lang = 'en-US';
const request = api.textRequest('Book this activity in my schedule', {
sessionId,
lang,
contexts : [{ name : 'activity' }],
});
request.on('response', function(response) {
console.log(response);
});
request.on('error', function(error) {
console.log(error);
});
request.end();
I didn't found documentation or exemple to do that except API documentation so I probably did something wrong
Whenever I pass a context as a queryParams or create a Context it don't work.
It also seems that context creation from API don't work at all.
import dialogflow from 'dialogflow';//Dialogflow SDK v2
import uuidv4 from 'uuid/v4';
const projectId = 'myID';
const sessionId = uuidv4();
const languageCode = 'en-US';
const sessionClient = new dialogflow.SessionsClient();
const contextClient = new dialogflow.ContextsClient();
const sessionPath = sessionClient.sessionPath(projectId, sessionId);
...
First try returned my Default Fallback Intent :
const request = {
session : sessionPath,
queryParams : {
context : {
parent : sessionPath,
name : contextClient.contextPath(
projectId,
sessionId,
'activity'
),
},
},
queryInput : {
text : {
text : 'Book this activity in my schedule',
languageCode : languageCode,
},
},
};
sessionClient.detectIntent(request)
.then(responses => {
const result = responses[0].queryResult;
if (result.intent) {
console.log(result.intent.displayName);
} else {
console.log(' No intent matched.');
}
});
Second try returned my Default Fallback Intent :
contextClient
.createContext({
parent : sessionPath,
context : {
name : contextClient.contextPath(
projectId,
sessionId,
'activity'
),
},
})
.then(() => contextClient.listContexts({ parent : sessionPath }))
.then(contexts => {
console.log(contexts);//returned an empty list
return sessionClient.detectIntent(request);
}).then(responses => {
const result = responses[0].queryResult;
if (result.intent) {
console.log(result.intent.displayName);
} else {
console.log(' No intent matched.');
}
});
Anybody see what's wrong with it ?
Help needed :)
Had same issue.
Found that I need to send "lifespanCount" greated than 0.
{
"session": "projects\/verifier-26084\/agent\/sessions\/1gg5b76c37f7111b",
"queryParams":
{
"contexts": [
{
"name": "projects\/verifier-26084\/agent\/sessions\/1gg5b76c37f7111b\/contexts\/ask-children",
"lifespanCount": 1
}]
},
"queryInput":
{
"text":
{
"text": "\u0442\u0440\u0438",
"languageCode": "ru-RU"
}
}
}

Resources