How to send extra data to DialogFlow while calling it using some SDK?
I understand that in v1, originalRequest.data was used for this purpose.
Basically I want to send username, mobile number etc from website session and pass it to DialogFlow so that I can get it in webhook and perform some operation.
I am using below code to call DialogFlow:
import dialogflow
def detect_intent_texts(text, session_id):
session_client = dialogflow.SessionsClient()
session = session_client.session_path(project_id, session_id)
text_input = dialogflow.types.TextInput(
text=text, language_code=language_code)
query_input = dialogflow.types.QueryInput(text=text_input)
response = session_client.detect_intent(
session=session, query_input=query_input)
return response.query_result.fulfillment_text
detect_intent_texts('hello how are you', 'some_session_id')
You need to set parameters in the context.
create a context
add parameter
extract the context and parameter in the next interaction.
In JSON, it will look like this
{
"fulfillmentText":"This is a text response",
"fulfillmentMessages":[ ],
"source":"example.com",
"payload":{
"google":{ },
"facebook":{ },
"slack":{ }
},
"outputContexts":[
{
"name":"context name",
"lifespanCount":5,
"parameters":{
"param":"param value"
}
}
],
"followupEventInput":{ }
}
You can take a look how it can be done in python using create_context in dialogflow-python-client
Related
I have 4 API request for money transfer
Authorize
GetBeneficiary
AddBenificiary
RequestTransfer
Now I need to get the result of request transfer and return to the UI and say 'Transfer is successful', and also if any of those API fail in between I need to send to the UI.
I have return something like this:
authorize(){
getBeificiary();
}
getBeificiary(){
if(no benificiary){
addBeificiary();
}else{
requestTransfer();
}
addBenificiary(){
requestTransfer();
}
requestTransfer(){
return 'message';
}
use like this:
var response=Future.wait([<list of apis>]);
// use response as response[0], response[1] as respective to the apis given in the line.
I have a working GET request in Postman where the body contains the query as seen below
The body is as follows
{
"query": {
"bool": {
"must": [
{
"term": {
"Vrvirksomhed.cvrNummer": "12345678"
}
}
]
}
}
}
Now i'm trying to get the same GET to work in Aure Data Factory but somehow it seems that the syntax needs to be different as it' doesn't use it correctly. Does it need to be wrapped somehow ?
This is because the ADF will ignore the Request body when your Request method is GET. So it can't work.
You can click '{}' button to view the code of Copy activity.
Even if your request body has content, there isn't requestBody property in source.
If you change your request method to POST, it will show.
So you can change your request method to POST to have a try.
I have to activate the properties to shuffle the question of a multiple choice type questoin, but I can't find the properties. I found this code that randomizes questions, but not the answers.
form.setShuffleQuestions(true);
Image of the visual component
Issuetracker:
This isn't currently possible. Consider adding a star (on top left) to the following feature requests for Google to prioritize the issue:
https://issuetracker.google.com/issues/36764938
https://issuetracker.google.com/issues/64134484
Partial worksround:
Partial Workaround as already mentioned in this answer is to shuffle the array creating options and setback the array using setChoiceValues(). The drawback of such server side randomizing is
It can only be done whenever the server script runs and not when client opens the form
Even if you randomize each minute, it is possible that users opening the form simultaneously will see the same order of options
Sample script:
const form = FormApp.openById('/*form id*/');
const item = form.addMultipleChoiceItem();
item.setTitle('Car or truck?');
const options = ['Truck', 'Car'];
//Durstenfeld algo
for (let i = options.length - 1; i > 0; i--) {
let rand = Math.floor(Math.random() * i);
[options[i], options[rand]] = [options[rand], options[i]];
}
item.setChoiceValues(options);
I believe that you have to randomize the options yourself with something like this:
function randomizeArray(A) {
var iA=A.slice();
var oA=[];
for(var i=0;i<A.length;i++) {
var index=Math.floor(Math.random()*iA.length);
oA.push(iA[index]);
iA.splice(index,1);
}
return oA;
}
Unfortunately, in the current sage, it seems that this cannot still be achieved by Google Forms service (FormApp).
But, On March 16, 2022, Google Forms API has been officially released. Ref By this, fortunately, I confirmed that your this question can be directly achieved using Google Forms API.
In the current stage, Google Forms API cannot be used with Advanced Google services. So it is required to do the following flow.
Usage:
1. Linking Google Cloud Platform Project to Google Apps Script Project for New IDE.
In order to use Forms API, please link Google Cloud Platform Project to Google Apps Script Project for New IDE, and please enable Forms API at the API console. Ref
When Google Forms API can be used with Advanced Google services, this process can be skipped.
2. Scope.
In order to use this sample script, please use the following scopes. Ref
https://www.googleapis.com/auth/script.external_request
https://www.googleapis.com/auth/forms
https://www.googleapis.com/auth/forms.body
When Google Forms API can be used with Advanced Google services, this process can be skipped.
3. Sample script:
Please copy and paste the following script to the script editor linked to Google Cloud Platform Project and save the script.
function myFunction() {
const formTitle = "sample"; // This is a form title.
// THis is an object for creating quizzes.
const obj = [
{ "question": "sample question 1", "answers": ["answer1", "answer2", "answer3"], "correct": ["answer1"], "point": 1, "type": "RADIO" },
];
// Create new Google Form and set as quize.
const form = FormApp.create(formTitle);
form.setIsQuiz(true).setTitle("Sample");
// form.setShuffleQuestions(true); // If you want to shuffle questions, you can use this line.
// Create request body for Google Forms API.
const url = `https://forms.googleapis.com/v1/forms/${form.getId()}:batchUpdate`;
const requests = obj.map(({ question, answers, correct, point, type }, index) => ({
createItem: {
item: {
title: question,
questionItem: { question: { choiceQuestion: { options: answers.map(value => ({ value })), shuffle: true, type }, grading: { correctAnswers: { answers: correct.map(e => ({ value: e })) }, pointValue: point } } },
}, location: { index }
}
}));
// Request to Google Forms API.
const params = {
method: "post",
contentType: "application/json",
headers: { authorization: "Bearer " + ScriptApp.getOAuthToken() },
payload: JSON.stringify({ requests }),
muteHttpExceptions: true
};
const res = UrlFetchApp.fetch(url, params);
console.log(res.getContentText())
}
When this script is run, as a sample, a new Google Form is created, and a sample question including the radio button is set. And, you can confirm that "Shuffle option order" is checked.
References:
Linking Google Cloud Platform Project to Google Apps Script Project for New IDE
Method: forms.batchUpdate
So I'm writing a chatbot application which requires the intake of parameters and then uses these parameters in post requests sent via a payload.
I'm having problems with grabbing the context value from a context variable within swift and was wondering how I would go about grabbing the value of the context variable and executing an action based on the value of that said context.
An example of this would be the following dialog flow...
Me: Trigger this
Bot: Ok, give me param x
Me: x
Bot: Ok I have x param, will post job now
This is the kind of flow I want to happen in the background of my application under the hood but I'm not sure how to grab value x after my user has input it.
So, suppose that you are using the iOS SDK from Watson Developer Cloud.
In your Conversation, add in your node:
{
"context": {
"myVariable": "<? input.text ?>"
},
"output": {
"text": {
"values": [
"My context variable value is $myVariable."
],
"selection_policy": "sequential"
}, { "etc": "etc" }
Obs.: The input.text will capture all that user types, you need to use regex for extract exactly what you want, try to see my examples in this answer.
And, in the iOS SDK you can see this follow example:
func testMessage() {
let description1 = "Start a conversation."
let expectation1 = self.expectation(description: description1)
let response1 = ["Hi. It looks like a nice drive today. What would you like me to do?"]
let nodes1 = ["node_1_1467221909631"]
var context: Context?
conversation.message(workspaceID: workspaceID, failure: failWithError) {
response in
// verify input
XCTAssertNil(response.input?.text)
// verify context
XCTAssertNotNil(response.context.conversationID)
XCTAssertNotEqual(response.context.conversationID, "")
XCTAssertNotNil(response.context.system)
XCTAssertNotNil(response.context.system.additionalProperties)
XCTAssertFalse(response.context.system.additionalProperties.isEmpty)
// verify entities
XCTAssertTrue(response.entities.isEmpty)
// verify intents
XCTAssertTrue(response.intents.isEmpty)
// verify output
XCTAssertTrue(response.output.logMessages.isEmpty)
XCTAssertEqual(response.output.text, response1)
XCTAssertEqual(response.output.nodesVisited!, nodes1)
context = response.context
expectation1.fulfill()
}
So, you can access your context variable using:
context.myVariable
response.context.myVariable
See more about methods in Watson Conversation here.
iOS SDK from Watson Developer Cloud.
I have a minimal (example) REST end-point test/people.cfc:
component
restpath = "test/people/"
rest = true
{
remote void function create(
required string first_name restargsource = "Form",
required string last_name restargsource = "Form"
)
httpmethod = "POST"
restpath = ""
produces = "application/json"
{
// Simulate adding person to database.
ArrayAppend(
Application.people,
{ "first_name" = first_name, "last_name" = last_name }
);
// Simulate getting people from database.
var people = Application.people;
restSetResponse( {
"status" = 201,
"content" = SerializeJSON( people )
} );
}
}
As noted here and in the ColdFusion documentation:
Note: ColdFusion ignores the function's return value and uses the response set using the RestSetResponse() function.
So the void return type for the function appears to be correct for the REST function.
Now, I know I can call it from a CFM page using:
httpService = new http(method = "POST", url = "https://localhost/rest/test/people");
httpService.addParam( name = "first_name", type = "formfield", value = "Alice" );
httpService.addParam( name = "last_name", type = "formfield", value = "Adams" );
result = httpService.send().getPrefix();
However, I would like to call the function without making a HTTP request.
Firstly, the REST CFCs do not appear to be accessible from within the REST directory. This can be solved simply by creating a mapping in the ColdFusion admin panel to the root path of the REST service.
I can then do:
<cfscript>
Application.people = [];
people = new restmapping.test.People();
people.create( "Alice", "Adams" );
WriteDump( application.people );
</cfscript>
This calls the function directly and the output shows it has added the person. However, the response from the REST function has disappeared into the aether. Does anyone know if it is possible to retrieve the response's HTTP status code and content (as a minimum - preferably all the HTTP headers)?
Update - Integration Testing Scenario:
This is one use-case (of several) where calling the REST end-point via a HTTP request has knock-on effects that can be mitigated by invoking the end-point directly as a method of a component.
<cfscript>
// Create an instance of the REST end-point component without
// calling it via HTTP request.
endPoint = new restfiles.test.TestRESTEndPoint();
transaction {
try {
// Call a method on the end-point without making a HTTP request.
endPoint.addValueToDatabase( 1, 'abcd' );
assert( getRESTStatusCode(), 201 );
assert( getRESTResponseText(), '{"id":1,"value":"abcd"}' );
// Call another method on the end-point without making a HTTP request.
endPoint.updateValueInDatabase( 1, 'dcba' );
assert( getRESTStatusCode(), 200 );
assert( getRESTResponseText(), '{"id":1,"value":"dcba"}' );
// Call a third method on the end-point without making a HTTP request.
endPoint.deleteValueInDatabase( 1 );
assert( getRESTStatusCode(), 204 );
assert( getRESTResponseText(), '' );
}
catch ( any e )
{
WriteDump( e );
}
finally
{
transaction action="rollback";
}
}
</cfscript>
Calling each REST function via a HTTP request will commit the data to the database after each request - cleaning up between tests where the data has been committed can get very complicated and often results in needing to flashback the database to a previous state (resulting in integration tests being unable to be run in parallel with any other tests and periods of unavailability during flashbacks). Being able to call the REST end-points without making lots of atomic HTTP requests and instead bundle them into a single transaction which can be rolled back means the testing can be performed in a single user's session.
So, how can I get the HTTP status code and response text which have been set by RestSetResponse() when I create an instance of the REST component and invoke the function representing the REST path directly (without using a HTTP request)?
#MT0,
The solution will* involve a few steps:
Change remote void function create to remote struct function create
Add var result = {"status" = 201, "content" = SerializeJSON( people )}
Change your restSetResponse(..) call to restSetResponse(result)
Add return result;
* The solution will not currently work, b/c ColdFusion ticket CF-3546046 was not fixed completely. I've asked Adobe to re-open it and also filed CF-4198298 to get this issue fixed, just in case CF-3546046 isn't re-opened. Please see my most recent comment on CF-3546046, and feel free to vote for either ticket. Once either is fixed completely, then the above-listed changes to your code will allow it to set the correct HTTP response when called via REST and to return the function's return variable when invoked directly. Note: you could also specify a headers struct w/in the result struct in step 2, if you also want to return headers when the function is invoked directly.
Thanks!,
-Aaron Neff