Actions on Google Fulfillment Response - php

When you receive a request, your fulfillment must return a response
I have a HTTPS endpoint which receives commands sent thru the google assistant(My Fulfilment URL). But i want to return a text to the user for every request made
Eg:
USER REQUEST : "Tell, 'app name' to do blah blah"
ASSISTANT RESPONSE : "Okay, sure"
As documented in this article --> https://developers.google.com/actions/components/fulfillment (RESPONSE FORMAT) , I have coded the json file according to the format said in the above link
But it says your fulfillment must return a response
RESPONSE.JSON
"finalResponse": {
"richResponse": {
"items": [
{
"simpleResponse": {
"textToSpeech": "sure thing",
"displayText": "Sure, thing!"
}
]
}
}
In my Fulfilment end point i did the above.
fulfilment.php
$file = [
"expectUserResponse" => false,
"finalResponse" => [
"richResponse" => [
"items" => [
[
"simpleResponse" => [
"textToSpeech" => "Sure thing!",
"displayText" => "Sure, thing?"
]
]
]
]
]
];
echo json_encode($file);
header('Content-Type: application/json');
How do i return this file in php back to google assistant?
I am using PHP :)

For starters - that isn't valid JSON. Valid JSON would look something like this:
{
"finalResponse": {
"richResponse": {
"items": [{
"simpleResponse": {
"textToSpeech": "sure thing",
"displayText": "Sure, thing!"
}
}]
}
}
}
Notice the opening and closing brackets to designate that this is a JSON object. What you're sending is a string that has been encoded as a JSON string. Using PHP, the easiest way to create valid JSON is to use json_encode and pass it a nested associative array. So something like this would generate it.
<?php
header('Content-Type: application/json');
$a = [
"finalResponse" => [
"richResponse" => [
"items" => [
[
"simpleResponse" => [
"textToSpeech" => "Sure thing!",
"displayText" => "Sure, thing?"
]
]
]
]
]
];
echo json_encode($a);
Note that the header() must come before anything, even a blank line, has been sent.
However... that might not be your only problem.
This doesn't look like it has all the fields that you should reply. If you're only sending a finalResponse, then you probably also need to set expectUserResponse to false.
(And are you sure that you want to end the conversation every time?)

Related

Laravel - Array to string conversion issue

I want to send request via post method with API, and when sending values, sometimes I need to send two values instead of one, and for this I need to loop it. The solution to this is, before sending the request, I save it to the array in the loop and try to complete the process by making json_encode.
My explanation may not be fully explanatory, so I will explain through the codes.
The request I want to throw is normally like this:
CURLOPT_POSTFIELDS =>'
[
{
"items":
[
{
"name":"string",
"sku":"string",
}
],
}
]'
But some times the items value needs to have two instead of one. For example:
CURLOPT_POSTFIELDS =>'
[
{
"items":
[
{
"name":"string",
"sku":"string",
},
{
"name":"string",
"sku":"string",
}
],
}
]'
So before i make this request i am saving these values to array in a foreach loop.
$data =array();
foreach ($request->orderItems as $orderItemId) {
$order_item = OrderItem::where('orderItemId',$orderItemId)->first();
$data[] = array(
"sku"=> $order_item->sku,
"name"=> $order_item->name,
)
}
And if I'm going to send more than one value, my final code looks like this.
CURLOPT_POSTFIELDS =>'
[
{
"items": '.json_encode($data).',
}
]'
Here is where the problem starts and when i try to send this request i get this error:
Array to string conversion
What should I do exactly? Where am I missing?
You might be missing the Content-Type header for your cURL call.
CURLOPT_HTTPHEADER => [
'Content-Type' => 'application/json',
],
Try to encode all the content in CURLOPT_POSTFIELDS like this way
$array = [
array(
"name" => "string",
"sku" => "string",
),
array(
"name" => "string",
"sku" => "string",
)
];
$final = json_encode([["items" => $array]]);
//now use this variable directly in CURLOPT_POSTFIELDS
CURLOPT_POSTFIELDS => $final
may it helps ....

How can i set a dynamic date for a JSON value?

Im trying to set a POST request to a file in my website with some data in JSON. There is a value response that needs to be a dynamic date so when the request is made the current date is saved in a custom field. How can i set up the code under "value" so the date is generated?
Have tried things like "variable":{ new Date(), } but can't make it work since always ends displaying the code and not a date, or the code is not validated if i add [ or { , etc.
{
"version": "v2",
"content": {
"messages": [],
"actions": [{
"action": "set_field_value",
"field_name": "bday_reg_date",
"value": "2019-06-22"
}, {
"action": "set_field_value",
"field_name": "bday_exp_date",
"value": "2019-06-29"
}
That's the code im basing mine. Everytime i access the file (apparently a .php file), a new date is generated on "value", that date is send and to a custom field called reg_date on another platform. What should be the correct way to get that dynamic value?
Thanks.
If your are trying to create a new json object in PHP you have to create an array first then use the json_encode($arr) function to convert it to json.
https://www.php.net/manual/en/function.json-encode.php
IE:
<?php
$dateNow = new DateTime('now');
$dateNextWeek = new DateTime('now');
$dateNextWeek->modify('+1 week');
$arr = [
'version' => 'v2',
'content' => [
'messages' => [],
'actions' => [
[
'action' => 'set_field_value',
'field_name' => 'bday_reg_date',
'value' => $dateNow->format('d-m-Y'),
],
[
'action' => 'set_field_value',
'field_name' => 'bday_reg_date',
'value' => $dateNextWeek->format('d-m-Y'),
],
]
]
];
return json_encode($arr);

Elasticsearch in php doesn't recognize dash

I'm working on a project and try to make a search with elasticsearch but my field can contain dash and when I search with it I can't find the result I'm looking for, so I tried to change the mapping but the index doesn't work at all. I don't have any error message but I can't find what I indexed even using a different field. So what I did was :
$params = [
'index' => 'arc',
'type' => 'purchase',
'id' => $purchase['id'],
'body' => $purchase
];
It worked great with that except for the field with the dash. My $purchase looks like that :
array:34 [
"id" => 163160
"distant" => "MOR-938BBM28147090"
[...]
]
so when I search for "MOR" I find the result but when I do "MOR-" nothing. I tried to change the mapping by doing that :
$params = [
'index' => 'arc',
'type' => 'purchase',
'id' => $purchase['id'],
'body' => [
'mappings' => [
'_default_' => [
'properties' => [
'distant' => [
'type' => 'string',
'index' => 'not_analyzed'
]
]
]
],
$purchase
]
];
But with that even if I try to search "163160" I can't find any result.
Whitespace analyzer could be the right solution in this case. It takes into account only whitespaces while breaking text into tokens, and characters like "-" or "_" are still treated as a part of a term.
But if you need to do a partial matching, for example with "MOR-" token, then it requires a bit more complicated mapping.
As I don't know php, I'll be using Elasticsearch syntax. First, create a proper mapping:
PUT http://127.0.0.1:9200/arc
{
"settings": {
"analysis": {
"analyzer": {
"edge_ngram_analyzer": {
"tokenizer": "my_tokenizer"
}
},
"tokenizer": {
"my_tokenizer": {
"type": "edge_ngram",
"min_gram": 3,
"max_gram": 18,
"token_chars": [
"letter",
"digit",
"punctuation"
]
}
}
}
},
"mappings": {
"purchase": {
"properties": {
"distant": {
"type": "string",
"analyzer": "edge_ngram_analyzer"
}
}
}
}
}
As you can see, I use EdgeNGram tokenizer here. When you index a document with MOR-938BBM28147090 in distant field, it will create following tokens:
[MOR, MOR-, MOR-9, MOR-93, MOR-938, MOR-938B, MOR-938BB, ...]
The core point here is punctuation character class in token_chars list, that tells elasticsearch, that dash character (and some others like ! or ") should be included in a token and not treated as a "split char".
Now when I index the document:
PUT http://127.0.0.1:9200/arc/purchase/163160
{
"distant": "MOR-938BBM28147090"
}
and run a term search query:
POST http://127.0.0.1:9200/arc/purchase/_search
{
"query": {
"bool" : {
"must" : {
"term" : {
"distant": "MOR-93"
}
}
}
}
}
I get in response:
"hits": {
"total": 1,
"max_score": 0.6337049,
"hits": [
{
"_index": "arc",
"_type": "purchase",
"_id": "163160",
"_score": 0.6337049,
"_source": {
"distant": "MOR-938BBM28147090"
}
}
]
}

Facebook messenger bot generic template not working

I am building a Facebook bot using api.ai and I have gotten to a point where I need to send responses using Facebook generic template. I fetch the list of items to listed from the database and put them in an array and assign to a variable. My problem is that the data is actually returned as shown by Ngrok but it not shown on Facebook as a generic template. Nothing shows. Here is my code.
while($result = mysqli_fetch_assoc($res)){
$array[] = array(
"title"=> $result['title'],
"image_url"=> $result['img_url'],
"subtitle"=> "See all our colors",
"buttons"=>[
[
"type"=>"postback",
"title"=>$result['title'],
"payload"=>$result['payload_id']
]
]
);
}
if ($intentName == "sex"){
$data =json_encode([
'speech' => "Hi ".$firstname,
'displayText' => "test",
'source' => "source",
'data' => ["facebook" => [
"attachment"=>[
"type"=>"template",
"payload"=>[
"template_type"=>"generic",
"elements"=>[
//One attachment
$array
//First attachment ends
]
]
] ]
]
]);
echo $data;
}
I solved it. It should have been:
"elements"=> $array

elasticsearch php search exists

How might one do the following request
GET /giata_index/giata_type/_search/exists
{
"query": {
"bool": {
"must": [
{
"term": {
"status": 2
}
},
{
"term": {
"ids": "26744"
}
}
]
}
}
}
with ElasticSearch's PHP library?
I have played around with the exists endpoint, but as it turns out, that can only check whether a specific uid is existant or not. So I guess I need to do a search. But I can't find a parameter in the Search endpoints's whitelist that would allow a simple check for exists or not.
The reason why I would like to avoid getting the entire document and just ask whether it exists or not is because I have multiple hundreds of thousands of imports and just as many documents in ES, so I would like it to put as little work into it as possible.
Note: I have also looked into head requests that are possible via HTTP requests (only retrieve the header of a document - either 200 or 404). But that would probably only exist for requests via HTTP.
If worse comes to worse I could shoot a curl via php and simply do it via HTTP. But I would prefer it otherwise.
It seems indeed that there's no endpoint voor search exists, but I think you use a simple alternative:
Use an empty "fields" array. And count the results of your query. If == 0: false. If > 0: true
GET /giata_index/giata_type/_search
{
"fields": [],
"query": {
"bool": {
"must": [
{
"term": {
"status": 2
}
},
{
"term": {
"ids": "26744"
}
}
]
}
}
}
An other alternative is to use _count : https://www.elastic.co/guide/en/elasticsearch/reference/1.6/search-count.html
It should be possible with the latest 2.x version.
Code sample could be something like this:
$clientBuilder = Elasticsearch\ClientBuilder::create();
// Additional client options, hosts, etc.
$client = $clientBuilder->build();
$index = 'your_index';
$type = 'your_type';
$params = [
'index' => $index,
'type' => $type,
'body' => [
'query' => [
'bool' => [
'must' => [
[
'term' => [
"status" => 2
]
],
[
'term' => [
'ids' => "26744"
]
]
]
]
]
];
try {
$client->searchExists($params);
} catch (Exception $e) {
// Not found. You might want to return FALSE if wrapped in a function.
// return FALSE;
}
// Found.
It is worth noting that if search is not wrapped in try/catch block it can break execution and throw an exception (status code 4xx if not found).
Also, it can not be used effectively in future mode.

Categories