How to save data between conversation in Dialogflow? - firebase

I don't understand how you're supposed to save data.
I tried using
let conv = agent.conv()
conv.data.data1=mydata //to save
mydata = conv.data.data1 //to load
agent.add(conv)
but it crash my app.
I saw that you could put info in
var token = JSON.stringify(request.body.originalDetectIntentRequest.payload.conversation.conversationToken);
but how do you put data in conversationToken in the response?
What is your method? Thanks

Use the output context to save parameters
{
"fulfillmentText":"This is a text response",
"fulfillmentMessages":[ ],
"source":"example.com",
"payload":{
"google":{ },
"facebook":{ },
"slack":{ }
},
"outputContexts":[
{
"name":"<Context Name>",
"lifespanCount":5,
"parameters":{
"<param name>":"<param value>"
}
}
],
"followupEventInput":{ }
}
If you are using NodeJS client
You can save context with parameters like
let param1 = [];
let param2 = {};
let ctx = {'name': '<context name>', 'lifespan': 5, 'parameters': {'param1':param1, 'param2': param2}};
agent.setContext(ctx);
and get it like
let params = agent.getContext("<context name>").parameters;
let param1 = params.param1;
let param2 = params.param2;
You can store arrays, JSON obj but there is a limit to the total payload the response can save. check for more details here. For large data, use DB.
Also, if you are using standalone actions-on-google, then you can simply add key-value pair to the data object. See the link where they are storing a count

Also if you want to mark those parameters as required and use slot filling, that will automatically generate your output contexts during fulfillment. You can see this through a basic sample here: https://github.com/dialogflow/fulfillment-slot-filling-nodejs

Related

Is a variable for a field name allowed during update in Meteor?

I have been trying to update a collection i have.Problem is,i dont know the field name so am relying on some logic to come up with the field name.
For instance
Er.update({ _id: "BCwrQEdiTr9GMmKWW" }, {
$set: {
"x" : y
}
});
where x is the field name.
This is my code
var obj = {};
obj[x] = y;
Er.update({ _id: "BCwrQEdiTr9GMmKWW" }, {$set: {obj}});
I am getting this error
update failed: MongoError: The dotted field 'ersubjects.0.English' in
'obj.ersubjects.0.English' is not valid for storage.
English is a field under ersubjects so i want to update it this way ersubjects.0.English and it works on mongo.
Why is this not working in meteor?.
You can't store documents that have a dot in the key. See this answer for an explanation.
What you can do is use lodash's extremely handy _.set function to create your object with dynamic keys like this:
var obj = {};
var variableKey = 'ersubjects';
_.set(obj, [variableKey, 0, 'English], 'someValue');
Now you can safely store this object to Mongo.

Parse json into a series of documents in a collection using a for or foreach loop best? [meteor]

I have a Meteor app that pulls data in from an external api. For simplicity sake we'll say something like...
var foo = Meteor.http.call("GET", "api-endpoint-url-here");
And inserts the data into a collection...
Bar = new Mongo.Collection("bar");
Bar.insert({
Results: foo
});
The json array (e.g. foo) includes a number of individual records each of which has it's own id number and corresponding data. I'm presently using JSON.parse to establish my array and then looping through the array to create individual documents using _.each
var fooParsed = JSON.parse(foo.content)
var fooArray = fooParsed.results;
_.each(fooArray, function(records) {
Bar.insert ({
record: record
});
});
For now it's crude but that aside - I've heard using forEach is preferred for performance. Is that the general consensus and any thoughts on how to streamline this and implement such a loop in this instance?
in case it's helpful to someone else in the future - here's where this netted out
fooArray.forEach(function(item) {
Bar.insert({
_id: item.id,
description: description,
});
});

how to discard initial data in a Firebase DB

I'm making a simple app that informs a client that other clients clicked a button. I'm storing the clicks in a Firebase (db) using:
db.push({msg:data});
All clients get notified of other user's clicks with an on, such as
db.on('child_added',function(snapshot) {
var msg = snapshot.val().msg;
});
However, when the page first loads I want to discard any existing data on the stack. My strategy is to call db.once() before I define the db.on('child_added',...) in order to get the initial number of children, and then use that to discard that number of calls to db.on('child_added',...).
Unfortunately, though, all of the calls to db.on('child_added',...) are happening before I'm able to get the initial count, so it fails.
How can I effectively and simply discard the initial data?
For larger data sets, Firebase now offers (as of 2.0) some query methods that can make this simpler.
If we add a timestamp field on each record, we can construct a query that only looks at new values. Consider this contrived data:
{
"messages": {
"$messageid": {
"sender": "kato",
"message": "hello world"
"created": 123456 // Firebase.ServerValue.TIMESTAMP
}
}
}
We could find messages only after "now" using something like this:
var ref = new Firebase('https://<your instance>.firebaseio.com/messages');
var queryRef = ref.orderBy('created').startAt(Firebase.ServerValue.TIMESTAMP);
queryRef.on('child_added', function(snap) {
console.log(snap.val());
});
If I understand your question correctly, it sounds like you only want data that has been added since the user visited the page. In Firebase, the behavior you describe is by design, as the data is always changing and there isn't a notion of "old" data vs "new" data.
However, if you only want to display data added after the page has loaded, try ignoring all events prior until the complete set of children has loaded at least once. For example:
var ignoreItems = true;
var ref = new Firebase('https://<your-Firebase>.firebaseio.com');
ref.on('child_added', function(snapshot) {
if (!ignoreItems) {
var msg = snapshot.val().msg;
// do something here
}
});
ref.once('value', function(snapshot) {
ignoreItems = false;
});
The alternative to this approach would be to write your new items with a priority as well, where the priority is Firebase.ServerValue.TIMESTAMP (the current server time), and then use a .startAt(...) query using the current timestamp. However, this is more complex than the approach described above.

How to parse url with Meteor

I'm using Meteor with another CMS, and am creating a url with the variables I need to run Meteor (ex. http://site.com?a=flash&b=hash). How to I make those variables usable, and get Meteor to ignore it as a location? When I load the url like that, my app doesn't load correctly, presumably because it thinks I'm requesting a different location.
Using iron router, if there is a query string or hash fragment in the url, you can access those using the query and hash properties of the this.params object.
// given the url: "/post/5?q=s#hashFrag"
Router.route('/post/:_id', function () {
var id = this.params._id;
var query = this.params.query;
// query.q -> "s"
var hash = this.params.hash; // "hashFrag"
});
Use of the querystring in Meteor should have no effect unless you're using eg. Meteor Router to invoke different methods depending on the current URL.
If you want to parse the querystring, just parse it by hand with eg. (in coffeescript)
querystring: ->
qs = {}
for pair in window.location.search.replace("?", "").split "&"
[k, v] = pair.split("=")
qs[k] = v
qs
Which will return an object like:
{ "a": "flash", "b": "hash" }

In MVC app using JQGrid - how to set user data in the controller action

How do you set the userdata in the controller action. The way I'm doing it is breaking my grid. I'm trying a simple test with no luck. Here's my code which does not work. Thanks.
var dataJson = new
{
total =
page = 1,
records = 10000,
userdata = "{test1:thefield}",
rows = (from e in equipment
select new
{
id = e.equip_id,
cell = new string[] {
e.type_desc,
e.make_descr,
e.model_descr,
e.equip_year,
e.work_loc,
e.insp_due_dt,
e.registered_by,
e.managed_by
}
}).ToArray()
};
return Json(dataJson);
I don't think you have to convert it to an Array. I've used jqGrid and i just let the Json function serialize the object. I'm not certain that would cause a problem, but it's unnecessary at the very least.
Also, your user data would evaluate to a string (because you are sending it as a string). Try sending it as an anonymous object. ie:
userdata = new { test1 = "thefield" },
You need a value for total and a comma between that and page. (I'm guessing that's a typo. I don't think that would compile as is.)
EDIT:
Also, i would recommend adding the option "jsonReader: { repeatitems: false }" to your javascript. This will allow you to send your collection in the "rows" field without converting it to the "{id: ID, cell: [ data_row_as_array ] }" syntax. You can set the property "key = true" in your colModel to indicate which field is the ID. It makes it a lot simpler to pass data to the grid.

Resources