I try to send an API request with cy.request but there seems to be something wrong with the data format. My code looks as follows:
cy.request({
url: Cypress.env("RtmApiUrl") + "/test-plan/",
method: "POST",
headers: {
"Authorization": "Bearer " + Cypress.env('RtmApiToken'),
"content-type": "application/json",
body: {
"projectKey": "QAIR",
"summary": "API Test Regression",
"description": "Full regression",
"parentTestKey": "F-QAIR-TP-8",
"priority": {
"id": 3,
"name": "Medium"
},
"status": {
"id": 10005,
"name": "Backlog"
},
"includedTestCases": []
},
},
});
And the console output from Cypress Test Runner:
CypressError: `cy.request()` failed on:
https://rtm-api.hexygen.com/api/test-plan/
The response we received from your web server was:
> 400: Bad Request
This was considered a failure because the status code was not `2xx` or `3xx`.
If you do not want status codes to cause failures pass the option: `failOnStatusCode: false`
-----------------------------------------------------------
The request we sent was:
Method: POST
URL: https://rtm-api.hexygen.com/api/test-plan/
Headers: {
"Connection": "keep-alive",
"Authorization": "Bearer <some Token>",
"content-type": "application/json",
"body": {
"projectKey": "QAIR",
"summary": "API Test Regression",
"description": "Full regression",
"parentTestKey": "F-QAIR-TP-8",
"priority": {
"id": 3,
"name": "Medium"
},
"status": {
"id": 10005,
"name": "Backlog"
},
"includedTestCases": []
},
"user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36",
"accept": "*/*",
"accept-encoding": "gzip, deflate",
"content-length": 0
}
-----------------------------------------------------------
The response we got was:
Status: 400 - Bad Request
Headers: {
"server": "Cowboy",
"connection": "keep-alive",
"x-content-type-options": "nosniff",
"x-xss-protection": "1; mode=block",
"cache-control": "no-cache, no-store, max-age=0, must-revalidate",
"pragma": "no-cache",
"expires": "0",
"strict-transport-security": "max-age=31536000 ; includeSubDomains",
"x-frame-options": "DENY",
"content-type": "application/json",
"content-length": "69",
"date": "Tue, 13 Jul 2021 07:32:36 GMT",
"via": "1.1 vegur"
}
Body: {
"errorMessages": [
"No content to map to Object due to end of input"
]
}
I already tried the same combination of header and body with Postman and curl and it worked. Is there something I missed?
Any help is appreciated. Thanks in advance.
Folks, I missed a bracket at the end of the headers block. So this was a real classic layer 8 issue...
cy.request({
url: Cypress.env("RtmApiUrl") + "/test-plan/",
method: "POST",
headers: {
"Authorization": "Bearer " + Cypress.env('RtmApiToken'),
"content-type": "application/json"
},
body: {
"projectKey": "QAIR",
"summary": "API Test Regression",
"description": "Full regression",
"parentTestKey": "F-QAIR-TP-8",
"priority": {
"id": 3,
"name": "Medium"
},
"status": {
"id": 10005,
"name": "Backlog"
},
"includedTestCases": []
},
},
});
Related
I am sending a request from a Nuxt3 SSR app (test.example.com) to a custom strapi endpoint (test-backend.example.com)
I'm making the call from Nuxt3 like this from app.vue
<script setup>
import { useStore } from '#/stores/index'
let data = reactive({})
[data] = await Promise.all([
useFetch(`${useRuntimeConfig().API_URL}api/debug`),
])
store.setApiData(data.data)
</script>
To hit this custom strapi endpoint at /api/debug
module.exports = {
async debug(ctx, next) {
ctx.body = {
ctx: ctx,
reqOrigin: ctx.request.origin,
}
}
};
Reading the request headers using ctx.request.origin returns the backend host and not the frontend host.
"ctx": {
"request": {
"method": "GET",
"url": "/api/debug",
"header": {
"host": "test-backend.example.com",
"x-real-ip": "203.96.140.24",
"x-forwarded-for": "203.96.140.24",
"connection": "close",
"cache-control": "no-cache",
"postman-token": "946f9d5f-b9b6-4dc0-a52b-95fd84b81de8",
"user-agent": "PostmanRuntime/7.6.0",
"accept": "*/*",
"accept-encoding": "gzip, deflate"
}
},
"response": {
"status": 200,
"message": "OK",
"header": {
"content-security-policy": "connect-src 'self' https:;img-src 'self' data: blob:;media-src 'self' data: blob:;default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline'",
"x-dns-prefetch-control": "off",
"expect-ct": "max-age=0",
"x-frame-options": "SAMEORIGIN",
"strict-transport-security": "max-age=31536000; includeSubDomains",
"x-download-options": "noopen",
"x-content-type-options": "nosniff",
"x-permitted-cross-domain-policies": "none",
"referrer-policy": "no-referrer",
"vary": "Origin",
"content-type": "application/json; charset=utf-8",
"x-powered-by": "Strapi <strapi.io>"
}
},
"app": {
"subdomainOffset": 2,
"proxy": false,
"env": "production"
},
"originalUrl": "/api/debug",
"req": "<original node req>",
"res": "<original node res>",
"socket": "<original node socket>"
},
"reqOrigin": "http://test-backend.example.com"
Logging ctx on the backend shows that ctx.request.header.host is test-backend.example.com. I was expecting host to be text.example.com where the fetch originated from. Not the host to which the request was being sent.
How do I get the request host and not the servers host?
Why does changing the maxResults parameter cause the resultSizeEstimate to drastically change when calling gmail.users.messages.list()?
The Google API docs lists resultSizeEstimate as: Estimated total number of results.
... which means this final result set should not change just by altering the number of items returned per page.
Example A: maxResults: 1 ... resultSizeEstimate: 8
{
"config": {
"url": "https://www.googleapis.com/gmail/v1/users/me/messages?q=before%3A2021%2F1%2F9&maxResults=1",
"method": "GET",
"headers": {
"Accept-Encoding": "gzip",
"User-Agent": "google-api-nodejs-client/0.7.2 (gzip)",
"Authorization": "Bearer [snip]",
"Accept": "application/json"
},
"params": {
"q": "before:2021/1/9",
"maxResults": 1
},
"responseType": "json"
},
"data": {
"messages": [ ... ],
"nextPageToken": "14911817971227869758",
"resultSizeEstimate": 8
},
"headers": {
"alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-Q050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\"",
"cache-control": "private",
"connection": "close",
"content-encoding": "gzip",
"content-type": "application/json; charset=UTF-8",
"date": "Sun, 09 Jan 2022 12:59:48 GMT",
"server": "ESF",
"transfer-encoding": "chunked",
"vary": "Origin, X-Origin, Referer",
"x-content-type-options": "nosniff",
"x-frame-options": "SAMEORIGIN",
"x-xss-protection": "0"
},
"status": 200,
"statusText": "OK"
}
Example B: maxResults: 2 ... resultSizeEstimate: 12
{
"config": {
"url": "https://www.googleapis.com/gmail/v1/users/me/messages?q=before%3A2021%2F1%2F9&maxResults=2",
"method": "GET",
"headers": {
"Accept-Encoding": "gzip",
"User-Agent": "google-api-nodejs-client/0.7.2 (gzip)",
"Authorization": "Bearer [snip]",
"Accept": "application/json"
},
"params": {
"q": "before:2021/1/9",
"maxResults": 2
},
"responseType": "json"
},
"data": {
"messages": [ ... ],
"nextPageToken": "16903415066875011466",
"resultSizeEstimate": 12
},
"headers": {
"alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-Q050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\"",
"cache-control": "private",
"connection": "close",
"content-encoding": "gzip",
"content-type": "application/json; charset=UTF-8",
"date": "Sun, 09 Jan 2022 13:10:48 GMT",
"server": "ESF",
"transfer-encoding": "chunked",
"vary": "Origin, X-Origin, Referer",
"x-content-type-options": "nosniff",
"x-frame-options": "SAMEORIGIN",
"x-xss-protection": "0"
},
"status": 200,
"statusText": "OK"
}
Example C: maxResults: (not set) ... resultSizeEstimate: 412
{
"config": {
"url": "https://www.googleapis.com/gmail/v1/users/me/messages?q=before%3A2021%2F1%2F9",
"method": "GET",
"headers": {
"Accept-Encoding": "gzip",
"User-Agent": "google-api-nodejs-client/0.7.2 (gzip)",
"Authorization": "Bearer [snip]",
"Accept": "application/json"
},
"params": {
"q": "before:2021/1/9"
},
"responseType": "json"
},
"data": {
"messages": [ ... ],
"nextPageToken": "16942818266524948378",
"resultSizeEstimate": 412
},
"headers": {
"alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-Q050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\"",
"cache-control": "private",
"connection": "close",
"content-encoding": "gzip",
"content-type": "application/json; charset=UTF-8",
"date": "Sun, 09 Jan 2022 13:09:05 GMT",
"server": "ESF",
"transfer-encoding": "chunked",
"vary": "Origin, X-Origin, Referer",
"x-content-type-options": "nosniff",
"x-frame-options": "SAMEORIGIN",
"x-xss-protection": "0"
},
"status": 200,
"statusText": "OK"
}
This was previously reported in Issue Tracker and was considered to be intended behavior by Google, since resultSizeEstimate is not expected to be exact; it's an "estimate":
the reason why resultSizeEstimate shows differents values is due to its estimation. As mentioned in the documentation resultSizeEstimate is just an estimated total number of results but not the exact number of results.
Reference:
users.messages.list method returns different amount of messages when using “maxResults” parameter
I'm using the Group Nodes in App Connect ACE 11 to call a service multiple times and trying to aggregate the the responses. Everything works fine and the below is the result of InputRoot.ComIbmGroupCompleteNode.Group.
{
"msg": {
"GroupProperties": {
"GroupId": "010000000000000000000000000000001000000000000000",
"GroupName": "TSTGRP",
"GroupCreationTime": 1593669682652,
"GroupCommitTime": 1593669682707,
"GroupCompleteTime": 1593669682806,
"GroupOutputTime": 1593669682806,
"GroupStatus": "Completed"
},
"Context": {
"HTTP": {
"RequestIdentifier": "45564854000000000e000000db851d0ecc11000000000000"
},
"RouterList": {}
},
"Replies": {
"FLDR": {
"ReplyId": "534f41503000000067e55223146300000400000000000000",
"RequestSendTime": 1593669682674,
"ReplyReceiptTime": 1593669682706,
"Reply": {
"Root": {
"HTTPResponseHeader": {
"X-Original-HTTP-Status-Line": "HTTP/1.1 200 OK",
"X-Original-HTTP-Status-Code": 200,
"Date": "Thu, 02 Jul 2020 06:01:17 GMT",
"Content-Type": "application/json; charset=utf-8",
"Content-Length": "83",
"Connection": "keep-alive",
"Set-Cookie": "__cfduid=dfbd2cc294d944ed4cfdf6b72a343f8dc1593669677; expires=Sat, 01-Aug-20 06:01:17 GMT; path=/; domain=.typicode.com; HttpOnly; SameSite=Lax",
"X-Powered-By": "Express",
"X-Ratelimit-Limit": "10000",
"X-Ratelimit-Remaining": "9999",
"X-Ratelimit-Reset": "1592660247",
"Vary": "Origin, Accept-Encoding",
"Access-Control-Allow-Credentials": "true",
"Cache-Control": "max-age=43200",
"Pragma": "no-cache",
"Expires": "-1",
"X-Content-Type-Options": "nosniff",
"Etag": "W/\"53-hfEnumeNh6YirfjyjaujcOPPT+s\"",
"Via": "1.1 vegur",
"CF-Cache-Status": "HIT",
"Age": "15242",
"Accept-Ranges": "bytes",
"cf-request-id": "03afb689ec00007f11da290200000001",
"Server": "cloudflare",
"CF-RAY": "5ac626bcaa097f11-CMB"
},
"JSON": {
"Data": {
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
}
}
}
}
},
"FLDR": {
"ReplyId": "534f415031000000273b5323146300000400000000000000",
"RequestSendTime": 1593669682707,
"ReplyReceiptTime": 1593669682737,
"Reply": {
"Root": {
"HTTPResponseHeader": {
"X-Original-HTTP-Status-Line": "HTTP/1.1 200 OK",
"X-Original-HTTP-Status-Code": 200,
"Date": "Thu, 02 Jul 2020 06:01:17 GMT",
"Content-Type": "application/json; charset=utf-8",
"Content-Length": "99",
"Connection": "keep-alive",
"Set-Cookie": "__cfduid=debd2bf084ee690942fb5d3439e41fa331593669677; expires=Sat, 01-Aug-20 06:01:17 GMT; path=/; domain=.typicode.com; HttpOnly; SameSite=Lax",
"X-Powered-By": "Express",
"X-Ratelimit-Limit": "500",
"X-Ratelimit-Remaining": "497",
"X-Ratelimit-Reset": "1593684076",
"Vary": "Origin, Accept-Encoding",
"Access-Control-Allow-Credentials": "true",
"Cache-Control": "max-age=43200",
"Pragma": "no-cache",
"Expires": "-1",
"X-Content-Type-Options": "nosniff",
"Etag": "W/\"63-+s0zIP5ZEQN9hypVJUneLybJ+L0\"",
"Via": "1.1 vegur",
"CF-Cache-Status": "HIT",
"Age": "8713",
"Accept-Ranges": "bytes",
"cf-request-id": "03afb68a0900007f29ad07c200000001",
"Server": "cloudflare",
"CF-RAY": "5ac626bcdc137f29-CMB"
},
"JSON": {
"Data": {
"userId": 1,
"id": 2,
"title": "quis ut nam facilis et officia qui",
"completed": false
}
}
}
}
},
"FLDR": {
"ReplyId": "534f4150320000000bbb5323146300000400000000000000",
"RequestSendTime": 1593669682707,
"ReplyReceiptTime": 1593669682737,
"Reply": {
"Root": {
"HTTPResponseHeader": {
"X-Original-HTTP-Status-Line": "HTTP/1.1 200 OK",
"X-Original-HTTP-Status-Code": 200,
"Date": "Thu, 02 Jul 2020 06:01:17 GMT",
"Content-Type": "application/json; charset=utf-8",
"Content-Length": "84",
"Connection": "keep-alive",
"Set-Cookie": "__cfduid=dfbd2cc294d944ed4cfdf6b72a343f8dc1593669677; expires=Sat, 01-Aug-20 06:01:17 GMT; path=/; domain=.typicode.com; HttpOnly; SameSite=Lax",
"X-Powered-By": "Express",
"X-Ratelimit-Limit": "500",
"X-Ratelimit-Remaining": "499",
"X-Ratelimit-Reset": "1593684076",
"Vary": "Origin, Accept-Encoding",
"Access-Control-Allow-Credentials": "true",
"Cache-Control": "max-age=43200",
"Pragma": "no-cache",
"Expires": "-1",
"X-Content-Type-Options": "nosniff",
"Etag": "W/\"54-J3JtLgWuXjgj1OZdyAcKAqOaKHo\"",
"Via": "1.1 vegur",
"CF-Cache-Status": "HIT",
"Age": "8713",
"Accept-Ranges": "bytes",
"cf-request-id": "03afb68a0c00007f11da291200000001",
"Server": "cloudflare",
"CF-RAY": "5ac626bcea187f11-CMB"
},
"JSON": {
"Data": {
"userId": 1,
"id": 3,
"title": "fugiat veniam minus",
"completed": false
}
}
}
}
}
}
}
}
My question is how can I access the 3 JSON.Data elements and create a combined response. I know this is not a valid JSON and FLDR is a repeating key. Also this is not an array. How can I access these elements and create a combined response like this?
{
"result1": {
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
},
"result2": {
"userId": 1,
"id": 2,
"title": "quis ut nam facilis et officia qui",
"completed": false
},
"result3": {
"userId": 1,
"id": 3,
"title": "fugiat veniam minus",
"completed": false
}
}
Any help would be very much appreciated.
If you have a message tree containing that structure then you can access any part of it - regardless of whether it would be a valid JSON document.
Have you tried writing a normal FOR loop in ESQL to iterate over the occurrences of FLDR?
Note: this code is completely un-tested and probably contains syntax errors and defects...
DECLARE index INTEGER 1;
FOR refFLDR AS InputRoot.ComIbmGroupCompleteNode.Group.msg.Replies.FLDR[] DO
DECLARE fieldName 'Result' || index;
CREATE LASTCHILD OF OutputRoot.JSON.Data TYPE Name NAME fieldName FROM refFLDR;
SET index = index + 1;
END FOR;
I am using the serverless framework to deploy a simple lambda (written in node/ express) behind api gateway...
In a GET I can see the origin header, but in a POST I cannot - it's not passed into my lambda function!
Anyone know why not and how to make it pass?
Background:
I did notice that in the POST the origin appears to be appended to the query string in the logs:
originalUrl: '/dev/endpoint?Origin=MY%20ORIGIN%20HERE',
So, I could extract the origin from the query string values, but I want to know if this is the correct way to do things on the serverless framework or should I be setting something to allow the API Gateway to send the origin through on a POST like it does on a GET ? Why are the 2 verbs behaving differently?
My Code/ Config:
the function definition in the serverless.yml looks like:
myGetFunction:
handler: lambda/index.handler
events:
- http:
path: /endpoint
method: get
cors: true
myPostFunction:
handler: lambda/index.handler
events:
- http:
path: /endpoint
method: post
cors: true
If I just put the following in my index.handler:
app.use((req, res) => {
console.log('LOG REQUEST', req)
res.send('interesting')
})
In my handler function, I only want to get the origin request header that was sent. In the GET it's easy: the cloudwatch logs show that it's available in the GET request in the headers object:
headers:
{
accept: '*/*',
'accept-encoding': 'gzip, deflate',
'cache-control': 'no-cache',
'cloudfront-forwarded-proto': 'https',
'cloudfront-is-desktop-viewer': 'true',
'cloudfront-is-mobile-viewer': 'false',
'cloudfront-is-smarttv-viewer': 'false',
'cloudfront-is-tablet-viewer': 'false',
'cloudfront-viewer-country': 'GB',
host: 'X.execute-api.us-east-1.amazonaws.com',
origin: 'MY ORIGIN HERE',
BUT: in the POST all the other headers are there, but origin is blank.
I did a bit of digging on this and ran into a couple realizations.
By default, it seems that no "origin" header passed in the API Gateway events. (I created a fresh serverless project, and just echoed back exactly what the API gateway event was.) So this is coming from some other source. I figured it may be a custom domain, and tested that. No dice.
My only other guess is that you have this behind some other layer (CloudFront?) that is forwarding these headers for you. If that ends up being the case, I would suggest you look and see if you can make it forward these headers for the POST request as it is for the GET request.
My only other final thought if none of the above is true is that there is some magic going on in some of the express middleware. I doubt this is the case.
For reference, this was my full serverless.yml and handler.js I tested with as well as a full unaltered event object I got in the endpoint.
service: so-test
provider:
name: aws
runtime: nodejs8.10
functions:
myGetFunction:
handler: handler.hello
events:
- http:
path: /endpoint
method: get
cors: true
myPostFunction:
handler: handler.hello
events:
- http:
path: /endpoint
method: post
cors: true
And the nodejs code:
'use strict';
module.exports.hello = async (event, context) => {
return {
statusCode: 200,
body: JSON.stringify({
message: 'Go Serverless v1.0! Your function executed successfully!',
input: event,
}),
};
};
Finally the response object
{
"message": "Go Serverless v1.0! Your function executed successfully!",
"input": {
"resource": "/endpoint",
"path": "/test/endpoint",
"httpMethod": "GET",
"headers": {
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "en-US,en;q=0.9",
"CloudFront-Forwarded-Proto": "https",
"CloudFront-Is-Desktop-Viewer": "true",
"CloudFront-Is-Mobile-Viewer": "false",
"CloudFront-Is-SmartTV-Viewer": "false",
"CloudFront-Is-Tablet-Viewer": "false",
"CloudFront-Viewer-Country": "US",
"Host": "so-test.serverless-examples.com",
"upgrade-insecure-requests": "1",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36",
"Via": "2.0 f92491812e422470607f365e923929b5.cloudfront.net (CloudFront)",
"X-Amz-Cf-Id": "6AwZPV3uCYxseJIAmsGzhApzRostCiLXwwM3XsbSJP4K8hQx11MSgw==",
"X-Amzn-Trace-Id": "Root=1-5c086dd9-bce03ab0c216116fa6de9786",
"X-Forwarded-For": "55.55.55.555, 70.132.32.155",
"X-Forwarded-Port": "443",
"X-Forwarded-Proto": "https"
},
"multiValueHeaders": {
"Accept": [
"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"
],
"Accept-Encoding": [
"gzip, deflate, br"
],
"Accept-Language": [
"en-US,en;q=0.9"
],
"CloudFront-Forwarded-Proto": [
"https"
],
"CloudFront-Is-Desktop-Viewer": [
"true"
],
"CloudFront-Is-Mobile-Viewer": [
"false"
],
"CloudFront-Is-SmartTV-Viewer": [
"false"
],
"CloudFront-Is-Tablet-Viewer": [
"false"
],
"CloudFront-Viewer-Country": [
"US"
],
"Host": [
"so-test.serverless-examples.com"
],
"upgrade-insecure-requests": [
"1"
],
"User-Agent": [
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36"
],
"Via": [
"2.0 f92491812e422470607f365e923929b5.cloudfront.net (CloudFront)"
],
"X-Amz-Cf-Id": [
"6AwZPV3uCYxseJIAmsGzhApzRostCiLXwwM3XsbSJP4K8hQx11MSgw=="
],
"X-Amzn-Trace-Id": [
"Root=1-5c086dd9-bce03ab0c216116fa6de9786"
],
"X-Forwarded-For": [
"55.55.55.555, 70.132.32.155"
],
"X-Forwarded-Port": [
"443"
],
"X-Forwarded-Proto": [
"https"
]
},
"queryStringParameters": null,
"multiValueQueryStringParameters": null,
"pathParameters": null,
"stageVariables": null,
"requestContext": {
"resourceId": "mftg6x",
"resourcePath": "/endpoint",
"httpMethod": "GET",
"extendedRequestId": "RdYZ7HaxoAMFQYQ=",
"requestTime": "06/Dec/2018:00:31:21 +0000",
"path": "/test/endpoint",
"accountId": "800708648372",
"protocol": "HTTP/1.1",
"stage": "dev",
"domainPrefix": "so-test",
"requestTimeEpoch": 1544056281163,
"requestId": "410632a3-f8ee-11e8-a7e2-7d886f93a0e4",
"identity": {
"cognitoIdentityPoolId": null,
"accountId": null,
"cognitoIdentityId": null,
"caller": null,
"sourceIp": "55.55.55.555",
"accessKey": null,
"cognitoAuthenticationType": null,
"cognitoAuthenticationProvider": null,
"userArn": null,
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36",
"user": null
},
"domainName": "so-test.serverless-examples.com",
"apiId": "txctij0cnp"
},
"body": null,
"isBase64Encoded": false
}
}
I have FB analytics configured for iOS and android app. It does recognize iOS platform when viewing events correctly. But for android it only qualifies it as android about 30% of all.
Here's how those events are shown in FB analytics debugging screen: ('inne wartości' stands for 'other')
I wonder how FB does the recognition? By advertising id? Read docs through but didn't find info about this anywhere.
Here's a FB response that gets recognized as android: (obfuscated few details):
{
"req": {
"method": "POST",
"url": "https://graph.facebook.com/v2.6/000000000/activities",
"data": {
"advertiser_id": "2e9ab235-84c0-4b22-8421-xxxxxxxxxxxxx",
"advertiser_tracking_enabled": 1,
"application_tracking_enabled": 1,
"bundle_id": "com.myapp",
"bundle_short_version": "1.7.0",
"event": "CUSTOM_APP_EVENTS",
"custom_events": [
{
"_appVersion": "1.7.0",
"_eventName": "App Launched",
"_logTime": 1476295031,
"fb_currency": "USD"
}
]
},
"headers": {
"user-agent": "Segment.io/1.0",
"content-type": "application/json"
}
},
"header": {
"access-control-allow-origin": "*",
"pragma": "no-cache",
"cache-control": "private, no-cache, no-store, must-revalidate",
"facebook-api-version": "v2.6",
"expires": "Sat, 01 Jan 2000 00:00:00 GMT",
"content-type": "text/javascript; charset=UTF-8",
"x-fb-trace-id": "BH4kXNYDDL+",
"x-fb-rev": "2617769",
"x-fb-debug": "eNcBCpuFfVirTkclVvZ0WeYh60r+2tBIqg6lKPCrWNtGASVULq6jrVwQxqYulMUyCI3ZaBhZRQ64xdxdXOQg2w==",
"date": "Wed, 12 Oct 2016 17:57:24 GMT",
"connection": "close",
"content-length": "16"
},
"status": 200,
"text": "{\"success\":true}"
}
And this one is not recognized as android:
{
"req": {
"method": "POST",
"url": "https://graph.facebook.com/v2.6/000000000000/activities",
"data": {
"advertiser_id": "88697a4d-f658-41d3-84db-xxxxxxxxxx",
"advertiser_tracking_enabled": 1,
"application_tracking_enabled": 1,
"bundle_id": "com.myapp",
"bundle_short_version": "1.7.0",
"event": "CUSTOM_APP_EVENTS",
"custom_events": [
{
"_appVersion": "1.7.0",
"_eventName": "App Launched",
"_logTime": 1476206487,
"fb_currency": "USD"
}
]
},
"headers": {
"user-agent": "Segment.io/1.0",
"content-type": "application/json"
}
},
"header": {
"access-control-allow-origin": "*",
"pragma": "no-cache",
"cache-control": "private, no-cache, no-store, must-revalidate",
"facebook-api-version": "v2.6",
"expires": "Sat, 01 Jan 2000 00:00:00 GMT",
"content-type": "text/javascript; charset=UTF-8",
"x-fb-trace-id": "AqASb9qsUSx",
"x-fb-rev": "2613995",
"x-fb-debug": "aDLUDoC+7vmlVY28UsEtusYgzdkmxK8qVrn4gCo29ovLw9Us27Gh/Iy1163dfTDF5rKg/JWiv3xsfq3hugijlg==",
"date": "Tue, 11 Oct 2016 17:21:37 GMT",
"connection": "close",
"content-length": "16"
},
"status": 200,
"text": "{\"success\":true}"
}
I can't see any interesting changes that that would point to an android platform.
Update
As advised by Ramkumar, I tried posting events with FB sdk and it indeed worked. I'd really like to keep using segment, so keeping this as solution is not possible in my app.
I wonder what's missing from the params that segment sends to FB. Is this because of session_id which is in there when using FB SDK but is absent in segment request? See gist with dump from adb logcat when using FB SDK
From your post, it looks like you are using segment.io to send events to our servers. If you use the FB SDK to send events you will not see this problem - could you please give that a try?