Jump to content

REST service Client - is it feasible? - is it recommended?


Recommended Posts

This is more of request for advice from the more experienced AutoIt'ers ..

There is a REST service available (yammer.com) that is a great system but the Adobe AIR client is crap. No one has made a native Windows client that I can find. I don't want to spend a lot of time on it, but am thinking of playing with making one that is very basic.

Searching through the forums, I see a number of functions for AutoIt to retrieve data from a web address, but little on how to POST to the service. (I did find one post but can't locate it again, although some simple tests weren't working for me with their example using wininet dll). Is it feasible to make a client app that could GET and POST data back and forth without too much trouble?

The responses will come back as JSON, and I did find that someone created a UDF for working with that, so I'm assuming that wouldn't be too difficult, unless anyone has experience to say otherwise.

Input is greatly appreciated. If it turned out decent enough and stable, I would release it for all to use, since its a shame there is no native option for this service.

Link to comment
Share on other sites

It seems to be an interesting project, but since I don't use the platform, I don't need it :oops:

You should be able to establish the communication with WinHTTP.

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

Thanks ProgAndy! I must not have been using the right word combinations as I hadn't come across your UDF, but it looks like it would work great. A simple function could be written utilizing your WinHTTP functions so that it would be easy to do the repetitive actions of GETting and POSTing responses over and over again for the different areas of the app. Now let's see if I get interested enough to continue. ;-)

Link to comment
Share on other sites

AutoIt is a bit undergunned in terms of what is available to consuming RESTful services compared to other languages. There is nothing aimed directly at consuming REST services.

There are UDFs though that can help. WinHTTP as protocol (beware of caching!) and JSON and XML UDFs for parsing. There is next to nothing for consuming the resources that make up the internet: There's nothing to parse or display HTML (other than embedded IE, which is limited) and image and video libraries are not always available. When they are available, they almost always rely on external libraries (licensing, open source).

Having lots of UDFs which somewhat conform to the same standards and ideology (naming and structure mostly) is nice. And while they work well on themselves, they don't always play nice together. Possibly requiring user/programmer to write wrapper-like libraries.

Lack of a way to create data structures (struct, class, associative array -- pick any) makes user implementations awkward at best and difficult at the worst, so you will want to consider using AutoItObject. A good REST service might also use code on demand, which is made difficult by limited dynamic behavior in that area (See #http://www.autoitscript.com/trac/autoit/ticket/1931).

As conclusion: This is a very interesting project. :oops: If you have the time, I am absolutely sure you can create a good solution in AutoIt. There are other languages that might be a better choice, but that always depends on the service you are consuming.

Link to comment
Share on other sites

There's nothing to parse or display HTML

That is not entirely correct. There exists an UDF for and They support some sort of extended subset of HTML and JS

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

  • 3 weeks later...

Just an update: I actually configured a client to get through the OAuth 1.0 hoops, correctly get authorized, access the xml version of the REST service and pull down the data. So, it does work and its not that complicated. The WinHTTP UDF worked great. The idea became more tedious as I tried to format the data to look like something.

AFAIK, there isn't a flexible 'panel' control of sorts to stick this stuff on and let it create a scrollable view. I did use a UDF I found for scrolling which worked well but seemed like it was starting to get complicated really fast when you wanted to be able to also resize the entire gui and still make everything work. Then, the messages retrieved are of different lengths, so creating labels or something like that to display them at different sizes also became a pain. Bottom line, creating a flexible, easy-to-use gui for this sort of thing seemed to be the cumbersome part to me. I was spending way too much time on trying to get it to look decent when it was relatively simple to get a working model up and running.

If anyone has some pointers on these gui issues that I mentioned or ideas, then maybe I can give it a go. Thanks for the input up till now.

Link to comment
Share on other sites

  • 3 months later...

Just an update: I actually configured a client to get through the OAuth 1.0 hoops, correctly get authorized, access the xml version of the REST service and pull down the data. So, it does work and its not that complicated. The WinHTTP UDF worked great.

Would you be willing to share your REST interface code, esp around the OAuth hoops? I'm trying to consume a service, but don't need the display. By spending the time I'm sure I could gin something up, but a leg up would be helpful.

Link to comment
Share on other sites

Would you be willing to share your REST interface code, esp around the OAuth hoops? I'm trying to consume a service, but don't need the display. By spending the time I'm sure I could gin something up, but a leg up would be helpful.

Sure, this is what I had. Haven't touched it since the original playing around since the GUI issues discouraged me too much and got busy with other things. This would definitely need a lot of cleaning up and more error handling, but this was a working model... I tried to take out everything except the parts that really pertain to the authorization and using it. You can piece it together depending on your application.

Func Authorize($verifier_input = "")
If $verifier_input = "" Then
; initial auth setup
$path = "/oauth/request_token"
$postdata = "oauth_consumer_key=" & $oauth_consumer_key
$header = 'Authorization: OAuth oauth_consumer_key="' & $oauth_consumer_key & '"'
$header &= ',oauth_signature_method="PLAINTEXT"'
$header &= ',oauth_timestamp="' & Timestamp() & '"'
$header &= ',oauth_nonce="' & Nonce() & '"'
$header &= ',oauth_signature="' & $oauth_signature & '"'

$response = MakeRequest("POST", $path, $postdata, $header)

SetTokenStrings($response[1])

$path = "/oauth/authorize"
$postdata = $response[1]
$header = ""
$link = "https://" & $host & $path & "?" & $postdata
ShellExecute($link)

Else
; returning setup, process verifier
$oauth_verifier = $verifier_input

$path = "/oauth/access_token"
$postdata = "oauth_consumer_key=" & $oauth_consumer_key
$header = 'Authorization: OAuth oauth_consumer_key="' & $oauth_consumer_key & '"'
$header &= ',oauth_token="' & $oauth_token & '"'
$header &= ',oauth_signature_method="PLAINTEXT"'
$header &= ',oauth_timestamp="' & Timestamp() & '"'
$header &= ',oauth_nonce="' & Nonce() & '"'
$header &= ',oauth_signature="' & $oauth_signature & '"'
$header &= ',oauth_verifier="' & $oauth_verifier & '"'

$response = MakeRequest("POST", $path, $postdata, $header)

SetTokenStrings($response[1])

IniWrite($ini, "auth", "tk", $oauth_token)
IniWrite($ini, "auth", "sig", $oauth_signature)
AuthStuff("HIDE")

Refresh()

EndIf

EndFunc



Func Refresh()
; make sure it isn't too recent first
If Timestamp() - $last_refresh > 44 Then
$last_refresh = Timestamp()

$path = "/api/v1/messages.xml"
$postdata = ""
$header = 'Authorization: OAuth oauth_consumer_key="' & $oauth_consumer_key & '"'
$header &= ',oauth_token="' & $oauth_token & '"'
$header &= ',oauth_signature_method="PLAINTEXT"'
$header &= ',oauth_timestamp="' & Timestamp() & '"'
$header &= ',oauth_nonce="' & Nonce() & '"'
$header &= ',oauth_signature="' & $oauth_signature & '"'

$response = MakeRequest("GET", $path, $postdata, $header)
$last_xml = $response[1]
Else
MsgBox(0, "", "Too soon to refresh!")
EndIf
_XMLLoadXML($last_xml)
$nNodes = _XMLGetNodeCount("/response/messages/message")
For $i = 1 To $nNodes
$body = _XMLGetValue("/response/messages/message[" & $i & "]/body/plain")

$text = $body[1]

Next

EndFunc

Func Post($s)
$path = "/api/v1/messages.xml"
$postdata = "body=" & $s ; need to encode this
$header = 'Authorization: OAuth oauth_consumer_key="' & $oauth_consumer_key & '"'
$header &= ',oauth_token="' & $oauth_token & '"'
$header &= ',oauth_signature_method="PLAINTEXT"'
$header &= ',oauth_timestamp="' & Timestamp() & '"'
$header &= ',oauth_nonce="' & Nonce() & '"'
$header &= ',oauth_signature="' & $oauth_signature & '"'
$header &= ' Content-Type: application/x-www-form-urlencoded'

$response = MakeRequest("POST", $path, $postdata, $header)

_ArrayDisplay($response)
;~ Refresh()
EndFunc

Func Startup()
; see if ini file is there first
If Not FileExists($ini) Then
FileOpen($ini, 10)
FileClose($ini)
EndIf

$temp_token = IniRead($ini, "auth", "tk", "")
$temp_signature = IniRead($ini, "auth", "sig", "")

If $temp_token = "" Then
; if blank, do initial authorization first
AuthStuff("SHOW")
MsgBox(16, "Initial setup required", "It appears that you have not set up authorization.")
Authorize()
Else
$oauth_token = $temp_token
$oauth_signature = $temp_signature
;~ Refresh()
EndIf


EndFunc

Func MakeRequest($req_type, $req_path, $req_postdata, $req_header, $req_return_type = 1)
; set up connection, pass arguments and return something ... options for returning?

Local $t_or_f
Switch $req_return_type
Case 1
; default return type
$t_or_f = "True"
Case 2
$t_or_f = "False"
EndSwitch

Local $session = _WinHttpOpen()
Local $connection = _WinHttpConnect($session, $host)
Local $response = _WinHttpSimpleSSLRequest($connection, $req_type, $req_path, $req_postdata, Default, $req_header, $t_or_f)
_WinHttpCloseHandle($connection)
_WinHttpCloseHandle($session)

Return $response

EndFunc

Func SetTokenStrings($s)
; we need oauth_token and oauth_token_secret from string and might be out of order
$aResponse = StringSplit($s, "&")
For $i = 0 To UBound($aResponse) -1
If StringInStr($aResponse[$i], "oauth_token=") Then
$oauth_token = StringReplace($aResponse[$i], "oauth_token=", "")
ElseIf StringInStr($aResponse[$i], "oauth_token_secret=") Then
$oauth_token_secret = StringReplace($aResponse[$i], "oauth_token_secret=", "")
EndIf
Next

$oauth_signature = $oauth_consumer_secret & "%26" & $oauth_token_secret

EndFunc


Func Timestamp()
Local $rslt = DllCall("msvcrt.dll", "int:cdecl", "time", "int", 0)
If @error = 0 Then Return $rslt[0]
Return -1
EndFunc

Func Nonce()
Return Random(100000000, 999999999, 1)
EndFunc
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...