Coldfusion Youtube API Upload Cfhttp Snippet - coldfusion

I am trying to upload a video using Youtube API so far so good but when i try to pass snippet and status with cfhttp in order to start a resumable upload although i get a 200 ok respond it seems that there none snippet parameter as a result the video does not have the appropriate title...
<cfset jsondet='{
"snippet": {
"title": "My video title",
"description": "This is a description of my video",
"tags": ["cool", "video", "more keywords"],
"categoryId": 22
},
"status": {
"privacyStatus": "private",
"embeddable": True,
"license": "youtube"
}
}'>
<cfhttp method="Post" url="https://www.googleapis.com/upload/youtube/v3/videos?uploadType=resumable&part=snippet,status" >
<cfhttpparam type="header" value="Bearer #form.rectoken#" name="Authorization">
<cfhttpparam type="header" value="278" name="Content-Length">
<cfhttpparam type="header" value="application/json; charset=UTF-8" name="Content-Type">
<cfhttpparam type="header" value="3000000" name="X-Upload-Content-Length">
<cfhttpparam type="header" value="video/*" name="X-Upload-Content-Type">
<cfhttpparam type="body" value="#serializeJSON(jsondet)#">
</cfhttp>
Does anyone have any freaking idea?

On this line " <cfhttpparam type="header" value="Bearer #form.rectoken#" name="Authorization">" what is rectoken?

Just Replace Jsondet.... As silly as that...
<cfset jsondet={
"snippet"= {
"title"= "My video title",
"description"= "This is a description of my video",
"tags"= ["cool", "video", "more keywords"],
"categoryId"= 22
},
"status"= {
"privacyStatus"= "private",
"embeddable"= True,
"license"= "youtube"
}
}>

Related

Coldfusion How to save PDF Response Stream to File

We have a REST API that returns a stream of content-type application/pdf. I just want to save it to a file on the server.
<cfhttp url="#ApiPath#" method="post" result="res">
<cfhttpparam type="header" name="Content-Type" value="application/json" />
<cfhttpparam type="body" value="#payload#" />
</cfhttp>
<cffile action = "write" file = "#FileName#" output = "#res.fileContent#">
I've producing a blank PDF, any ideas? ( ive tried various combinations of cfdocument/cfpdf with no luck)
here's a dump of the REST response:
I think I've got it:
Solution 1:
<cfhttp url="#url#" method="post" result="res">
<cfhttpparam type="header" name="Content-Type" value="application/json" />
<cfhttpparam type="body" value="#payload#" />
</cfhttp>
<cfset bytes = res.FileContent.toByteArray()>
<cfscript>
fos = createObject("java", "java.io.FileOutputStream").init("myfile.pdf");
fos.write(bytes);
fos.flush();
fos.close();
</cfscript>
EDIT: Based on SOS's solution this also worked:
Solution 2:
<cfhttp url="#url#" method="post" result="res" getAsBinary="Auto">
<cfhttpparam type="header" name="Content-Type" value="application/json" />
<cfhttpparam type="body" value="#payload#" />
</cfhttp>
<cfset fileName = listlast(res["responseHeader"]["content-disposition"],";=")>
<cffile action="write" file="#path#\#fileName#" output="#res.FileContent#">

EZ Text API & ColdFusion

Anyone have any experience with the EZ Text API and ColdFusion? I'm trying this call:
<cfhttp url="https://app.eztexting.com/sending/messages?format=JSON"
method="POST" result="objGet" charset="utf-8">
<cfhttpparam type="header" name="Content-Type" value="application/x-www-form-urlencoded">
<cfhttpparam type="formfield" name="User" value="xxx" />
<cfhttpparam type="formfield" name="Password" value="xxx"/>
<cfhttpparam type="formfield" name="PhoneNumbers[]" value="9999999999" />
<cfhttpparam type="formfield" name="MessageTypeID" value="1" />
<cfhttpparam type="formfield" name="Message" value="Hello" />
</cfhttp>
... which is returning a status code of 200 and trying to redirect to their home page.
Their tech support can only tell me that I should use curl which is not installed on the server that I need it on. I have used curl successfully in my devel environment, so I'm sure that the url and credentials are good.
Any thoughts are welcome! Thanks.
I'm guessing you're using the REST API. If yes, the reason it's redirecting you to the home page is because the URL is incorrect. Apparently the format parameter is case sensitive. So ?format=JSON should be changed to ?format=json (all lower case).
Making that minor adjustment to your code example:
<cfhttp url="https://app.eztexting.com/sending/messages?format=json"
method="POST" result="objGet" charset="utf-8">
...
</cfhttp>
... returns the expected JSON response for bogus credentials, instead of the html for the home page:
{
"Response": {
"Status": "Failure",
"Code": 401,
"Errors": [
"Authorization Required"
]
}
}
Once you get past this issue, you may want to double check your formfield names. The API lists the parameter name PhoneNumbers, not PhoneNumbers[].

Google g suite Invalid Given/Family Name: FamilyName (ColdFusion/HTTP POST)

I have seen several posts about this issue, but I haven't been able to overcome mine using the suggestions. Following is my code and the results:
<cffunction name="CreateUser" hint="Create new GSuite user." returntype="struct" access="public">
<cfargument name="token" hint="The Google-provided access token." type="string" required="yes">
<cfargument name="state" hint="The unique anti-forgery string." type="string" required="yes">
<cfargument name="userdata" hint="A json string containing user data" type="string" required="yes">
<cfargument name="api" hint="API Key for the Google Domain" type="string" required="yes">
<cfhttp method="post" charset="utf-8" url="https://www.googleapis.com/admin/directory/v1/users?state=#state#&access_token=#token#" result="uResult">
<cfhttpparam type="header" name="auth" value="Authorization: Bearer #token#">
<cfhttpparam type="header" name="accept" value="Accept: application/json">
<cfhttpparam type="header" name="content" value="Content-type: application/json">
<cfhttpparam type="body" name="body" value=#userdata#>
</cfhttp>
<cfreturn uResult>
</cffunction>
The JSON string being used is:
{
"password":"Test#me12!",
"primaryEmail":"John#doe.com",
"name":
{
"familyName":"Doe",
"givenName":"John"
}
}
I am taking my HTTP POST structure from the following example:
Google Users: insert (Directory API)
The result I get back from Google is this:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "invalid",
"message": "Invalid Given/Family Name: FamilyName"
}
],
"code": 400,
"message": "Invalid Given/Family Name: FamilyName"
}
}
I cannot understand what might be wrong. Per other posts, I have included the content-type. Per Google's example, I have included the accept header and the auth header. Still, I cannot get a different result.
If I take the JSON string I pass to the function and use it in the Google link above, I am able to create the user. However, if I pass it through HTTP POST, I cannot. Please tell me there is a stray comma or missing dot somewhere in there.
Your header "name" and "values" looks off. Don't put the header names inside the "value" attribute. That's what the "name" attribute is for :-)
For example the authorization and disposition headers should be:
<cfhttpparam type="header" name="Content-Type" value="application/json">
<cfhttpparam type="header" name="Authorization" value="Bearer #token#">
Also, the "body" parameter has no "name" attribute, only a "value":
<cfhttpparam type="body" value="#userdata#">
For more details, see also the cfhttpparam documentation.

CFHTTP & CloudFlare API: DELETE purge_everything not working

Has anyone else been able to DELETE purge_everything with CFHTTP?
I can't seem to get ColdFusion CFHTTP to successfully purge a CloudFlare zone's cache. But I am able to do other things like list zones, etc. So I know I can successfully CFHTTP to CloudFlare's API.
This is the curl command, which works:
curl -svX DELETE -H 'X-Auth-Email: a#b.c' -H 'X-Auth-Key: XYZ' https://api.cloudflare.com/client/v4/zones/xxxxxxx/purge_cache -H 'Content-Type: application/json' --data '{"purge_everything":true}'
The error returned is:
{"success":false,"errors":[{"code":1012,"message":"Request must
contain one of \"purge_everything\" or \"files\", or
\"tags"}],"messages":[],"result":null}
I've tried so many combinations of code... these are the different variables I've tried:
<cfset stFields = '{"purge_everything":true}'>
<cfset stFieldsJson = {"purge_everything":true}>
<cfset stFieldsJson2 = {
"fields" : {
"purge_everything" : true
}
}>
<cfset stFieldsJson3 = {
"purge_everything" : true,
"fields" : {
"purge_everything" : true
}
}>
<cfset tmp = {} />
<cfset tmp['purge_everything'] = true />
... and here are some different combinations of calls I've made...
<cfhttp url="https://api.cloudflare.com/client/v4/zones/4da78b2707f9753eb79a93d505b4d0d3/purge_cache" method="DELETE" result="cFlare" charset="utf-8">
<cfhttpparam type="header" name="X-Auth-Email" value="a#b.c">
<cfhttpparam type="header" name="X-Auth-Key" value="XYZ">
<cfhttpparam type="header" name="Content-Type" value="application/json; charset=utf-8">
<cfhttpparam type="header" name="accept" value="*/*">
<cfhttpparam type="body" value="#serializeJson(stFieldsJson)#" encoded="false">
</cfhttp>
<cfdump var="#cFlare#"><Cfflush>
<cfhttp url="https://api.cloudflare.com/client/v4/zones/4da78b2707f9753eb79a93d505b4d0d3/purge_cache" method="DELETE" result="cFlare" charset="utf-8">
<cfhttpparam type="header" name="X-Auth-Email" value="a#b.c">
<cfhttpparam type="header" name="X-Auth-Key" value="XYZ">
<cfhttpparam type="header" name="Content-Type" value="application/json; charset=utf-8">
<cfhttpparam type="header" name="accept" value="*/*">
<cfhttpparam type="body" value="#serializeJson(stFieldsJson2)#" encoded="false">
</cfhttp>
<cfdump var="#cFlare#"><Cfflush>
<cfhttp url="https://api.cloudflare.com/client/v4/zones/4da78b2707f9753eb79a93d505b4d0d3/purge_cache" method="DELETE" result="cFlare">
<cfhttpparam type="header" name="X-Auth-Email" value="a#b.c">
<cfhttpparam type="header" name="X-Auth-Key" value="XYZ">
<cfhttpparam type="header" name="Content-Type" value="application/json">
<cfhttpparam type="header" name="accept" value="*/*">
<cfhttpparam type="body" value="#serializeJson(stFieldsJson3)#" encoded="false">
</cfhttp>
<cfdump var="#cFlare#"><Cfflush>
<cfhttp url="https://api.cloudflare.com/client/v4/zones/4da78b2707f9753eb79a93d505b4d0d3/purge_cache" method="DELETE" result="cFlare">
<cfhttpparam type="header" name="X-Auth-Email" value="a#b.c">
<cfhttpparam type="header" name="X-Auth-Key" value="XYZ">
<cfhttpparam type="header" name="Content-Type" value="application/json">
<cfhttpparam type="header" name="accept" value="*/*">
<cfhttpparam type="body" value="#serializeJson(tmp)#" encoded="false">
</cfhttp>
<cfdump var="#cFlare#"><Cfflush>
<cfhttp url="https://api.cloudflare.com/client/v4/zones/4da78b2707f9753eb79a93d505b4d0d3/purge_cache" method="DELETE" result="cFlare" charset="utf-8">
<cfhttpparam type="header" name="X-Auth-Email" value="a#b.c">
<cfhttpparam type="header" name="X-Auth-Key" value="XYZ">
<cfhttpparam type="header" name="Content-Type" value="application/json; charset=utf-8">
<cfhttpparam type="header" name="accept" value="*/*">
<cfhttpparam type="body" value='{"purge_everything":true}' encoded="false">
</cfhttp>
<cfdump var="#cFlare#"><Cfflush>
<cfhttp url="https://api.cloudflare.com/client/v4/zones/4da78b2707f9753eb79a93d505b4d0d3/purge_cache" method="DELETE" result="cFlare" charset="utf-8">
<cfhttpparam type="header" name="X-Auth-Email" value="a#b.c">
<cfhttpparam type="header" name="X-Auth-Key" value="XYZ">
<cfhttpparam type="header" name="Content-Type" value="application/json; charset=utf-8">
<cfhttpparam type="header" name="accept" value="*/*">
<cfhttpparam type="body" value='"purge_everything":true' encoded="false">
</cfhttp>
<cfdump var="#cFlare#"><Cfflush>
<cfhttp url="https://api.cloudflare.com/client/v4/zones/4da78b2707f9753eb79a93d505b4d0d3/purge_cache" method="DELETE" result="cFlare" charset="utf-8">
<cfhttpparam type="header" name="X-Auth-Email" value="a#b.c">
<cfhttpparam type="header" name="X-Auth-Key" value="XYZ">
<cfhttpparam type="header" name="Content-Type" value="application/json; charset=utf-8">
<cfhttpparam type="header" name="accept" value="*/*">
<cfhttpparam type="body" value='purge_everything' encoded="false">
</cfhttp>
<cfdump var="#cFlare#"><Cfflush>
I've also tried with and without the 'Encoded' Body attribute, with and without the 'Charset' attribute in all places.
Any help is appreciated.
Not sure which version of CF you are running. However, I suspect you are not doing anything wrong, but that <cfhttp> simply is not sending a body when the method="DELETE", which would make sense given the error message.
A simple way to test it is point your <cfhttp> call to a test page on your local CF server. On the test page dump GetHttpRequestData() so you can view the actual headers and content submitted. (Another option is to use the built in TCPMonitor on an open port, which provides more detail about both request and response. However, for this scenario, the first method is simplest.)
Test Page
<!--- echo request headers and content --->
<cfdump var="#getHTTPRequestData()#">
Request
<!--- simulate request --->
<cfset requestBody["purge_everything"] = true>
<cfhttp url="http://localhost/testPage.cfm" method="DELETE" result="cFlare" charset="utf-8" >
<cfhttpparam type="header" name="X-Auth-Email" value="a#b.c">
<cfhttpparam type="header" name="X-Auth-Key" value="XYZ">
<cfhttpparam type="header" name="Content-Type" value="application/json; charset=utf-8">
<cfhttpparam type="header" name="accept" value="*/*">
<cfhttpparam type="body" value="#serializeJson(requestBody)#" encoded="false">
</cfhttp>
<!--- display request headers and content --->
<cfoutput>#cFlare.fileContent#</cfoutput>
Notice the content, or body, is empty when method="DELETE"? However, change it to method="POST" and the content magically appears.
Sending a body with a DELETE request should be valid, so it sounds like a bug. If so, you will need to find a different tool to make the http request, such as invoking curl.exe from cfexecute, or using a custom tag like cfx_http5, or use java classes like as URLConnection or Apache's HTTPClient.
After reading up on some docs, it appears that the CloudFlare API is mixing methods in a way that CFHTTP will not.
CloudFlare's API states to use the DELETE method and content type header of "application/json". Their exact example is:
$ curl -X DELETE "https://api.cloudflare.com/client/v4/zones/023e105f4ecef8ad9ca31a8372d0c353/purge_cache" \
-H "X-Auth-Email: user#example.com" \
-H "X-Auth-Key: c2547eb745079dac9320b638f5e225cf483cc5cfdda41" \
-H "Content-Type: application/json" \
--data '{"purge_everything":true}'
However when one uses --data, curl will POST with content-type application/x-www-form-urlencoded. https://curl.haxx.se/docs/manpage.html#-d
CFHTTP however is following specs.
POST is used to send data. DELETE is for deleting the URI.
POST: https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5
DELETE: https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.7
When I CFHTTP with POST I get an error that only DELETE is accepted for the URI. When I CFHTTP with DELETE, no content is being POSTed.
My workaround, without going out of standard CFML, was to use their v1 API. It's working like a champ. https://www.cloudflare.com/docs/client-api.html

Google Calendar OAuth access_token doesn't work for POST functions

I am having issues calling Calendar:Insert via Google's API
https://www.googleapis.com/calendar/v3/calendars
I don't believe there are authorization/permission issues, the access_token is acquired via a refresh_token with the following scope: "https://www.googleapis.com/auth/calendar"
When I use a valid access_token to perform GET there are no issues, but this is a POST and I consistently get this response:
{"error":
{ "errors":
[{ "domain": "global",
"reason": "authError",
"message": "Invalid Credentials",
"locationType": "header",
"location": "Authorization"
}],
"code": 401,
"message": "Invalid Credentials"
}
}
Here is the Railo code I'm running, I've stripped it of all pretense and nuance:
<cfhttp url="https://www.googleapis.com/calendar/v3/calendars" charset="utf-8" method="post">
<cfhttpparam type="header" name="Authorization" value="bearer #arguments.access_token#" />
<cfhttpparam type="formfield" name="summary" value='hello world' />
</cfhttp>
Here is an example of a get that works just fine:
<cfhttp url="https://www.googleapis.com/calendar/v3/calendars/#arguments.calendarID#/events?access_token=#arguments.access_token#" charset="utf-8" method="get" />
So far I've attempted placing the access_token in a variety of ways. As a query parameter, as a json struct in the cfhttpparam type="body" with no luck
This stackoverflow question indicates that the Google Calendar API documentation neglects to mention a required parameter "minAccessRole". I've fiddled with that too to no avail.
Some time removed from the problem often brings clarity.
With trial and error I was able to get some error code feedback from the API. At some point revealed to me the Content-Type I was sending was "octet-stream".
I added the following line, to specify the Content-Type. I chose "application/json" since the https://developers.google.com/oauthplayground/ had that as the default content-type for the operation: calendar insert.
<cfhttpparam type="header" name="Content-Type" value="application/json" />
Then it occurred to me that I was attempting to send form fields to the API and not JSON.
The final working code for callooks something like this:
<cfhttp url="https://www.googleapis.com/calendar/v3/calendars" charset="utf-8" method="post">
<cfhttpparam type="header" name="Content-Type" value="application/json" />
<cfhttpparam type="header" name="Authorization" value="bearer #arguments.access_token#" />
<cfhttpparam type="body" value='{"summary":"newCalendar"}' />
</cfhttp>