views:

196

answers:

2

UPDATE: I managed to get this thing working!

Turns out, you NEED to send a secure ticket with the call to get a proper response. I have no idea why it worked in Poster without it. There are a couple other parameters that are required which ColdFusion apparently doesn't send by default.

Here is a working call:

<!---MyTicketValue is sent over from the SAML gateway--->
<cfset myTicket = #cookie.MyTicketValue#>

<!---here we set the XML for the POST--->
<cfsavecontent variable="APIxml"><qdbapi><ticket><cfoutput>#myTicket#</cfoutput></ticket><apptoken>c4abnsde36pse7hzurwvjjb4m</apptoken></qdbapi></cfsavecontent>

<!---and this is the post with all necessary headers (don't ask me why they're needed)--->
<cfhttp url="https://workplace.intuit.com/db/main" method="POST" result="objGet">
  <cfhttpparam type="header" name="Accept-Encoding" value="gzip,deflate"/>
  <cfhttpparam type="header" name="Keep-Alive" value="115" />
  <cfhttpparam type="header" name="QUICKBASE-ACTION" value="API_GetUserInfo" />
  <cfhttpparam type="header" name="Content-Type" value="application/xml; charset=UTF-8" />
  <cfhttpparam type="body" value="#APIxml#" />
</cfhttp>

And this returns a perfect response from the Intuit Workplace.


I am trying to send a call to Intuit's API with Coldfusion. The call must be POSTed to them (through a SAML gateway). A token must be supplied in the header.

I have really no experience with cfhttp, and am totally confused with this whole API call situation. I need some pretty basic assistance here.

Basically, how do I format the cfhttp tag so that I can have this token in the header?

<cfxml variable="API_GetUserInfo">

<qdbapi>
   <apptoken>c4abnsdepseds7hdzurwvjjb4m</apptoken>
   <email>[email protected]</email>
</qdbapi>

</cfxml>


<cfhttp
  url="https://workplace.intuit.com/db/main"
  method="POST"
  result="objGet">

  <cfhttpparam
    type="header"
    name="Header"
    value="QUICKBASE-ACTION:API_GetUserInfo" 
  />

  <cfhttpparam
    type="xml"
    name="API_GetUserInfo"
    value="#API_GetUserInfo#"
  />

</cfhttp>

Later, I've tried the Poster add on for Firefox.

I can get the call to work just fine with that, but when I try to replicate it in CF, I still can't get a response.

Here's the updated code:

<cfhttp url="https://workplace.intuit.com/db/main" method="POST" result="objGet" >

<cfhttpparam type="header" name="QUICKBASE-ACTION" value="API_GetUserInfo" />

<cfhttpparam type="formfield" name="xml" value="#API_GetUserInfo#" />

</cfhttp>

And in Poster, here's what I'm entering:

URL: https://workplace.intuit.com/db/main

Content Type: xml

Content:

<qdbapi>
  <apptoken>c4abnsdepseds7hdzurwvjjb4m</apptoken>
  <email>[email protected]</email>
</qdbapi>

and 1 Header:

Name: QUICKBASE-ACTION

Value: API_GetUserInfo

With these settings, I get a correct response.

Any ideas as to what I'm doing wrong with the coldfusion code?

+3  A: 

Just poking around the intuit sdk page, it looks like there is a PHP dev kit available if you have access. I would poke around the HTTP call it makes to get an idea of how to structure a similar call in ColdFusion. Because you say "POSTed" you would normally use the type of FormField for the second cfhttpparam tag as using the type of XML changes the structure and content type of the request.

I also noticed a Java SAML gateway on their site that you might be able to add the war file to your site and call the Java api directly from your ColdFusion code.

shooksm
poking around the php dev kit is a very good idea! it never crossed my mind.however, I think my main issue right now is coldfusion syntax. I have an idea of what I want to do, I just am having troubles making CF do it, and doing it so that Intuit understands.
Jimmy
I think if you just change the 2nd cfhttpparam to type="formfield" as shooksm suggests, you might be on your way.
Adam Tuttle
unfortunately, that didn't help. It gives me the same response.
Jimmy
+2  A: 

Got it. You need to wrap your XML with a ToString. It will put the XML declaration at the beginning of the XML to make it a valid XML document. I just tried it on my end and it worked.

<cfhttpparam
    type="xml"
    name="API_GetUserInfo"
    value="#ToString(API_GetUserInfo)#"
/>

Since the above didn't work, I tried several other things and here is where I am at. I used Fiddler to monitor the HTTP requests that Poster makes that we know is a good request and here is the request header:

POST https://workplace.intuit.com/db/main HTTP/1.1
Host: workplace.intuit.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 ( .NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
QUICKBASE-ACTION: API_GetUserInfo
Content-Type: application/xml; charset=UTF-8
Content-Length: 109
Cookie: scache=Jun  3 2010 18:30:57_3; ptest=1277297927934; stest=1277298582509
Pragma: no-cache
Cache-Control: no-cache

<qdbapi>
  <apptoken>c4abnsdepseds7hdzurwvjjb4m</apptoken>
  <email>[email protected]</email>
</qdbapi>

The next thing I tried was mimicking as much of the request as I could but it is still not returning the XML. Some things you will notice changed is the use of CFSAVECONTENT to get rid of the XML declaration and the addition of a number of header and cookie properties to try to simulate the Poster request:

<cfsavecontent variable="API_GetUserInfo"><qdbapi>
    <apptoken>c4abnsdepseds7hdzurwvjjb4m</apptoken>
    <email>[email protected]</email>
</qdbapi></cfsavecontent>

<cfhttp url="https://workplace.intuit.com/db/main" method="POST" result="objGet" useragent="Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 ( .NET CLR 3.5.30729)">
    <cfhttpparam type="header" name="Accept" value="application/xml" />
    <cfhttpparam type="header" name="Accept-Language" value="en-us,en" />
    <cfhttpparam type="header" name="Accept-Charset" value="utf-8" />
    <cfhttpparam type="header" name="Keep-Alive" value="115" />
    <cfhttpparam type="header" name="Connection" value="keep-alive" />
    <cfhttpparam type="header" name="QUICKBASE-ACTION" value="API_GetUserInfo" />
    <cfhttpparam type="header" name="Content-Type" value="application/xml; charset=UTF-8" />
    <cfhttpparam type="cookie" name="scache" value="Jun  3 2010 18:30:57_3" />
    <cfhttpparam type="cookie" name="ptest" value="1277297927934" />
    <cfhttpparam type="cookie" name="stest" value="1277298582509" />
    <cfhttpparam type="header" name="Pragma" value="no-cache" />
    <cfhttpparam type="header" name="Cache-Control" value="no-cache" />
    <!---<cfhttpparam encoded="no" type="formfield" name="" value="#API_GetUserInfo#" />--->
    <cfhttpparam type="body" value="#API_GetUserInfo#" />
</cfhttp>

CFHTTP is not translating some property as expected and I am just not sure which one it is. Maybe a second set of eyes will help. Might have to use CreateObject and Java directly (java.net classes) to do the HTTP request and bypass CFHTTP and what every wonky default it is adding to the HTTP request to cause it to fail.

shooksm
It still isn't working for me. :(
Jimmy
Could you be more specific? When I used your code as is, I got nothing back in the CFHTTP.FileContent but when I used ToString, the site returned back content.
shooksm
Oh yeah, sorry. I get content back, but its garbage. The response, when the call is done correctly, is supposed to be xml with some important info. The response I get is html (its actually the html for Workplace.Intuit.com).
Jimmy
Interesting. I didn't bother to look at the returned results as something was better then nothing. I am busy at work but will take a look tonight. Specifically, I am going to monitor the HTTP request using poster and try to duplicate it 100% using CFHTTP and see what I come up with. Maybe it needs something else like a valid user agent to trick it into sending back XML.
shooksm
Oh wow. Thanks for all the help! I hope you can figure something out because the Intuit guys aren't being nearly as helpful...
Jimmy
Wow. Thank you so much for putting all this effort into figuring this out for me! I tried sticking your code into mine and switching some stuff around even and I'm getting no result. I'll just have to go some other route. I really appreciate the effort. I wish I could upvote 20 times.
Jimmy