I'm trying to verify our fulfillment cloud function is only requested by Dialogflow.
The recommended solution is "Verifying requests" but, in our case, we are using Dialogflow, not Actions SDK:
const {dialogflow} = require('actions-on-google');
const fulfillment = dialogflow({
clientId: "clientIdDialogflow",
debug: true,
verification: "projectId"
});
fulfillment.intent("bienvenida", (conv) => { commonsDialogController.wellcomeFunction(conv) });
...etc
Is it possible use this to verify a request in Dialogflow or only is available in Actions SDK?
If in Dialogflow, and it is not possible use this, we have to retrieve the header and to process JWT, but in the logs the authorization header is not present. The headers are:
Headers { "host": "URL.cloudfunctions.net", "user-agent": "Google-Dialogflow", "transfer-encoding": "chunked", "accept": "*/*", "accept-encoding": "gzip,deflate,br", "content-type": "application/json", "forwarded": "for=\"X.X.X.X\";proto=https", "function-execution-id": "7868dfgr656", "x-appengine-country": "ZZ", "x-appengine-default-version-hostname": "aaaaa-tp.appspot.com", "x-appengine-https": "on", "x-appengine-request-log-id": "id", "x-appengine-user-ip": "X.X.X.X", "x-cloud-trace-context": aaaaaa/aaaa=1", "x-forwarded-for": "X.X.X.X", "x-forwarded-proto": "https", "connection": "close" }
The error in the response is:
{ "status": 403, "body": { "error": "A verification header key was not found" }, "headers": { "content-type": "application/json;charset=utf-8" } }
check out this answered question regarding Dialogflow verification.
You can set verification headers on the Dialogflow console and verify it with the fulfillment library like so:
const app = dialogflow({
verification: {
HEADER_KEY: 'HEADER_VALUE',
},
})
In the Dialogflow console, you can set the header key and value under Fulfillment > Webhook > HEADERS.
Related
so I want to make search request to my elastic enterprise search app using guide from the documentation in here , I don't want to use elastic node JS client, but I want to make http request using axios.
here is the code I use
const url = "https://XXXXXXX38ce49e5aff1aa238e6f9195.ent-search.asia-southeast1.gcp.elastic-cloud.com/api/as/v1/engines/events/search"
const headers = {"Authorization": "Bearer search-qpz4bu5o7ubb8j31r15juyrh"}
const jsonData = {
query: "hello there"
}
try {
const {data} = await axios.post(url,jsonData,headers)
response.status(200).send(data)
} catch (error) {
console.log(error)
response.status(500).send(error)
}
but I always get 401 error like this:
{
"message": "Request failed with status code 401",
"name": "Error",
"stack": "Error: Request failed with status code 401\n at createError (/Users/xxx/Documents/elastic_jxxx/firebase_emulator/functions/node_modules/axios/lib/core/createError.js:16:15)\n at settle (/Users/xxxx/Documents/elastic_jakarta_kumpul_muslim/firebase_emulator/functions/node_modules/axios/lib/core/settle.js:17:12)\n at IncomingMessage.handleStreamEnd (/Users/xxxxx/Documents/elastic_xxxxx/firebase_emulator/functions/node_modules/axios/lib/adapters/http.js:244:11)\n at IncomingMessage.emit (events.js:203:15)\n at endReadableNT (_stream_readable.js:1145:12)\n at process._tickCallback (internal/process/next_tick.js:63:19)",
"config": {
"url": "https://XXXXXXXa638ce49e5aff1aa238e6f9195.ent-search.asia-southeast1.gcp.elastic-cloud.com/api/as/v1/engines/events/search",
"method": "post",
"data": "{\"query\":\"hello there\"}",
"headers": {
"Accept": "application/json, text/plain, */*",
"Content-Type": "application/json;charset=utf-8",
"User-Agent": "axios/0.20.0",
"Content-Length": 28
},
"transformRequest": [
null
],
"transformResponse": [
null
],
"timeout": 0,
"xsrfCookieName": "XSRF-TOKEN",
"xsrfHeaderName": "X-XSRF-TOKEN",
"maxContentLength": -1,
"maxBodyLength": -1,
"Authorization": "Bearer search-qpz4bu5o7ubb8j31r15juyrh"
}
}
I believe I have put the correct search key, I can get the sucessful response using the same baseURL and search key in postman like this
what went wrong in here ?
The headers need to be passed as a named object in the config part.
So try it like this:
const {data} = await axios.post(url, jsonData, { headers: headers })
or even more concisely:
const {data} = await axios.post(url, jsonData, { headers })
Tip: Postman is capable of pre-constructing axios requests when you click on Code. So next time you're not sure, Postman is here to help:
Using Chrome dev tools I can see all the requests made. I want to replicate one of them using a script. The request is replicable as replaying it from dev tools works. I'm using this code:
let request = require("request");
request.put("<hidden>", {
"headers": {
":authority": "<hidden>",
":method": "PUT",
":path": "/api/<hidden>",
":scheme": "https",
"accept": "*/*",
"accept-encoding": "gzip, deflate, br",
"accept-language": "en-US",
"authorization": "<hidden>",
"content-length": "0",
// and more
}
}, (err, response, body) => {
console.log(err);
console.log(response.statusCode);
console.log(body);
});
The console says:
TypeError [ERR_INVALID_HTTP_TOKEN]: Header name must be a valid HTTP token [":authority"]
at ClientRequest.setHeader (_http_outgoing.js:487:3)
at new ClientRequest (_http_client.js:221:14)
at Object.request (https.js:309:10)
at Object.request (C:\Users\Admin\AppData\Roaming\npm\node_modules\puppeteer-core\node_modules\agent-base\patch-core.js:25:22)
at Request.start (C:\Users\Admin\AppData\Roaming\npm\node_modules\request\request.js:751:32)
at Request.end (C:\Users\Admin\AppData\Roaming\npm\node_modules\request\request.js:1505:10)
at end (C:\Users\Admin\AppData\Roaming\npm\node_modules\request\request.js:564:14)
at Immediate._onImmediate (C:\Users\Admin\AppData\Roaming\npm\node_modules\request\request.js:578:7)
at processImmediate (internal/timers.js:439:21) {
code: 'ERR_INVALID_HTTP_TOKEN'
}
I tried not using .put(), or specifying method and body properties. Same results.
Headers that show with a leading colon are "pseudo-headers". You don't actually send them yourself with the request() library as they are an illegal http 1.1 header format.
You can read about them here: Purpose of pseudo colon-header fields.
You should be able to remove all the pseudo-headers and just make sure that the information in them is properly specified elsewhere in your request (url, method, etc...) which they would normally already be.
I'm facing a problem with the validation of the notification url when I want to register a subscription with the outlook API.
The options passed in the request are :
var optionsSubscription = {
url: "https://outlook.office.com/api/v2.0/me/subscriptions",
method: "POST",
headers: {
"authorization": "Bearer " + user.outlookCalAccessToken,
"accept": "application/json",
"ContentType": "application/json",
},
json: {
"#odata.type": "#Microsoft.OutlookServices.PushSubscription",
"Resource": "me/events",
"NotificationURL": "https://xxx/callback",
"ChangeType": "Created,Deleted,Updated"
},
"Content-Type": "application/json"
}
The response is the following :
Notification URL 'https://xxx/callback?validationtoken=N2FhY2JhNmItYTc2MC00MGUwLThmOGItZWQ2N2Q5Nzg5Y2Y2' verification failed System.Net.WebException:
The request was aborted: Could not create SSL/TLS secure channel.
at System.Net.HttpWebRequest.GetResponse()
at Microsoft.Exchange.OData.Model.Notifications.PushNotification.PushSubscriptionCallbackUrlValidationHelper.SendRequestAndVerifyResponse (Uri callbackUrl, PushSubscription pushSubscription).
When I request the notification url with Postman, it works and returns the validation token with a 200 status as expected.
The SSL certificate is generated with let's encrypt.
I programmed a Node.JS Server with FCM and POST Protocol and my Client app is made with Swift code.
In Terminal, It prints success code like this
id=0:1476620858011270%00f7ba1cf9fd7ecd
But In my Client App, there is no notification. So I tried with the notification tab in my Firebase Console, and it worked very well.
This is my header in my server file
var headers = {
'Content-Type': 'application/json',
'Authorization': 'key=<Server Key>',
'project_id': '<Project ID>'
}
and This is my Request Code
request({
headers: headers,
url: "https://fcm.googleapis.com/fcm/send",
method: "POST",
form: {
"notification" :{
"title": "titie",
"body": "body"
},
"content-available": true,
"priority": "high",
"to": "<Firebase Token>"
}
}, function(error, response, body) {
console.log(body);
});
I try to listen on my calendar change events (google-apps/calendar/v3/reference/events/watch).
I did everything from Google console side, domains - OK, everything is verified and I succeeded to create channel. Also i succeeded to get sync message with right headers (see below). From docs:
Sync message
After creating a new notification channel to watch a resource, the
Google Calendar API sends a sync message to indicate that
notifications are starting. The X-Goog-Resource-State HTTP header
value for these messages is sync. Because of network timing issues, it
is possible to receive the sync message even before you receive the
watch method response.
That mean that notifications are starting
However when I change something in snaggs#comp.com account -
nothing happens, no request sends to callback : 'https://dev-api.mycompany/google-watch/'
This is my working code:
var google = require('googleapis');
var googleAuth = require('google-auth-library');
var _ = require('underscore-node');
var uuid = require('node-uuid');
// ......
var channel_id = uuid.v1();
_auth.credentials = {
access_token: _token.access_token,
token_type: _token.token_type,
refresh_token: _token.refresh_token,
expiry_date: _token.expiry_date
};
var data = {
auth: _auth,
calendarId: _token.provider_email,
singleEvents: true,
orderBy: 'startTime',
resource: {
id: channel_id,
token: 'email='+_token.provider_email,
address: 'https://dev-api.mycompany/google-watch/',
type: 'web_hook',
params: {
ttl: '36000'
}
}
};
calendar.events.watch(data, function (err, response) {
if (err) {
console.error('The API returned an error: ' + err);
return;
}
});
When I start above mentioned snippets of code i get response:
{
"kind": "api#channel",
"id": "277fa000-d4b6-12e5-ab58-e7afaf85ea65",
"resourceId": "C7vFL07CYfqaHy3vDss4qugWDfk",
"resourceUri": "https://www.googleapis.com/calendar/v3/calendars/snaggs#comp.com/events?orderBy=START_TIME&singleEvents=true&alt=json",
"token": "email=snaggs#comp.com",
"expiration": "1455667451000"
}
And in 'https://dev-api.mycompany/google-watch/' URL I get sync message regards to documents, like (See google-apps/calendar/v3/push):
{
"host": "dev-api.mycompany",
"accept": "*/*",
"accept-encoding": "gzip,deflate",
"user-agent": "APIs-Google; (+https://developers.google.com/webmasters/APIs-Google.html)",
"x-goog-channel-expiration": "Tue, 16 Feb 2016 22:44:51 GMT",
"x-goog-channel-id": "277fa000-d4b6-12e5-ab58-e7afaf85ea65",
"x-goog-channel-token": "email=snaggs#comp.com",
"x-goog-message-number": "1",
"x-goog-resource-id": "C7vFL07CYfqaHy3vDss4qugWDfk",
"x-goog-resource-state": "sync",
"x-goog-resource-uri": "https://www.googleapis.com/calendar/v3/calendars/snaggs#comp.com/events?orderBy=START_TIME&singleEvents=true&alt=json",
"x-forwarded-for": "56.102.7.132",
"x-forwarded-port": "443",
"x-forwarded-proto": "https",
"content-length": "0",
"connection": "keep-alive"
}
but not exists message
Do I miss something?
please help,
We have been using Push Notifications for a few years and noticed that for the last 24 hours we did not receive any notifications across several thousand calendars.
Like you we can create/stop a channel but no notifications are received for changes as normal.
As of about an hour ago we are receiving them again. Please try your channel again as it may be a glitch on the Google Push side of things that has been resolved.