Save JSON response in Coldfusion - json

I want to sent push messages with Firebase Cloud Messaging. Everything is working, except for one thing. I want to save the response (see below) from Firebase to update a user profile in the database. So let's say the response gives back a failure, I want to sent that response back to my database.
To sent a push message I use this script:
var key = 'my-key';
var to = 'to-key';
var notification = {
'title': 'Portugal vs. Denmark',
'body': '5 to 1',
'icon': 'firebase-logo.png',
'click_action': 'http://localhost:8081'
};
fetch('https://fcm.googleapis.com/fcm/send', {
'method': 'POST',
'headers': {
'Authorization': 'key=' + key,
'Content-Type': 'application/json'
},
'body': JSON.stringify({
'notification': notification,
'to': to
})
}).then(function(response) {
console.log(response);
}).catch(function(error) {
console.error(error);
})
The response I get back from the Firebase is:
My question is how can I save (or sent) that response to my coldfusion server. I was thinking of re-writing the script to coldfusion like:
<cfscript>
objResponse = {
'message':{
'to':'SOME_TOKEN',
'notification':{
'title': 'Portugal vs. Denmark',
'body': '5 to 1',
'icon': 'firebase-logo.png',
'click_action': 'localhost:8081'
}
}
}
</cfscript>
<Cfdump var="#objResponse#" >
<cfoutput >#SerializeJSON(objResponse)#</cfoutput>
<cfhttp url="https://fcm.googleapis.com/fcm/send" method="post" result="objGet">
<cfhttpparam type="header" name="Accept" value="application/json" />
<cfhttpparam type="header" name="Authorization" value="key=MY_KEY">
<cfhttpparam type="header" name="Content-Type" value="application/json" />
<cfhttpparam type="body" value='#SerializeJSON(objResponse)#'/>
</cfhttp>
But that is giving me a 400 bad request:
On https://firebase.google.com/docs/cloud-messaging/http-server-ref#interpret-downstream I found
Only applies for JSON requests. Indicates that the request could not be parsed as JSON, or it contained invalid fields (for instance, passing a string where a number was expected). The exact failure reason is described in the response and the problem should be addressed before the request can be retried.
So I understand it has something to do with the JSON request i'm sending, but I can't figure out what the problem is.

Since you are making this request from javascript in your browser, you would need to add some code in the .then() callback that would make an ajax post request to your ColdFusion server, sending the data you want to save.
Not sure what your flow is here, but you could also make the http request from the ColdFusion server itself.

Related

How to allow Cors Headers in Google AppScript for making an XMLHttpRequest?

I have created a doGet and doPost endpoints in my appscript. When I hit the endpoint to make a post request from Python, it does work perfectly and as expected.
But when I try to hit the same url with my Flutter based mobile App, it throws me an XML error. (Which I suspect is related to CORSING).
When I hit the url with get request, I get the right response, but post request is failing. To ensure that my Post request is properly configured, I have made a post request to public API and it worked like charm.
Is it possible to add headers, where I could enable cors like this:
allowHeaders = {
"Access-Control-Allow-Origin": "*", // Required for CORS support to work
"Access-Control-Allow-Credentials": true, // Required for cookies, authorization headers with HTTPS
"Access-Control-Allow-Headers": "Origin,Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,locale",
"Access-Control-Allow-Methods": "POST, OPTIONS"
}
Here is what my doPost request returns:
ContentService.createTextOutput(JSON.stringify(
{
data: isAuthenticated.data,
error: true,
//request: request,
msg: query.apiKey,
//paramters:request.parameters
})).setMimeType(ContentService.MimeType.JSON)
Here is my python script to get the post response:
requests.post("https://script.google.com/macros/s/AKfycbz7kTROol8u509M_p9pMZ9XRnL-myVjcRQKeb9Etp_OIMPnH640vHf_0Jp2dvvrbto7kOg/exec",
json = requestObject)
And here is my Flutter function:
Future<http.Response> createAlbum() async{
print("Trying to make a post request");
var result = await http.post(Uri.parse('https://script.google.com/macros/s/AKfycbz7kTROol8u509M_p9pMZ9XRnL-myVjcRQKeb9Etp_OIMPnH640vHf_0Jp2dvRIco7kOg/exec'),
headers: {"Content-Type": "application/json"},
body: jsonEncode(<String, dynamic>{
"apiKey":apiKey,
"operationType":"register_user",
"operationData": {
"email": "shivam#yoptima.com",
"otp": 318728
}
}),
);
print("Here is the result: " + result.body);
}
Just to clarify things:
Get Request works for both the platforms.
Post Request works with python for AppScript.
Post Request works for any other public API from flutter.
Post Request doesn't work for Flutter when Hitting AppScript API.
I suspect it to be something to do with CORS. (But not very sure).
Flutter http library makes request via XMLHttpRequest.

I can't resolve error with API POST function

I am trying to post data via an API interface.
I have checked the JSON of the data with JSON formatter and tested the API post in ReqBin and they work fine but when I execute it in App Script I get the same error, seemingly ignoring the attributes I put in the options variable.
Error is
{"code":"not_acceptable","message":"I can only talk JSON. Please set 'Accept' and 'Content-Type' to 'application/json' in your http request header."}
Note: I have tried sending just the data as the payload without json.stringify'ing it as it is formatted as JSON to start with.
In all cases it executes, but comes back 406
Is there another way to add 'Accept':"application/json" into the header??
My Code
function exportNation()
{
// Make a POST request with a JSON payload.
var data = {
"person":
{
"email":"mikenizzckelisaweiner#tv.com",
"last_name":"Bozzrovowski",
"first_name":"Edwzzard",
"tags":"Imported Data,Volunteer,Sign Request"
}
};
var options = {
"method":"POST",
"Content-Type":"application/json",
'Accept':"application/json",
'muteHttpExceptions':true,
'payload':JSON.stringify(data)
};
var response = UrlFetchApp.fetch('https://xyz.xyz.com/api/v1/people?
access_token=5604da84fXXXXXXXXXXXXXXXX42da1ea',options );
}
Any help would be greatly appreciated!
Additional HTTP headers need to be sent as a headers object.
See: https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app#advanced-parameters
var options = {
"method":"POST",
"contentType":"application/json",
"headers": {'Accept':"application/json"},

JSON is Malformed in Fetch POST request using React Native

I have a function in a React Native app that is supposed to send data to a server that I'm hosting. This function seems to be throwing errors though every time I press submit and this function is called. The function should be sending a POST request to my webserver and receive information back. It has no problem receiving information but sending is another story... The current code below is giving me an error that says "JSON Parse error: Unrecognized token '<'. But as you can see in my code below I do not even have that symbol present in the 2nd parameter of the fetch function. Occasionally, when I tweak what I have I get an error that also says 'JSON Parse error: Unexpected EOF'. I am not sure how exactly this request is I guess 'malformed'. I am pulling it straight from the docs given by Facebook. I have also tried Axiom & XMLHttpRequest and I am still seeing similar JSON errors. Anyone?
login = () => {
// check if the username is being passed off properly...
//alert(this.state.username);
fetch('MYURL', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
username: this.state.username,
password: this.state.password,
})
})
.then(function(response){ return response.json(); }) // transforms response into data that is readable for this app...
.then(function(data) {
console.log(data);
})
.done();
}
When I shoot that post request in Postman I get back header "Content-Type: text/html; charset=UTF-8". So you don't get json back at all, that's why it doesn't work. I would venture that you have to add the correct application/json header in your backend.

upload.approach "pull" request returns success message, but the content isn't valid

There does not exist an official Vimeo API SDK for Coldfusion, so I wrote one based on the official PHP code. In the end, we're only interested in what JSON string Vimeo sees when it receives a request anyway, right?
I'm attempting to do a PULL approach, and I receive a video ID, link, status of "processing" etc when I run the script. The video appears in my account online as "Pending". This is the JSON content of my request:
Headers:
POST https://api.vimeo.com/me/videos
{
"Content_Type": "application/json",
"Authorization": "Bearer 7b8686f6d7cb....65990",
"Accept": "application/vnd.vimeo.*+json; version=3.4"
}
body:
{
"upload": {
"approach":"pull",
"size":30003213,
"link":"https://mysite.me/api/index.cfm/video?PK=Na6z6ZZMQ&SI=45rtt4423"},
"name":"Employee1.mp4"
}
}
The response I receive back from Vimeo includes the following data (obviously this is not the entire response):
{
"Statuscode": "201 Created",
"Filecontent": {
"uri":"/videos/3...393",
"name":"Untitled",
"description":null,
"link":"https://vimeo.com/3...393"
},
"app":{
"name":"My Vimeo App Name",
"uri":"/apps/14...6"
},
"status":"uploading",
"resource_key":"0b83....d49dc",
"upload":{
"status":"in_progress",
"complete_uri":null,
"approach":"post",
"size":null,
"redirect_url":null,
"link":null
},
"transcode":{"status":"in_progress"}
}
I can't seem to get Vimeo to recognize this as a "pull" approach, nor recognize the file name, size, etc. It appears that the request is successful, but the video in "My Videos" on Vimeo never completes uploading or transcoding, has no name, doesn't honor my settings for privacy or other options, and seems to be some sort of processing error.
I'll be glad to share some ColdFusion code with any experienced with it, but I feel like the issue probably lay with the compiled JSON rather than ColdFusion.
Solution:
when sending the requestes via ColdFusion, instead of sending the JSON content like this:
<cfhttpparam type="body" value="{"upload":{"approach":"pull","size":30003213,"link":"https://example.com/api/index.cfm/video?PK=Na6z6Zp4ca&CK=4EP56DM566&SI=6868"},"name":"EmployeeProfile.mp4"}" />
the parameters should be sent like this:
<cfhttpparam type="formField" encoded="false" name="upload.approach" value="pull" />
<cfhttpparam type="formField" encoded="false" name="upload.size" value="30003213" />
<cfhttpparam type="formField" encoded="false" name="upload.link" value="https://example.com/api/index.cfm/video?PK=Na6z6Zp4ca&CK=4EP56DM566&SI=6868" />
Not sure why, but when you send a POST request to Vimeo from ColdFusion, Vimeo does not recognize any of the JSON body of the cfhttpparam. You must use type="formField".

ColdFusion and SmartSheet API

I'm attempting to call the smartsheet.com api and read the JSON data from a list sheet request. Im new to API's so I'm certain I'm missing much with my code.
Here is what I have so far:
<cfscript>
apiURL = "https://api.smartsheet.com/2.0/sheets";
apiToken = "xxxxxxxxxxxxxxxxxxxxxxxxx";
</cfscript>
<cfhttp url="#apiURL#" method="GET" result="httpResp" timeout="120" charset="utf-8">
<cfhttpparam type="header" name="Authorization" value="Bearer #apiToken#" />
</cfhttp>
However I do not receive the desired response:
I was attempting to use the sample provided to retrieve the data:
SmartSheet API 2.0
Example Request:
curl https://api.smartsheet.com/2.0/sheets -H "Authorization: Bearer ACCESS_TOKEN"
Example Response:
{
"pageNumber":1,
"pageSize":100,
"totalPages":1,
"totalCount":2,
"data":[
{
"accessLevel":"OWNER",
"id":4583173393803140,
"name":"sheet 1",
"createdAt":"2015-06-05T20:05:29Z",
"modifiedAt":"2015-06-05T20:05:43Z"
},
{
"accessLevel":"OWNER",
"id":2331373580117892,
"name":"sheet 2",
"createdAt":"2015-06-05T20:05:29Z",
"modifiedAt":"2015-06-05T20:05:43Z"
}
]
}
What version of CF? Looks similar to this issue: ColdFusion 9.0.1 - 3574332 CHTTP returns filecontent as java.io.ByteArrayOutputStream when mimetype is application/json. The workaround is to either:
Set the CFHTTP attribute getasbinary="never" OR
Convert the returned fileContent object into a string using:
<cfset rawJSONString = httpResp.fileContent.toString()>