I have 3 groups( html ) inside every group is four people and those people are the same in all 3 groups but just different numbers (votes/credits whatever), and I have a json file where is values for those people inside group. My HTML file reads my json file without problem.
I'm using Dialogflows Inline Editor to work with the Google Assistant. What I want is that the same way my html( javascript ) is reading those values from json file, I want to be able to load the person.json file as well. I have edited that many times could not manage to call person.json url.
For example:
"Hey google, tell me Alex credits"
< here it should read from my json file which is 73 >
Here are codes: person1.html
var response = await fetch("laurel.json");
var arr = await response.json();
var laurel= arr[1];
var dflt = {
min: 0,
max: 100,
// donut: true,
gaugeWidthScale: 1.1,
counter: true,
hideInnerShadow: true
}
var ee1 = new r({
id: 'ee1',
value: laurel['Jennifer'],
title: 'Jennifer ',
defaults: dflt
});
var ee2 = new r({
id: 'ee2',
value: laurel['Peter'],
title: 'Peter',
defaults: dflt
});
var ee3 = new r({
id: 'ee3',
value: laurel['Justin'],
title: 'Justin',
defaults: dflt
});
var ee4 = new r({
id: 'ee4',
value: laurel['Alex'],
title: 'Alex',
defaults: dflt
});
});
inline editors index.js :
intentMap.set('persons1', someFunction);
function someFunction(agent) {
agent.add(`Alex credits are 73 `);
}
// // 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/dialogflow-fulfillment-nodejs/tree/master/samples/actions-on-google
// // 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);
});
You've got a couple of options here. Either you switch your plan to Blaze and make a network request for the JSON data that is hosted on your public URL mentioned earlier.
Or you can also just put the JSON data into the Firebase realtime database as it is also accessible as a JSON document on a public URL if you set the database rules to publicly readable.
database.rules.json
{
"rules": {
"persons": {
".read": true
}
}
}
After that you can access your JSON data in Firebase on this URL: https://<your-project-id>.firebaseio.com/persons.json
That should be effectively the same thing for accessing in your web app.
For your AoG fulfillment you can simply use the Firebase SDK to access the data
firebase.database().ref('persons').child('personId');
Related
I'm integrating amazon connect chatbot on my end and I want to establish a connection between a customer and an agent. In order to so, I have used onMessage event to retrieve agent messages back on my platform but right now, it is not triggered.
I have initially used aws-sdk and #aws-sdk/client-connectparticipant library to send messages where I have used multiple SDKs api in this order
startChatContact -> createParticipantConnection -> sendEvent -> sendMessage
This was done in order to establish a connection between a client and an agent, so that they can send messages to each other as well. With these SDKs, I was successfully able to send messages from customer to agent but in order to retrieve the messages back, I have used getTranscript api inititally, which I was calling in every 2 seconds to check for any updated messages. I have also stored message ids on my end to avoid any duplicate entries.
But now I'm looking for a better solution and for that, I have used amazon-connect-chatjs library and I have used the code below:
import "amazon-connect-streams";
import "amazon-connect-chatjs";
connect.contact(contact => {
if (contact.getType() !== connect.ContactType.CHAT) {
// applies only to CHAT contacts
return;
}
contact.onAccepted(() => {
const cnn = contact.getConnections().find(cnn => cnn.getType() === connect.ConnectionType.AGENT);
const agentChatSession = connect.ChatSession.create({
chatDetails: cnn.getMediaInfo(),
options: {
region: "us-west-2"
},
type: connect.ChatSession.SessionTypes.AGENT,
websocketManager: connect.core.getWebSocketManager()
});
});
});
I have also tried creating a customer chat session, but it is not working as well
const customerChatSession = connect.ChatSession.create({
chatDetails: {
contactId: "...",
participantId: "...",
participantToken: "..."
},
options: { // optional
region: "us-west-2"
},
type: connect.ChatSession.SessionTypes.CUSTOMER
});
Apart from that, I have used onTyping event, but it is not getting triggered as well.
Please let me know if I'm missing anything or doing anything wrong here.
Update1
if i add console.log
const customerChatSession = connect.ChatSession.create({
chatDetails: {
contactId: "...",
participantId: "...",
participantToken: "..."
},
options: { // optional
region: "us-west-2"
},
type: connect.ChatSession.SessionTypes.CUSTOMER
});
console.log("Here");
then even it does not print Here.
There is no error on console.
To create agentChatSession need websocket
connect.core.getWebSocketManager()
this is undefined even.
My NodeJS application writes logs with Winston. These logs then will be picked up by Promtail, to be saved to S3 by Loki and then processed in a dashboard in Grafana.
I want to create logs in Winston with dailyrotation of 30m. I want the logs to first be stored in my folder "/home/gad-web/gad-logs" when they are still being appended. And when they are rotated I want to move them to "/home/gad-web/gad-logs-rotated". Promtail will be looking at this specific folder.
I want to use dynamic filenames for different logs being written out, so that I can easily assign static labels to each file separetly using Promtail, rather than having to process each log line and assign a dynamic label to each line of log in one large file.
my file logger.mjs looks like this (formats, levels and other irrelevant data is left out):
const logDir = '/home/gad-web/gad-logs'
const logDirRotated = '/home/gad-web/gad-logs-rotated'
let winstonGdprProofFormat = winston.format.combine(...)
let winstonDailyRotateFileTransport = new winston.transports.DailyRotateFile({
frequency: '30m',
format: winstonGdprProofFormat,
filename: `${logDir}/all-gdpr-proof-%DATE%.log`,
datePattern: 'YYYY-MM-DD HH-mm',
})
// Move the file to another location after it is rotated, so it can be picked up by Promtail
winstonDailyRotateFileTransport.on('rotate', function (oldFilenamePath, newFilenamePath) {
let pathToMoveTo = `${logDirRotated}/${path.basename(oldFilenamePath)}`
fs.rename(oldFilenamePath, pathToMoveTo, function (err) {
if (err) throw err
})
})
let winstonTransports = []
if (process.env.environment !== 'local') {
winstonTransports.push(winstonConsoleTransport)
winstonTransports.push(winstonDailyRotateFileTransport)
} else {
winstonTransports.push(winstonConsoleWithColorsTransport)
}
const logger = winston.createLogger({
level: process.env.environment !== 'local' ? 'info' : 'debug',
levels: winstonLevels,
transports: winstonTransports,
})
export function log (obj) {
let { level, requestId, method, uri, msg, time, data } = obj
if (!level) {
level = 'info'
}
logger.log({
level: level,
requestId: requestId,
method: method,
uri: uri,
msg: msg,
time: time,
data: data,
})
}
It is being called in files that write logs like this:
import { log } from '../config/logger.mjs'
...
function writeRequestLog (start, request, requestId) {
let end = new Date().getTime()
let diff = end - start
log({ level: 'info', requestId: requestId, method: request.method, uri: request.path, msg: null, time: `${diff}ms`, data: JSON.stringify(request.query) })
}
Since the file is imported directly, it is immediately executed, and the winstonDailyRotateFileTransport is created using ${logDir}/all-gdpr-proof-%DATE%.log as the filename. How do I go around this instantiating this with a filename, so that I get daily rotated log files of 30minutes for a bunch of dynamically created different files?
I tried creating a Class in JS, but I quickly got into trouble because of the .on('rotate', ...) defined for the winstonDailyRotateFileTransport, and i'm also not sure of other implications creating a class for this might have (since this logger will be used a lot of times in my code)
I'm trying to integrate the backchannel and getting the values.
https://github.com/Microsoft/BotFramework-WebChat/tree/master/samples/15.d.backchannel-send-welcome-event
I also tried this. Get URL Referer and Origin header from Microsoft Bot Framework
I also tried deserializing the values still not able to get the data.
how can i get the language values?
here's my sample code:
var userinfo = {
id: 'user-id',
name: 'user name',
locale: 'es'
};
var botConnection = new BotChat.DirectLine({
token: 'mytoken',
user: userinfo,
locale: 'es'
});
BotChat.App({
botConnection : botConnection,
user: userinfo,
bot: { id: 'bot-id', name: 'bot name' },
}, document.getElementById('botDiv'));
botConnection
.postActivity({
from: userinfo,
name: 'ConversationUpdate',
type: 'event',
value: '',
})
.subscribe(function (id) {
console.log('"trigger ConversationUpdate" sent');
});
The purpose of this I want to pass the locale to my bot from my website.
just like in the emulator.
Thanks!
I would recommend adding the locale to the back channel event's channel data. That way on the bot side you can simply access the locale in the incoming activity without having to deserialize any JSON objects when you receive the event. Note, you can also use text or value in place of channelData. See the code snippets below.
BotChat Back Channel Event
// Send back channel event
botConnection.postActivity({
from: userinfo,
name: 'setLocale',
type: 'event',
channelData: "es"
}).subscribe(id => console.log(id));
Bot - C#
public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
{
if (turnContext.Activity.Type == ActivityTypes.Message)
{
...
} else if (turnContext.Activity.Type == "event") {
// Check for `setLocale` events
if (turnContext.Activity.Name == "setLocale") {
await turnContext.SendActivityAsync($"Your locale is set to {turnContext.Activity.ChannelData}");
}
}
else
{
await turnContext.SendActivityAsync($"{turnContext.Activity.Type} event detected");
}
}
Hope this helps!
I am attempting to update an entity in my datastore kind using sample code from here https://cloud.google.com/datastore/docs/reference/libraries. The actual code is something like this:
/ Imports the Google Cloud client library
const Datastore = require('#google-cloud/datastore');
// Your Google Cloud Platform project ID
const projectId = 'YOUR_PROJECT_ID';
// Creates a client
const datastore = new Datastore({
projectId: projectId,
});
// The kind for the new entity
const kind = 'Task';
// The name/ID for the new entity
const name = 'sampletask1';
// The Cloud Datastore key for the new entity
const taskKey = datastore.key([kind, name]);
// Prepares the new entity
const task = {
key: taskKey,
data: {
description: 'Buy milk',
},
};
// Saves the entity
datastore
.save(task)
.then(() => {
console.log(`Saved ${task.key.name}: ${task.data.description}`);
})
.catch(err => {
console.error('ERROR:', err);
});
I tried to create a new entity using this code. But when I ran this code and checked the datastore console, there were no entitites created.Also, I am unable to update an existing entity. What could be the reason for this?
I am writing the code in Google Cloud Functions.This is the log when I run this function:
{
insertId: "-ft02akcfpq"
logName: "projects/test-66600/logs/cloudaudit.googleapis.com%2Factivity"
operation: {…}
protoPayload: {…}
receiveTimestamp: "2018-06-15T09:36:13.760751077Z"
resource: {…}
severity: "NOTICE"
timestamp: "2018-06-15T09:36:13.436Z"
}
{
insertId: "000000-ab6c5ad2-3371-429a-bea2-87f8f7e36bcf"
labels: {…}
logName: "projects/test-66600/logs/cloudfunctions.googleapis.com%2Fcloud-functions"
receiveTimestamp: "2018-06-15T09:36:17.865654673Z"
resource: {…}
severity: "ERROR"
textPayload: "Warning, estimating Firebase Config based on GCLOUD_PROJECT. Intializing firebase-admin may fail"
timestamp: "2018-06-15T09:36:09.434Z"
}
I have tried the same code and it works for me. However, I have noticed that there was a delay before the entities appeared in Datastore. In order to update and overwrite existing entities, use .upsert(task) instead of .save(task) (link to GCP documentation). You can also use .insert(task) instead of .save(task) to store new entities.
Also check that the project id is correct and that you are inspecting the entities for the right kind.
I am developing a very basic calendar with Angular and Node and I haven't found any code on this.
Workflow is the following : create an event, input the recipient's e-mail address, validate the event.
This triggers an e-mail sent to the recipient. The mail should be in the outlook meeting request format (not an attached object).
This means that when received in outlook the meeting is automatically added in the calendar.
Is this possible? If yes is it possible with only javascript on Node side?
For those still looking for an answer, here's how I managed to get the perfect solution for me.
I used iCalToolkit to create a calendar object.
It's important to make sure all the relevant fields are set up (organizer and attendees with RSVP).
Initially I was using the Postmark API service to send my emails but this solution was only working by sending an ics.file attachment.
I switched to the Postmark SMTP service where you can embed the iCal data inside the message and for that I used nodemailer.
This is what it looks like :
var icalToolkit = require('ical-toolkit');
var postmark = require('postmark');
var client = new postmark.Client('xxxxxxxKeyxxxxxxxxxxxx');
var nodemailer = require('nodemailer');
var smtpTransport = require('nodemailer-smtp-transport');
//Create a iCal object
var builder = icalToolkit.createIcsFileBuilder();
builder.method = meeting.method;
//Add the event data
var icsFileContent = builder.toString();
var smtpOptions = {
host:'smtp.postmarkapp.com',
port: 2525,
secureConnection: true,
auth:{
user:'xxxxxxxKeyxxxxxxxxxxxx',
pass:'xxxxxxxPassxxxxxxxxxxx'
}
};
var transporter = nodemailer.createTransport(smtpTransport(smtpOptions));
var mailOptions = {
from: 'message#domain.com',
to: meeting.events[0].attendees[i].email,
subject: 'Meeting to attend',
html: "Anything here",
text: "Anything here",
alternatives: [{
contentType: 'text/calendar; charset="utf-8"; method=REQUEST',
content: icsFileContent.toString()
}]
};
//send mail with defined transport object
transporter.sendMail(mailOptions, function(error, info){
if(error){
console.log(error);
}
else{
console.log('Message sent: ' + info.response);
}
});
This sends a real meeting request with the Accept, decline and Reject button.
It's really unbelievable the amount of work you need to go through for such a trivial functionality and how all of this not well documented.
Hope this helps.
If you do not want to use smtp server approach in earlier accepted solution, you have Exchange focused solution available. Whats wrong in current accepted answer? it does not create a meeting in sender's Calendar, you do not have ownership of the meeting item for further modification by the sender Outlook/OWA.
here is code snippet in javascript using npm package ews-javascript-api
var ews = require("ews-javascript-api");
var credentials = require("../credentials");
ews.EwsLogging.DebugLogEnabled = false;
var exch = new ews.ExchangeService(ews.ExchangeVersion.Exchange2013);
exch.Credentials = new ews.ExchangeCredentials(credentials.userName, credentials.password);
exch.Url = new ews.Uri("https://outlook.office365.com/Ews/Exchange.asmx");
var appointment = new ews.Appointment(exch);
appointment.Subject = "Dentist Appointment";
appointment.Body = new ews.TextBody("The appointment is with Dr. Smith.");
appointment.Start = new ews.DateTime("20170502T130000");
appointment.End = appointment.Start.Add(1, "h");
appointment.Location = "Conf Room";
appointment.RequiredAttendees.Add("user1#constoso.com");
appointment.RequiredAttendees.Add("user2#constoso.com");
appointment.OptionalAttendees.Add("user3#constoso.com");
appointment.Save(ews.SendInvitationsMode.SendToAllAndSaveCopy).then(function () {
console.log("done - check email");
}, function (error) {
console.log(error);
});
Instead of using 'ical-generator', I used 'ical-toolkit' to build a calender invite event.
Using this, the invite directly gets appended in the email instead of the attached .ics file object.
Here is a sample code:
const icalToolkit = require("ical-toolkit");
//Create a builder
var builder = icalToolkit.createIcsFileBuilder();
builder.method = "REQUEST"; // The method of the request that you want, could be REQUEST, PUBLISH, etc
//Add events
builder.events.push({
start: new Date(2020, 09, 28, 10, 30),
end: new Date(2020, 09, 28, 12, 30),
timestamp: new Date(),
summary: "My Event",
uid: uuidv4(), // a random UUID
categories: [{ name: "MEETING" }],
attendees: [
{
rsvp: true,
name: "Akarsh ****",
email: "Akarsh **** <akarsh.***#abc.com>"
},
{
rsvp: true,
name: "**** RANA",
email: "**** RANA <****.rana1#abc.com>"
}
],
organizer: {
name: "A****a N****i",
email: "A****a N****i <a****a.r.n****i#abc.com>"
}
});
//Try to build
var icsFileContent = builder.toString();
//Check if there was an error (Only required if yu configured to return error, else error will be thrown.)
if (icsFileContent instanceof Error) {
console.log("Returned Error, you can also configure to throw errors!");
//handle error
}
var mailOptions = { // Set the values you want. In the alternative section, set the calender file
from: obj.from,
to: obj.to,
cc: obj.cc,
subject: result.email.subject,
html: result.email.html,
text: result.email.text,
alternatives: [
{
contentType: 'text/calendar; charset="utf-8"; method=REQUEST',
content: icsFileContent.toString()
}
]
}
//send mail with defined transport object
transporter.sendMail(mailOptions, function(error, info){
if(error){
console.log(error);
}
else{
console.log('Message sent: ' + info.response);
}
});
It should be possible as long as you can use SOAP in Node and also if you can use NTLM authentication for Exchange with Node. I believe there are modules for each.
I found this blog very helpful when designing a similar system using PHP
Please check the following sample:
const options = {
authProvider,
};
const client = Client.init(options);
const onlineMeeting = {
startDateTime: '2019-07-12T14:30:34.2444915-07:00',
endDateTime: '2019-07-12T15:00:34.2464912-07:00',
subject: 'User Token Meeting'
};
await client.api('/me/onlineMeetings')
.post(onlineMeeting);
More Information: https://learn.microsoft.com/en-us/graph/api/application-post-onlinemeetings?view=graph-rest-1.0&tabs=http