Postman pre-request script: Can't access header from response - javascript

I am writing the following pre-request Script to get my JWT for authentication:
pm.sendRequest(echoPostRequest, function (err, res) {
console.log(err, res, typeof res);
if(err === null){
console.log(res.header)
// var authHeader = res.header.find(v => {v.key === 'Authorization'})
}
});
This is what the console output currently looks like:
null, {id: "4ba2b741-316e-454d-b896-eab3aef74ae2", status: "OK", code: 200…}, object
undefined
OK
// If you enlarge the opbject it looks like the following:
id: "4ba2b741-316e-454d-b896-eab3aef74ae2"
status: "OK"
code: 200
header: [10] <--- There are my headers ?!
stream: {…}
cookie: [0]
responseTime: 121
responseSize: 0
The problem is I can not access the header array the script always tells me it is undefined, same if I try the access the cookie array. But I can access every other single property, maybe it's because header and cookie are arrays? I don't know. Any ideas what I am doing wrong and how I can get my Authorization header?

I think the Problem must be a bug, my workaround is to stringify and parse the object as json, than the headers are accessible.
r = JSON.parse(JSON.stringify(res))

Related

How to setup greeting text or get_started in JavaScript

I am trying to develop a bot for FB Messenger and I'm always getting stuck with their documentation. Currently, I tried to add a Greeting Text and a Get_Started button in JavaScript, so I will be able to modify it easily. It seems like most of their documentation is in PHP or they just telling you to add it by sending a POST request using CURL, which worked for me, but again, it's not so modular.
I can't find proper documentation in JavaScript. and the only one is this:
https://www.techiediaries.com/build-messenger-bot-nodejs/
But I can't find the place where you actually call the greeting or get started functions.
there is also this https://github.com/fbsamples/original-coast-clothing
but I still can't find where they trigger the Greetings and the Get_Started postbacks. Only the json file where they store it /locales/en_US.json "profile".
My code currently has
// Accepts POST requests at /webhook endpoint
app.post('/webhook', (req, res) => {
// Parse the request body from the POST
let body = req.body;
// Check the webhook event is from a Page subscription
if (body.object === 'page') {
// Iterate over each entry - there may be multiple if batched
body.entry.forEach(function(entry) {
// Get the webhook event. entry.messaging is an array, but
// will only ever contain one event, so we get index 0
let webhook_event = entry.messaging[0];
console.log(webhook_event);
// Get the sender PSID
let sender_psid = webhook_event.sender.id;
console.log('Sender PSID: ' + sender_psid);
// Check if the event is a message or postback and
// pass the event to the appropriate handler function
if (webhook_event.message) {
handleMessage(sender_psid, webhook_event.message);
} else if (webhook_event.postback) {
handlePostback(sender_psid, webhook_event.postback);
}
});
// Return a '200 OK' response to all events
res.status(200).send('EVENT_RECEIVED');
} else {
// Return a '404 Not Found' if event is not from a page subscription
res.sendStatus(404);
}
});
function setupGreetingText(res){
var messageData = {
"greeting":[
{
"locale":"default",
"text":"Greeting text for default local !"
}, {
"locale":"en_US",
"text":"Greeting text for en_US local !"
}
]};
request({
"uri": "https://graph.facebook.com/v2.6/me/messages",
"qs": { "access_token": process.env.PAGE_ACCESS_TOKEN },
"method": 'POST',
"headers": {'Content-Type': 'application/json'},
"form": messageData
},
function (error, response, body) {
if (!error && response.statusCode == 200) {
// Print out the response body
res.send(body);
} else {
// TODO: Handle errors
res.send(body);
}
});
}
but I still dont know how to trigger it.
Examples on the documentation look like this. This is how you break it down. Final result can be found below.
curl -X POST -H "Content-Type: application/json" -d '{
"get_started": {"payload": "<postback_payload>"}
}' "https://graph.facebook.com/v2.6/me/messenger_profile?access_token=<PAGE_ACCESS_TOKEN>"
Third word is the type of request you'll send and should be defined inside the method property.
Between the curly braces, is how the content inside the json property should be formatted.
The link on the last line is the link you should provide to the uri property minus the query part ?access_token=<PAGE_ACCESS_TOKEN>
SendAPI's uri is https://graph.facebook.com/v8.0/me/messages (you're using this)
MessengerProfileAPI's uri is https://graph.facebook.com/v2.6/me/messenger_profile (use this instead)
In the end, your request function should look something like this:
request(
{
"uri": "https://graph.facebook.com/v2.6/me/messenger_profile",
"qs": { "access_token": process.env.PAGE_ACCESS_TOKEN },
"method": "POST",
"json": {
"get_started": {"payload": "start"}
},
},
(err) => {
if (!err) {
console.log('request sent!');
} else {
console.error("Unable to send message:" + err);
}
}
);
Even though its been almost 3 months since this question has been asked. I hope this will still come useful.
Was struggling and frustrated as you trying to implement the examples on facebook for developers documentation but I finally got to understand it after some looking and observation at other developers webhook on github.

check if api token exists in header in javascript

I am trying to test if an API token exists in my API call. the headers being passed to are -
"host": [
{
"key": "Host",
"value": "mydomain"
}
],
"x-api-key": [
{
"key": "x-api-key",
"value": "mykey"
}
]
}
Now my code looks like
// Check if apikey is a part of the headers
if ( !headers.hasOwnProperty('x-api-key') || headers['x-api-key'][0].value!="mykey") {
const body = 'Unauthorized';
const response = {
status: 401,
statusDescription: 'Unauthorized',
body: body,
};
callback(null, response);
}
My If case errors out instead of sending 401 if the headers are missing x-api-key altogether
"errorMessage": "Cannot read property '0' of undefined",
How should i change my condition so i can check for both the key/value pair and not have undefined errors incase of missing header key/value
Try updating your code to
// Check if apikey is a part of the headers
if ( !headers.hasOwnProperty('x-api-key') || (headers.hasOwnProperty('x-api-key') && headers['x-api-key'][0].value!="mykey")) {
const body = 'Unauthorized';
const response = {
status: 401,
statusDescription: 'Unauthorized',
body: body,
};
callback(null, response);
}
Your first condition checks if x-api-key exists in the headers. And the second condition checks the value for the x-api-key.
The way OR works is that it will stop its execution either at the first occurence of a true condition or will process each condition. Thus in your case, if x-api-key is not passed as a header, it still goes and checks the second condition. Since the x-api-key does not exist, it will not be able to read [0] of the property and hence the error.
However AND stops its execution at the first occurence of a false condition, and hence will never process the second condition if the x-api-key is not a part of the headers.

MongoDB Atlas Trigger -- Receiving a "StitchError: HTTP request failed: unexpected status code: expected=200, actual=415" error

We're trying to create a trigger in MongoDB Atlas that will automatically reduce our Azure tier of an evening to save cost. The function we've put together (probably incorrectly!) returns an error when we try to run it. The result output is:
logs:
uncaught promise rejection: StitchError: HTTP request failed: unexpected status code: expected=200, actual=415
> result:
{
"$undefined": true
}
> result (JavaScript):
EJSON.parse('{"$undefined":true}')
We've tried messing around with the headers and body, but the end result is always the same.
Here's the WIP function:
exports = function() {
const response = context.http.patch({
scheme: "https",
host: "cloud.mongodb.com",
path: "/api/atlas/v1.0/groups/abc123/clusters/fake-server",
username: "usernamehere",
password: "passwordhere",
digestAuth: true,
headers: {"Content-Type": [ "application/json" ]},
body: {"clusterType":"REPLICASET", "providerSettings":{"providerName":"AZURE", "instanceSizeName":"M10", "regionName":"regionhere" } },
encodeBodyAsJSON: true
});
};
Any help would be greatly appreciated.
It turns out that we had it right the whole time.
Executing the exact same code as above is now correctly reducing our tier. I don't know what was causing the MongoDB Atlas API to think that our headers and / or request body were incorrect, but it's perfectly happy with it today.
The only other thing I will point out is that if you want this part of the error to go away...
> result:
{
"$undefined": true
}
> result (JavaScript):
EJSON.parse('{"$undefined":true}')
...you need to change the function to async / await like so:
exports = async function() {
const response = await context.http.patch({

Axios - How to read JSON response?

Axios 0.17.1
.then(function (response) {
console.log(response);
//console.log(response.status);
//It is an error -> SyntaxError: Unexpected token u in JSON at position 0
console.log(JSON.parse(response.data.error));
console.log(response.data.error); //undefined.
The console.log of response is
{data: "{"error":"Name must be entered with more than one … NULL↵
["isPipe":protected]=>↵ NULL↵ }↵}↵", status: 203, statusText:
"Non-Authoritative Information", headers: {…}, config: {…}, …} config
: {adapter: ƒ, transformRequest: {…}, transformResponse: {…}, timeout:
0, xsrfCookieName: "XSRF-TOKEN", …} data : "{"error":"Name must be
entered with more than one character."}object(Slim\Http\Response)#32
(5) {↵ ["status":protected]=>↵ int(200)↵
["reasonPhrase":protected]=>↵ string(0) ""↵
["protocolVersion":protected]=>↵ string(3) "1.1"↵
["headers":protected]=>↵ object(Slim\Http\Headers)#33 (1) {↵
["data":protected]=>↵ array(1) {↵ ["content-type"]=>↵
array(2) {↵ ["value"]=>↵ array(1) {↵ [0]=>↵
string(24) "text/html; charset=UTF-8"↵ }↵
["originalKey"]=>↵ string(12) "Content-Type"↵ }↵ }↵ }↵
["body":protected]=>↵ object(Slim\Http\Body)#31 (7) {↵
["stream":protected]=>↵ resource(59) of type (stream)↵
["meta":protected]=>↵ NULL↵ ["readable":protected]=>↵ NULL↵
["writable":protected]=>↵ NULL↵ ["seekable":protected]=>↵
NULL↵ ["size":protected]=>↵ NULL↵ ["isPipe":protected]=>↵
NULL↵ }↵}↵" headers : {content-type:
"application/json;charset=utf-8"} request : XMLHttpRequest
{onreadystatechange: ƒ, readyState: 4, timeout: 0, withCredentials:
false, upload: XMLHttpRequestUpload, …} status : 203 statusText :
"Non-Authoritative Information"
proto : Object
JSON.parse(response.data) as well as response.data.error -> Both are giving error. How can i read the data?
Slimframework 3.
$data = array('error' => 'Name must be entered with more than one character.');
$newResponse = $response->withJson($data, 203);
return $newResponse;
In Axios responses are already served as javascript object, no need to parse, simply get response and access data.
Assuming the response from the server looks like this:
{"token": "1234567890"}
Then in Axios you can access it like this:
console.log( response.data.token )
As already written, Axios already returns JSON by default. Just use response.data as simple JS object.
However, following insight might help others: I had an issue that Axios returned the response as a string. When investigated I discovered that the server returned an invalid JSON (it was a static file server). When fixed the JSON format, Axios used JSON instead of string again.
you can simply get it as following,
ex:
{
"terms": {
"title": "usage",
"message": "this is the usage message"
}
}
when the response look like this,you can get it using "response.data",and so on....
.then(response =>
console.log( response.data.terms.message)
Cheers !
I had a similar format response as the one in console log and my issue was that my .json file wasn't properly formatted. I was missing a comma. Post your json file to have a look.
axios by defualt convert response to JSON, you must use response.data instead of response
export const addPosts = () => async (dispatch) => {
await axios('https://jsonplaceholder.typicode.com/todos/1')
.then(response => dispatch({type: postActionTypes.POSTS, payload: response.data}))}
For some reason, in my case the JSON was properly formatted but was returned as string anyway. With this workaround I solved the issue.
// ...
return await this.axios_instance.request<T>({
method,
url,
headers,
params,
transformResponse: (data) => JSON.parse(data), // <----------
data,
});
Simply put, I explicitly told to transform the response using JSON.parse. For some reason this worked, while other answers didn't.
This worked for me!! Hope it helps.
Here is sample code,
try {
const res = await axios.get("/end-point");
console.log("JSON data from API ==>", res.data);
} catch (error) {
// handle error
}
I had a similar problem. As others have pointed out, axios reads the json as a js object and you can easily move through the hierarchy to get your field data.
However, for me axios did not want to read the json as an object and instead returned a string. The cause was that there was a hanging comma at the end of the json due to a previous row deletion in the file. So the file content wasn't valid json, and axios simply returned a string.
Remove the comma, everything worked.
I would suggest to check the json for any incorrect syntax.
I had the same problem and I found that I was not reading data properly. Finally, I got a solution. try this.
my data was like:
response = [{"myname","Anup","age":23,"Education":"Graduation"}]
I was trying to retrieve data like(this was giving output undefined)
axios('https://apiurl.com')
.then((reponse)=>{
const recieved_Data=fetchdata.data;
console.log(recieved_Data.name);
})
Correct Approach:
axios('https://apiurl.com')
.then((reponse)=>{
const recieved_Data=fetchdata.data;
console.log(recieved_Data[0].name);
})
as you can see i have passed the index value of the array of my response recieved_Data[0].name And this gave me the correct output.
Vote me if this works for you.
Thanks!
So I came across this post in search of an answer to my question. "How to access data in a json file returned by an api." Nonetheless, what worked for me at the end of the day was an answer to a similar question on stackoverflow to which the link is Axios. How to get error response even when api return 404 error, in try catch finally.
However, here is the code I used to access my error codes returned by my backend api.
axios.get(/sanctum/csrf-cookie).then(response => {
axios.post(api/register, registerInfo)
.then(response => {
console.log('This is the response: ' + response.data.errors);
}).catch(error => {
console.log('This is the error: ' +
error.response.data.errors.name);
});
});

Http provider doesn't reach my localhost server

I've got a provider that uses the Http service to perform a GET operation over a localhost server:
requestAchievedCombined(config){
return new Promise( (resolve, reject) => {
const URL = "localhost:3000";
const query = "?collection=achieved_combined&query=columns";
this.http.get(URL+"/api"+query).subscribe( response => {
// TODO: check data integriy
console.log(">> API RES: ", response)
resolve(response);
}, err => this.errorHandler(err, reject));
})
}
The server is hosted in localhost:3000 and running, and it works perfectly when called from the navigator with that same GET query string... it returns some JSON.
Thing is, when I execute my Angular app, this gives me the following error:
ERROR [DataRequester] =>
{…}
_body: "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<title>Error</title>\n</head>\n<body>\n<pre>Cannot GET /function%20URL()%20%7B%20%20%20%20[native%20code]%7D/api</pre>\n</body>\n</html>\n"
headers: Object { _headers: Map, _normalizedNames: Map }
ok: false
status: 404
statusText: "Not Found"
type: 2
url: "http://localhost:4200/function%20URL()%20%7B%20%20%20%20[native%20code]%7D/api?collection=achieved_combined&query=columns"
__proto__: Object { constructor: Response(), toString: Response.prototype.toString() }
Do anybody know why this happens? What am I doing wrong? I'm using the latest Angular version.
pd: yes I tried putting http:// before localhost in the URL.
EDIT: After changing the url to http://localhost:3000 and call the property in a proper way (I was forgetting the this. thing), I could manage to communicate with the server, but now I'm having this issue:
ERROR [DataRequester] =>
{…}
_body: error
bubbles: false
cancelBubble: false
cancelable: false
composed: false
currentTarget: null
defaultPrevented: false
eventPhase: 0
explicitOriginalTarget: XMLHttpRequest { __zone_symbol__xhrSync: false, __zone_symbol__xhrURL: "http://localhost:3000/api?collection=achieved_combined&query=columns", readyState: 4, … }
isTrusted: true
lengthComputable: false
loaded: 0
originalTarget: XMLHttpRequest { __zone_symbol__xhrSync: false, __zone_symbol__xhrURL: "http://localhost:3000/api?collection=achieved_combined&query=columns", readyState: 4, … }
target: XMLHttpRequest { __zone_symbol__xhrSync: false, __zone_symbol__xhrURL: "http://localhost:3000/api?collection=achieved_combined&query=columns", readyState: 4, … }
timeStamp: 3687.8557595446277
total: 0
type: "error"
__proto__: ProgressEventPrototype { lengthComputable: Getter, loaded: Getter, total: Getter, … }
headers: Object { _headers: Map, _normalizedNames: Map }
ok: false
status: 0
statusText: ""
type: 3
url: null
__proto__: Object { constructor: Response(), toString: Response.prototype.toString() }
URL is a global function that gets "called". Try renaming the URL var to url and it should work.
Okay, first thing wrong was that I wasn't calling the URL property in a good way: actually, it wasn't in the method but in the class, and I was forgetting the "this.", so I wasn't pointing to the right variable.
Secondly, fixed my edit simply setting up CORS in my express server:
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
Now my Angular app correctly gets the data!
I'm just passing by to give you some code
requestAchievedCombined(config): Observable<any> {
const URL = "localhost:3000";
const query = "?collection=achieved_combined&query=columns";
return this.http.get(URL+"/api"+query)
.map( response => {
// TODO: check data integriy
console.log(">> API RES: ", response)
return response;
}, err => this.errorHandler(err))
// .toPromise() // If you still want your cherished promise
;
}
I've changed your function to simplify it : you should use Observables instead of Promises. I know, I was skeptical at first too, but Observables are way more powerful than promises. and if you still don't like it, simply call .toPromise() right after the map operator, it will still be clearer ;)
Other than that, Could you post the trace of your error instead of the payload ? We need the error message to know what is happening.

Categories