Change day/month language in DialogFlow bot - dialogflow-es

I'm creating an assistant for an italian restaurant using DialogFlow.
I've set the language to spanish, and everything seems to go fine, but when i show the final date of the reservation it is shown in english (Friday and May in attached picture's case).
Is it possible to change it?
This is the code that generates the above particular response to a table booking process:
function createBooking(agent) {
let guests = agent.parameters.comensales;
let time = new Date(agent.parameters.time);
let date = new Date(agent.parameters.date);
let bookingDate = new Date(date);
var numeroReserva = Math.random().toString(16).slice(2, 8).toUpperCase();
bookingDate.setHours(time.getHours());
bookingDate.setMinutes(time.getMinutes());
let now = new Date();
if (guests < 1){
agent.add('You need to reserve a table for at least one person. Please try again!');
} else if (bookingDate < now){
agent.add(`No puedes reservar una fecha pasada. Por favor, inténtalo de nuevo!`);
} else if (bookingDate.getFullYear() > now.getFullYear()) {
agent.add(`No puedes hacer una reserva para ${bookingDate.getFullYear()} todavía. Por favor, elige una fecha en ${now.getFullYear()}.`);
} else {
let timezone = parseInt(agent.parameters.time.toString().slice(19,22));
bookingDate.setHours(bookingDate.getHours() + timezone);
agent.add(`Perfecto. He reservado una mesa para ${guests} el ${bookingDate.toString().slice(0,21)}`);
agent.add(`Tu código de reserva es: ${numeroReserva}`);
agent.add('Nos vemos pronto!');
agent.add('Buon appetito!');
}
}

The code running the fulfillment runs within Google's compute infrastructure which has a default locale/language of US English. When a request arrives for fullfilment from Dialog flow, that request carries with it the language that we are to use to respond. See the languageCode in the Webhook Request JSON. When we use the APIs in Node.js, it looks like this data is available in the agent.locale property.
Looking at the JavaScript Date object, we seem to have a method on it called toLocaleString() which converts a date/time into a string but additionally supplies the language (locale) to be used to create the language specific content and format. If we put all this together, we might find that the following code line may work:
agent.add(`Perfecto. He reservado una mesa para ${guests} el ${bookingDate.toLocalString(agent.locale).slice(0,21)}`);
This may take a few tests to get right. I'd start by logging agent.locale as a test to ensure that it has the value we expect/hope.

It's late but for those who face with this problem. You know you can do it like this:
let options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric',
hour12: false, hour: 'numeric', minute: 'numeric' };
var curr_date = new Date();
agent.add(`Sono le ` + curr_date.toLocaleString('it-IT', options));

If someone likes to use moment.js
you can add library to your project from fulfillment inline editor.
Go to Fulfillment, click on "package.json"
add the following lines in dependencies
"moment": "^2.24.0",
"moment-timezone": "^0.5.31"
Then back to index.js and add the following line to import it
const moment = require('moment-timezone');
and then you can handle like this in your function
if(agent.locale === 'en'){
moment.locale('en-US');
agent.add(`Now is ` + moment().tz(your_time_zone).format('LLLL'));
}
else if(agent.locale === 'it-IT' || agent.locale === 'it'){
moment.locale('it');
agent.add(`Sono le ` + moment().tz(your_time_zone).format('LLLL'));
}
The sample of response is " Sono le martedì 20 ottobre 2020 15:30"
or "Now is Tuesday, October 20, 2020 3:31 PM"

Related

function to add new Objekt in an existing object

i am pretty new to Javascript an had a idea for a small thing to code. The idea was to make an Objekt (kunden) in here we have some clients. In this Objekt i have one existing Client (kunde_1) and a Method (erstellen() ). With the Method i want to add a new client (new Objekt) to the exisiting Objekt (kunden) using a client counter. The counter should count up everytime the function ist called. Here ist my Try, but i have no real idea how to use my counter to create the new client. Here ist the Error that i get:
Uncaught TypeError: Cannot create property 'vorname' on string 'kunde_2'
Is it possible to adjust my code a bit to get it right or am i on a complete wrong path...
let count_kunde = 1; // because i already have one client called kunde_1
let kunden = {
erstellen() {
count_kunde +=1;
let neuer_kunde = `kunden_${count_kunde}`; // the idea was to create a variable that stores "kunde_2" and through DOT Notation add the values via prompt.
neuer_kunde.vorname = prompt("Vorname:"),
neuer_kunde.nachname= prompt("Nachname"),
neuer_kunde.straße= prompt("Straße"),
neuer_kunde.hausnummer= prompt("Hausnummer"),
neuer_kunde.plz= prompt("Plz"),
neuer_kunde.ort= prompt("Ort")
},
kunde_1: {
vorname: "Bengt",
nachname: "Flecks",
straße: "Scheffelstraße",
hausnummer: 33,
plz: 10367,
ort: "Berlin"
}
};
Here ist the new code after solving the Problem with special thanks to #Deivid Ugarte (with my comments in german):
// Anzahl aktueller Kunden zum Start des Programms
let count_kunde = 1;
// Erstellung des Objektes kunden zum speichern der neu erstellten
Kunden
let kunden = {
kunde_1: {
vorname: "Bengt",
nachame: "Flecks",
straße: "Scheffelstraße",
hausnummer: 33,
plz: 10367,
ort: "Berlin"
}
};
//Funktion zum erstellen eines neuen Kunden
const kunden_erstellen = function() {
count_kunde += 1;
let neuer_kunde = `kunde_${count_kunde}`;
// Erstellung des Objektes kunden.kunde_n wobei n = count_kunde um
im nächsten Schritt die Eigentschaften mit den eingeegebenen Werten
hinzuzufügen
kunden[neuer_kunde] = {};
kunden[neuer_kunde].vorname = prompt("Vorname:"),
kunden[neuer_kunde].nachname = prompt("Nachname"),
kunden[neuer_kunde].straße= prompt("Straße"),
kunden[neuer_kunde].hausnummer= prompt("Hausnummer"),
kunden[neuer_kunde].plz= prompt("Plz"),
kunden[neuer_kunde].ort= prompt("Ort")
};
// Funktionsaufruf zum erstellen eines Kunden
kunden_erstellen();
You need to define neuer_kunde as an object let neuer_kunde = {} and then assign the name to the object neuer_kunde.name = kunden_${count_kunde}.
The error you had was that you are trying to assign a property to the first created string

create a json dynamically in node js

I have a problem with creating a json dynamically. I retrieve the data of a sent json:
body.value look like :
{
hubspotProperty: 'question3',
response: 'Nous utilisons un google drive mais il est très peu utilisé'
},
{
hubspotProperty: 'question2',
response: 'Nous complétons le CRM quand nous avons ' +
'le temps et au bon vouloir du commercial'
},
{
hubspotProperty: 'question1',
response: "Nous n'avons aucun processus " +
"automatisé et nous n'en voyons pas " +
"l'intérêt"
}
]
but I want the hubspot property to be the key of the new json and the response to be my I don't now how I can do this .
Help me please
Bonjour, the simplest way to make json:
var someValue = "Jean"
var jsonString = `{"nom":"${someValue}"}`
Take care of the "backwards ticks" `
Regarding the json which comes in to you:
var exampleJson = `{ "hubspotProperty": "question3" }`
It is this easy ...
var args = JSON.parse(exampleJson)
var value = args.hubspotProperty
console.log("it's done .. " + value)

Firestore import data-file is not correct saved (ä,ö,ü,á are shown as symbols)

i try to import some data in my firestore, this works quite well.
The data are german, english and spanish languages, so I have á,í, ä,...
My .json file is correct and when i opened it via xcode and vs code everything looks fine.. When i start my import and take a look at my database, those letters will be replaced by icons...
And i dont know why ... Does anybody know how to fix this?
As an example this is my .json :
{
"exercisesTest" : [
{
"exercises": "a_01",
"description_d": "Stell dich schulterbreit hin und stütz deine Hände in die Hüfte. Senk deinen Oberkörper ab, so als wolltest du dich auf einen Stuhl setzen. Achte darauf, dass deine Füße während der ganzen Bewegung immer fest am Boden bleiben und sich immer über den Fußgelenken befinden.",
"description_e": "Take a stance with your feet shoulder-width apart and put your hands on your hips. Lower your upper body as if you were sitting on a chair. Make sure that your feet remain firmly on the ground during the whole movement. Your knees should always be above the ankles.",
"description_s": "Ponte en posición con los pies separados a la anchura de los hombros y pon las manos sobre las caderas. Baja la parte superior del cuerpo como si estuvieras sentado en una silla. Asegúrate de que tus pies permanezcan firmemente en el suelo durante todo el movimiento. Las rodillas deben estar siempre por encima de los tobillos."}]}
and this is my firebase db...
Import will be done by my .js file and works fine, except the icons :p
const admin = require('./node_modules/firebase-admin');
const serviceAccount = require("./serviceAccountKey.json");
const data = require("./data.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "xxxx"
});
data && Object.keys(data).forEach(key => {
const nestedContent = data[key];
if (typeof nestedContent === "object") {
Object.keys(nestedContent).forEach(docTitle => {
admin.firestore()
.collection(key)
.doc(docTitle)
.set(nestedContent[docTitle])
.then((res) => {
console.log("Document successfully written!");
})
.catch((error) => {
console.error("Error writing document: ", error);
});
});
}
});
Thanks for your help!
Okay, i deleted my whole .json file and create a new one with a different csv to json - now it works...
used this csv to json + validator
https://csvjson.com/json_validator

Filtering Outlook Calendar API results by date

I'm using Node (specifically the node-outlook npm module) to pull through my Outlook.com calendar and the base request is working. I'm getting back results from the API, but I'm having trouble with the oData request parameters to only reutrn results for today. Here's what I've got:
var queryParams = {
'$select': 'Subject,Start,End',
'$orderby': 'Start/DateTime desc',
//'$top': 10,
'startDateTime': startDateString,
'endDateTime': endDateString
//'$filter': "Start/DateTime ge " + startDateString + " and Start/DateTime le " + endDateString
};
outlook.base.setApiEndpoint('https://outlook.office.com/api/v2.0');
outlook.base.setAnchorMailbox(<my email address>);
outlook.base.setPreferredTimeZone('Europe/London');
outlook.calendar.getEvents({token:token, odataParams: queryParams},function(error, result){
//Do some stuff with the event data here
}
However, if I use the parameters are shown above (where startDateString is 2016-10-28T00:00:00 and endDateString is 2016-10-28T23:59:59) I'm still getting back events both in the past and in the future.
This isn't what I want - what I was hoping to do was just pull through the current days events (hence the attempt at useing the oData $filter, but the API doesn't seem to like that and it moans about incompatible binary operators).
Can anyone advise what I need to amend in the params to just get back events scheduled for today?
Thanks
EDIT: Here's an example of what I'm getting returned:
StartDateTime and EndDateTime properties are represented as DateTimeTimeZone values When creating or updating event the value (which includes time zone information):
"StartDateTime": {
"DateTime": "2016-10-28T00:00:00",
"TimeZone": "Europe/London" //current time zone
}
is getting converted to UTC value:
"StartDateTime": {
"DateTime": "2016-10-27T23:00:00",
"TimeZone": "UTC"
}
The same applies to filtering operation. That is the reason why startDateString and endDateTime values should be converted from local time to UTC for getting today events.
For example, using Moment.js library:
var startDateStringUtc = moment(startDateString).toISOString();
var endDateStringUtc= moment(endDateString).toISOString();
var queryParams = {
'$select': 'Subject,Start,End',
'$orderby': 'Start/DateTime desc',
//'$top': 10,
'startDateTime': startDateStringUtc,
'endDateTime': endDateStringUtc
//'$filter': "Start/DateTime ge " + startDateString + " and Start/DateTime le " + endDateString
};
About DateTimeTimeZone structure
According to MSDN:
Describes the date, time, and time zone of a point in time.
DateTime DateTime A single point of time in a combined date and time representation (T) according to ISO 8601
format.
TimeZone String One of the following time zone names.
How to determine timezone when the event was created
OriginalStartTimezone and OriginalEndTimezone are meant to reflect
what timezone was set when the event was created or updated
Figured it out (or at least this SO question did it for me)
It turns out the times need to be enclosed in quotes!
var queryParams = {
'$orderby': 'Start/DateTime desc',
'$filter': "Start/DateTime ge '" + startDateString + "' and Start/DateTime le '" + endDateString + "'"
};
And now its working.
Grrr!

mustache.js date formatting

I have started using mustache.js and so far I am very impressed. Although two things puzzle me. The first leads on to the second so bear with me.
My JSON
{"goalsCollection": [
{
"Id": "d5dce10e-513c-449d-8e34-8fe771fa464a",
"Description": "Multum",
"TargetAmount": 2935.9,
"TargetDate": "/Date(1558998000000)/"
},
{
"Id": "eac65501-21f5-f831-fb07-dcfead50d1d9",
"Description": "quad nomen",
"TargetAmount": 6976.12,
"TargetDate": "/Date(1606953600000)/"
}
]};
My handling function
function renderInvestmentGoals(collection) {
var tpl = '{{#goalsCollection}}<tr><td>{{Description}}</td><td>{{TargetAmount}}</td><td>{{TargetDate}}</td></tr>{{/goalsCollection}}';
$('#tblGoals tbody').html('').html(Mustache.to_html(tpl, collection));
}
Q1
As you can see my 'TargetDate' needs parsing but I am unsure of how to do that within my current function.
Q2
Say I wanted to perform some function or formatting on one or more of my objects before rendering, what is the best way of doing it?
You can use "Lambdas" from mustache(5)
"TargetDate": "/Date(1606953600000)/",
"FormatDate": function() {
return function(rawDate) {
return rawDate.toString();
}
}, ...
Then in the markup:
<td>
{{#FormatDate}}
{{TargetDate}}
{{/FormatDate}}
</td>
From the link:
When the value is a callable object, such as a function or lambda, the object will be invoked and passed the block of text. The text passed is the literal block, unrendered.
I have created a small extension for Mustache.js which enables the use of formatters inside of expressions, like {{expression | formatter}}
You would anyway need to create a function that parses your date value like this:
Mustache.Formatters = {
date: function( str) {
var dt = new Date( parseInt( str.substr(6, str.length-8), 10));
return (dt.getDate() + "/" + (dt.getMonth() + 1) + "/" + dt.getFullYear());
}
};
And then just add the formatter to your expressions:
{{TargetDate | date}}
You can grab the code from here: http://jvitela.github.io/mustache-wax/
It's a long time ago but got on this looking for exactly the same. Mustachejs (now) allows you to call functions of the passed data and not only that; in the function the value of this is whatever value is true in a section.
If my template is like this:
{{#names}}
<p>Name is:{{name}}</p>
<!-- Comment will be removed by compileTemplates.sh
#lastLogin is an if statement if lastLogin it'll do this
^lastLogin will execute if there is not lastLogin
-->
{{#lastLogin}}
<!--
formatLogin is a method to format last Login
the function has to be part of the data sent
to the template
-->
<p>Last Login:{{formatLogin}}</p>
{{/lastLogin}}
{{^lastLogin}}
not logged in yet
{{/lastLogin}}
{{#name}}
passing name to it now:{{formatLogin}}
{{/name}}
{{/names}}
And Data like this:
var data={
names:[
{name:"Willy",lastLogin:new Date()}
],
formatLogin:function(){
//this is the lastDate used or name based on the block
//{{#name}}{{formatLogin}}{{/name}}:this is name
//{{#lastLogin}}{{formatLogin}}{{/lastLogin}}:this is lastLogin
if(!/Date\]$/.test(Object.prototype.toString.call(this))){
return "Invalid Date:"+this;
}
return this.getFullYear()
+"-"+this.getMonth()+1
+"-"+this.getDate();
}
};
var output = Mustache.render(templates.test, data);
console.log(output);
You can get the timestamp using simple String methods:
goalsCollection.targetDate = goalsCollection.targetDate.substring(6,18);
Of course, this depends on your timestamp being the same length each time. Another option is:
goalsCollection.targetDate =
goalsCollection.targetDate.substring(6, goalsCollection.targetDate.length - 1);
These techniques aren't specific to Mustache and can be used to manipulate data for any library. See the Mozilla Developer Center Documentation on substring for more details.
To declare a function within a json you can always do this.
var json = '{"RESULTS": true, "count": 1, "targetdate" : "/Date(1606953600000)/"}'
var obj = JSON.parse(json);
obj.newFunc = function (x) {
return x;
}
//OUTPUT
alert(obj.newFunc(123));
Working example of a 'lambda' function for parsing an ISO-8601 date and formatting as UTC:
var data = [
{
"name": "Start",
"date": "2020-04-11T00:32:00.000-04:00"
},
{
"name": "End",
"date": "2022-04-11T00:32:00.000-04:00"
},
]
var template = `
{{#items}}
<h1>{{name}}</h1>
{{#dateFormat}}
{{date}}
{{/dateFormat}}
{{/items}}
`;
var html = Mustache.render(template, {
items: data,
dateFormat: function () {
return function (timestamp, render) {
return new Date(render(timestamp).trim()).toUTCString();
};
}
});
document.getElementById("main").innerHTML = html;
<script src="https://unpkg.com/mustache#4.2.0/mustache.min.js"></script>
<div id="main"></div>
If you want fancier date formatting you could use for example something like:
new Date().toLocaleDateString('en-GB', {
day : 'numeric',
month : 'short',
year : 'numeric', hour: 'numeric', minute: 'numeric'
})
// outputs '14 Apr 2022, 11:11'
I've been using Mustache for my projects as well, due to its ability to be shared across client/server. What I ended up doing was formatting all values (dates, currency) to strings server-side, so I don't have to rely on helper Javascript functions. This may not work well for you though, if you're doing logic against these values client-side.
You might also want to look into using handlebars.js, which is essentially Mustache, but with extensions that may help with client-side formatting (and more). The loss here is that you will probably not be able to find a server-side implementation of handlebars, if that matters to you.

Resources