How to read the response returned to a Twilio function from another function? - api

Really basic question - I'm calling a twilio function from another twilio function to retrieve the ID of a salesforce record. The following code is what gets returned from one function to another. I'm just trying to "read" the contents of the response to get the ID but can't seem to figure it out. I confirmed that the function returning the response works correctly (contains the right data.)
Help is much appreciated!
responsebody
2020-11-24T19:38:02.642Z 13c8fae2-5f74-40c2-942a-d6aa7ed85c48 INFO Response {
size: 0,
timeout: 0,
[Symbol(Body internals)]:
{ body:
PassThrough {
_readableState: [ReadableState],
readable: true,
_events: [Object],
_eventsCount: 2,
_maxListeners: undefined,
_writableState: [WritableState],
writable: false,
allowHalfOpen: true,
_transformState: [Object] },
disturbed: false,
error: null },
[Symbol(Response internals)]:
{ url: 'https://coxczsdlk-dffcat-8307.twil.io/sf-get-record',
status: 200,
statusText: 'OK',
headers: Headers { [Symbol(map)]: [Object] },
counter: 0 } }
Here's the code for the function returning this response - this line returns the correct ID - response.body.records[0].Id
const querystring = require('querystring');
const request = require('request');
let globalCallback;
exports.handler = function(context, event, callback) {
globalCallback = callback;
console.log("Starting");
console.log("event: ", event);
run(context.DOMAIN_NAME, event);
};
function run(domain, event){
request({
uri: `https://${domain}/sf-access-token`,
method: 'GET'
}, function (err, res, body) {
if(res.statusCode == 200){
// Received Access Token. Now build and send the request
processRequest(JSON.parse(body), event);
} else{
globalCallback(`Error getting token: ${res.body}`);
}
});
}
function processRequest(sfAuthReponse, event){
// if(validateRequest(event)) {
var options = {
// uri: `${sfAuthReponse.instance_url}/services/data/v43.0/query/?q=SELECT+id+From+${event.objectAPIName}+WHERE+callSID__c='${event.callSID}'`,
uri: `${sfAuthReponse.instance_url}/services/data/v43.0/query/?q=SELECT+id+From+Case+WHERE+callSID__c='1'`,
headers: {
'Authorization': 'Bearer ' + sfAuthReponse.access_token,
'Content-Type': 'application/json',
},
body: event.fields,
json:true,
method: 'GET'
};
request(options, processResponse);
// }
}
function validateRequest(event) {
let valid = false;
let validationMessage;
if(!event.objectAPIName || event.objectAPIName.trim().length === 0) {
validationMessage = "Parameter, objectAPIName, was not set in the JSON Request Body. Provide the SF API Name of the object to create";
} else if (!event.fields) {
validationMessage = "Parameter, fields, was not set in the JSON Request Body. Provide this parameter with a JSON value representing the fields to set when creating the SF object.";
} else {
valid = true;
}
if(!valid) {
globalCallback(validationMessage);
}
return valid; // <== This will always return true since execution is terminated with the callback if invalid
}
function processResponse(error, response, body) {
if (!error && response.statusCode == 200) {
console.log('response.body.records[0].Id');
console.log(response.body.records[0].Id);
// Successfully created new object. Response 201 from successful object creation
//globalCallback(null, response.body.records[0].Id);
globalCallback(null, response);
} else{
console.log("Error: ", error);
console.log("Response: ", response);
console.log(body);
globalCallback(body);
}
}
and here's some of the code for the first function calling the above function, not sure how to dot notation into the response.
fetch('https://casdflk-dsfdsfat-8707.twil.io/sf-get-record', {
headers: {
'Authorization': 'Basic ' + context.ENCODED_TWILIO_CREDS,
'Content-Type': 'application/json'
},
method: 'POST',
body: {
objectAPIName: 'Case',
callSID: '1',
}
// callback(null,sid);
}).then(record => {
console.log('recordbody11');
console.log(record.body);
return record;

It looks like you are using fetch.
Fetch has a method .json() that you need to call on the response.
See the MDN page
Is that your question or did I miss something?

Related

React Native Fetch data from api issue

I'm trying to fetch data and access it later from an api that involves token authorization. The token will be generating in other places. this is the current fetch method and the error I have. Please help, been stuck here for days.
async getUserToken() {
const userData = await AsyncStorage.getItem("userData")
let data = JSON.parse(userData as string);
let dataString = data._W.token as string
return dataString
}
//fetch file from api here
async componentDidMount(){
try {
const response = await fetch(SOME_RANDOM_API), {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Token' +
await this.getUserToken(),
},
body: JSON.stringify({
document: this.state.document,
name: this.state.name,
size: this.state.size,
file_type: this.state.file_type,
uploaded: this.state.uploaded,
})
})
const responseJson = await response.json();
console.log(responseJson)
// console.log("response is"+ responseJson)
this.setState({
isLoading: false,
dataSource: responseJson,
});
console.log("response 2 is"+ responseJson)
} catch (error) {
console.log("error is"+ error);
}
}
error here
Object {
"detail": "Unsupported media type \"application/json\" in request.",
}
error isTypeError: undefined is not a function (near '...this.state.dataSource.map...')
TypeError: undefined is not a function (near '...this.state.dataSource.map...')

How to set formData for boolean in Axios post request

I'm trying send a post request using axios to my backend but I can't send the boolean "isActive" for some reason. Is there a way to do this?
async submit() {
const isValid = await this.$validator.validateAll()
if (isValid && !this.submitting) {
let formData = new FormData();
formData.set("city", this.formData.city)
formData.set("state", this.formData.state)
formData.set("county", this.formData.county)
formData.set("isActive", true) // <- NOT ACCEPTING THIS VALUE
axios.post("/api/v1/team/createTeam", formData, {
headers: {
'Content-Type': 'application/json'
}
})
.then(res => {
if (res.status === 200) {
this.submitting = true
this.cancelModal()
} else {
console.log(res.data.code);
}
})
.catch(function (err) {
console.log(err);
})
}
}
FormData can only contain string values. Setting a Boolean true would result in "true" for the value. The backend would have to convert that string to a Boolean.
Also, your header should not be application/json (intended for JSON payloads). If sending FormData as the payload, the header should be multipart/form-data:
axios.post("/api/v1/team/createTeam", formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
If your backend is actually expecting JSON, then you can't send FormData. Switch to a JavaScript object instead (which does accept Booleans):
const payload = {
city: this.formData.city,
state: this.formData.state,
county: this.formData.county,
isActive: true,
}
axios.post("/api/v1/team/createTeam", payload, {
headers: {
'Content-Type': 'application/json'
}
})

Is there any way to catch the response data which is causing the POST 400 (Bad Request) for Vue js fetch api?

I am sending post request from an array by looping through all indexes one by one.
function apiService(endpoint, method, data) {
// D.R.Y. code to make HTTP requests to the REST API backend using fetch
const config = {
method: method || "GET",
body: data !== undefined ? JSON.stringify(data) : null,
headers: {
'content-type': 'application/json',
'X-CSRFTOKEN': CSRF_TOKEN
}
};
return fetch(endpoint, config)
.then(handleResponse)
.catch(error => console.log(error))
}
let len = this.rowObject.length;
for (var i = 0; i <len; i++) {
apiService(endpoint, method, this.rowObject[i]);
}
I want to catch the this.rowObject[i] object or the i index which causes bad 400 request.
Can it be done using try catch?
You can inject an error handler that captures the information you want, like with onError below.
function apiService(endpoint, method, data, onError) {
// D.R.Y. code to make HTTP requests to the REST API backend using fetch
const config = {
method: method || "GET",
body: data !== undefined ? JSON.stringify(data) : null,
headers: {
'content-type': 'application/json',
'X-CSRFTOKEN': CSRF_TOKEN
}
};
return fetch(endpoint, config)
.then(handleResponse)
.catch(onError)
}
let len = this.rowObject.length;
for (var i = 0; i <len; i++) {
let onError = error => console.log("Error on rowObject " + i + ": " + error);
apiService(endpoint, method, this.rowObject[i], onError);
}

How to migrate using request library for a POST request to Axios?

I've been grinding this out for awhile but am definitely hard blocked. I want to migrate my program from a deprecated request library to a different one. I chose axios but can't get it to work. All I need to be able to do is make the post request in a similar way that lets me access the response body.
Here is my working deprecated library request code:
const getPage = (apiUrl, size, stagedDateAfter) => {
let options = {
json: true,
body: {
"summary": false,
"sort": [{"stagedDate": "asc"}],
"search_after": [stagedDateAfter],
"queries": [],
"page": {"max": size}
}
};
request.post(apiUrl, options, (error, res, body) => {
if (error) {
return console.log(error)
}
if (!error && res.statusCode === 200 && keepGoing == true) {
if(body.meta.total == 0 || (!body)){
throw("error");
}
/*
Code works from this point, can access body, data, etc
*/
}
}
My failing axios library code:
function checkResponseStatus(res) {
if(res.statusCode === 200 && keepGoing == true) {
return res
} else {
throw new Error(`The HTTP status of the reponse: ${res.status} (${res.statusText})`);
}
}
const headers = {
'Content-Type': 'application/json'
}
const getPage = (apiUrl, size, stagedDateAfter) => {
let options = {
json: true,
body: {
"summary": false,
"sort": [{"stagedDate": "asc"}],
"search_after": [stagedDateAfter],
"queries": [],
"page": {"max": size}
}
};
axios.post(apiUrl, options, headers)
.then(response => {
console.log(response);
if(!response){
checkResponseStatus(response);
}
return response;
})
.catch(error => {
console.log(error.res)
})
.then(data => { //This code doesn't work since response not defined here
if(response.data.status == 200){
console.log(data);
}
});
All I need is to be able to access the response body using axios similarly to how I did with the request library but I'm reading the documentation, api, etc and I just cant seem to get the exact format right.
Solved it! Correct format that lets me access body properly.
let options = {
url: stringURL,
method: 'POST',
json: true,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
data: {
"summary": false,
"sort": [{"stagedDate": "asc"}],
"search_after": [stagedDateAfter],
"queries": [],
"page": {"max": size}
}
};
axios(options)
.then((response)=>{
//rest of code

React Native: Ajax error with RxJS on simple post request

I am trying to perform a simple post request in React Native with a module that I also use for my website.
I have an api.ts file where the following is defined:
import { ajax } from 'rxjs/observable/dom/ajax';
import { AjaxRequest } from 'rxjs/observable/dom/AjaxObservable';
const ApiClient = {
loginUser: (email: string, password: string) => {
let requestBody = {email, password};
let url = `${dotenv.REACT_APP_API_URL}/api/users/login`;
return createRequestOptions(url, HttpOptions.POST, requestBody);
}
}
The request options method is as follows:
const createRequestOptions = (url: string, method: string, requestBody?: object) => {
let requestOptions: AjaxRequest = {
method: method,
url: url,
crossDomain: true,
responseType: 'json',
headers: {
'Content-Type': 'application/json',
}
};
if ((method === HttpOptions.POST || method === HttpOptions.PUT) && requestBody) {
requestOptions.body = requestBody;
}
console.log(requestOptions);
return ajax(requestOptions);
};
The output of the requestOptions is as follows:
Object {
"body": Object {
"email": "myemail#gmail.com",
"password": "mypassword",
},
"crossDomain": true,
"headers": Object {
"Content-Type": "application/json",
},
"method": "POST",
"responseType": "json",
"url": "http://localhost:3001/api/users/login",
}
Finally in my epic I have the following:
const authLoginEpic: Epic = (action$, store) =>
action$.pipe(
ofType(ActionTypes.AUTH_LOGIN_REQUEST),
mergeMap((action: AuthLoginRequest) =>
ApiClient.loginUser(action.payload.username, action.payload.password).pipe(
map((res: any) => {
return AuthLoginReceive.create({response: res.response, email: action.payload.username});
}),
catchError((err) => {
console.log(JSON.stringify(err));
For some reason the catchError is triggered and I have no idea why this may be. The output of the log is:
{"message":"ajax error","name":"AjaxError","xhr":{"UNSENT":0,"OPENED":1,"HEADERS_RECEIVED":2,"LOADING":3,"DONE":4,"readyState":4,"status":0,"timeout":0,"withCredentials":false,"upload":{},"_aborted":false,"_hasError":true,"_method":"POST","_response":"","_url":"http://localhost:3001/api/users/login","_timedOut":false,"_trackingName":"unknown","_incrementalEvents":false,"_requestId":null,"_cachedResponse":null,"_headers":{"content-type":"application/json"},"_responseType":"json","_sent":true,"_lowerCaseResponseHeaders":{},"_subscriptions":[]},"request":{"async":true,"crossDomain":true,"withCredentials":false,"headers":{"Content-Type":"application/json"},"method":"POST","responseType":"json","timeout":0,"url":"http://localhost:3001/api/users/login","body":"{\"email\":\"mymail#gmail.com\",\"password\":\"mypassword\"}"},"status":0,"responseType":"json","response":null}
The Ajax error is not very descriptive. Does anyone what I may be doing wrong?
It seems that this happened due to the simple fact that the api address was set to localhost or 127.0.0.1
Ensure to have set this to your local network IP address!