seangriffin

Twitter UDF

18 posts in this topic

#1 ·  Posted (edited)

This UDF allows users to access the Twitter API from within AutoIT.

It supports the current OAuth open authentication standard, which has become the new standard for user authentication in Twitter.

REQUIREMENTS:

  • AutoIt3 3.2 or higher
LIST OF FUNCTIONS:

_GUICtrlTwitter_Create(ByRef $twitter, $left, $top, $width, $height)

_GUICtrlTwitter_Authenticate($twitter, $twitter_ctrl, $consumer_key, $consumer_secret, $hide_token_authetication = True)

_GUICtrlTwitter_UpdateStatus(ByRef $twitter, $message, $lat, $long)

_GUICtrlTwitter_Search($search_text, $result_type = "mixed")

EXAMPLE:

The following example demonstrates how the Twitter UDF can be used to authenticate a user, update their status (post a tweet) and search for tweets in Twitter.

When the GUI first opens, two main sections are displayed:

  • Authentication
  • Tweeting
In the Authentication section, you may click on the Authenticate button to initiate the OAuth / Twitter user authentication process for this example app (which has the Consumer Key of WW6MD2bbVwoUHmCgijXog, and the Consumer Secret of fH0zAbhQD5lTBY0HRMKamftUxnWuWoHeblzGKLO2MQ).

An Authentication GUI will be displayed, and you will be prompted to enter your Twitter username and password to continue. If you don't have a Twitter account yet, you have the option to immediately create one during this process. After providing your details, and clicking the Allow button, the GUI will close, and you will be returned to the main GUI. The status bar in the main GUI will briefly report that your authentication was successful. Note that you only need to perform this authentication process once for the entire time that you use this example. If you close and re-open this example, then you need to perform this authentication process again.

Proceeding to the Tweeting section, you may now enter a Message to tweet, and optionally a latitude and longitude, and click the Tweet button. Note that the Tweet button is only active "after" you have authenticated yourself (see the paragraphs above). The status bar will briefly report that your tweet was successful. You may login to Twitter (http://twitter.com) in your own favourite browser to confirm that the tweet did work.

You can search for tweets in Twitter by entering Search Text and clicking the Search button. The Search Results listview will then be populated with a list of all results from that search.

Twitter Example.au3

DOWNLOAD:

Latest Version - v0.1 (02/07/10)

Twitter.au3

Edited by seangriffin

Cheers, Sean.

See my other UDFs:

Chrome UDF - Automate Chrome | SAP UDF - Automate SAP | Java UDF - Automate Java Applications & Applets | Tesseract (OCR) UDF - Capture text from applications, controls and the desktop | Textract (OCR) UDF - Capture text from applications and controls | FileSystemMonitor UDF - File, Folder, Drive and Shell Monitoring | VLC (Media Player) UDF - Creating and controlling a VLC control in AutoIT | Google Maps UDF - Creating and controlling Google Maps (inc. GE) in AutoIT | SAPIListBox (Speech Recognition) UDF - Speech Recognition via the Microsoft Speech (SAPI) ListBox | eBay UDF - Automate eBay using the eBay API | ChildProc (Parallel Processing) UDF - Parallel processing functions for AutoIT | HyperCam (Screen Recording) UDF - Automate the HyperCam screen recorder | Twitter UDF - Automate Twitter using OAuth and the Twitter API | cURL UDF - a UDF for transferring data with URL syntax

See my other Tools:

Rapid Menu Writer - Add menus to DVDs in seconds | TV Player - Automates the process of playing videos on an external TV / Monitor | Rapid Video Converter - A tool for resizing and reformatting videos | [topic130531]Rapid DVD Creator - Convert videos to DVD fast and for free | ZapPF - A tool for killing processes and recycling files | Sean's eBay Bargain Hunter - Find last minute bargains in eBay using AutoIT | Sean's GUI Inspector - A scripting tool for querying GUIs | TransLink Journey Planner with maps - Incorporating Google Maps into an Australian Journey Planner | Automate Qt and QWidgets | Brisbane City Council Event Viewer - See what's going on in Brisbane, Australia

Share this post


Link to post
Share on other sites



I got oAuth working in iTunesTweet by sending the data to a custom written web script.

Ah ok. Same situation here with me. Direct calls using "MSXML2.ServerXMLHTTP" or "winhttp.winhttprequest.5.1" in AutoIT failed for me, even though I was passing exactly the same headers and/or data to Twitter that the Javascript was. I couldn't believe what I was seeing. I even followed a very good (language independent) guide on the web on how to access Twitter and OAuth for client applications, and got the same failures using these HTTP objects in AutoIT. At least Javascript works reliably every time.


Cheers, Sean.

See my other UDFs:

Chrome UDF - Automate Chrome | SAP UDF - Automate SAP | Java UDF - Automate Java Applications & Applets | Tesseract (OCR) UDF - Capture text from applications, controls and the desktop | Textract (OCR) UDF - Capture text from applications and controls | FileSystemMonitor UDF - File, Folder, Drive and Shell Monitoring | VLC (Media Player) UDF - Creating and controlling a VLC control in AutoIT | Google Maps UDF - Creating and controlling Google Maps (inc. GE) in AutoIT | SAPIListBox (Speech Recognition) UDF - Speech Recognition via the Microsoft Speech (SAPI) ListBox | eBay UDF - Automate eBay using the eBay API | ChildProc (Parallel Processing) UDF - Parallel processing functions for AutoIT | HyperCam (Screen Recording) UDF - Automate the HyperCam screen recorder | Twitter UDF - Automate Twitter using OAuth and the Twitter API | cURL UDF - a UDF for transferring data with URL syntax

See my other Tools:

Rapid Menu Writer - Add menus to DVDs in seconds | TV Player - Automates the process of playing videos on an external TV / Monitor | Rapid Video Converter - A tool for resizing and reformatting videos | [topic130531]Rapid DVD Creator - Convert videos to DVD fast and for free | ZapPF - A tool for killing processes and recycling files | Sean's eBay Bargain Hunter - Find last minute bargains in eBay using AutoIT | Sean's GUI Inspector - A scripting tool for querying GUIs | TransLink Journey Planner with maps - Incorporating Google Maps into an Australian Journey Planner | Automate Qt and QWidgets | Brisbane City Council Event Viewer - See what's going on in Brisbane, Australia

Share this post


Link to post
Share on other sites

Great to see oAUTH working via AutoIT! But i have a problem. I use a program that sends messages via commandline. I build a app with autoit to send the commandline string to twitter (currently via the old Basic Auth) this program kills it self after the message has been send. The autoit app post messages to a private twitter account. Is it possible to use oAUTH without authenticate again?

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

Ok, reviving an old thread here, sorry :)

First off... FANTASTIC work on this! I had been trying to figure a way to authenticate with Twitter, since the old version no longer works.

I have this working fairly well in the application I am working on. My script has a receiver function that allows SendMsg commands, and does away with the GUI all together. This is being done to integrate with a CarPC front End, Ride Runner. When done it will allow tweets to be sent by using the On Screen Keyboard, as well as buttons to tweet your location ect ect.

The only thing I can not overcome is the having to click the "Allow" button for the authentication. It would appear that they may have changed the code on the site on how the form is submitted. I tried different examples in the AI Help documentation, as well as searching the here on the AI forums with no avail.

I did find that where the "_IEAction($submit, "click")" command is located, seems to be before the authentication form loads. I have moved it down in the script lower in the code, and added a _IELoadWait($twitter) so the form fully loads on the screen before trying to click something.

_IENavigate($twitter, "https://twitter.com/oauth/authorize?oauth_token=" & $oauth_token)
    _IELoadWait($twitter)


    if $hide_token_authetication = True Then GUICtrlSetState($twitter_ctrl, $GUI_SHOW)

        sleep(500)
    $form = _IEFormGetObjByName($twitter, "request")
    $submit = _IEFormElementGetObjByName($form, "Allow")
    _IEAction($submit, "click")
;~  _IELinkClickByText ($twitter, "Allow")

As you can see, I also tested the IELinkClickByText command which seems to be of no help.

I just can not seem to get this to auto click the "Allow" on the page.

Any help here would be greatly appreciated!

Edited by JohnWPB

Share this post


Link to post
Share on other sites

No ideas here on how to auto click the "Allow" button?

Share this post


Link to post
Share on other sites

I've just downloaded and tried this out - got myself a consumer key, etc.

Only problem is, twitter has given me back a PIN number which apparently needs to be entered into the application to complete the oAuth process. Have I missed something? The dialog says -

---

You've granted access to TrollDetector!

Next, return to TrollDetector and enter this PIN to complete the authorization process: XXXXXXX(blanked out)

← Go to Twitter Go to the TrollDetector homepage

You can revoke access to any application at any time from the Applications tab of your Settings page.

By authorizing an application you continue to operate under Twitter's Terms of Service. In particular, some usage information will be shared back with Twitter. For more, see our Privacy Policy.

---

So, have twitter overlaid another hurdle that has to be jumped over which the UDF doesn't currently support?

Share this post


Link to post
Share on other sites

Aha - worked it out - in

_GUICtrlTwitter_Authenticate

you need to include a new string to look for when checking the dialog output for the username/password entry -

Do          
    Sleep(250)
    $response = _IEBodyReadText($twitter)   
Until ( StringInStr($response, "successfully granted access") or StringInStr($response, "You've granted access to") )

Adding this clears the successfully authenticated dialog and clears things again.

Share this post


Link to post
Share on other sites

I've been trying to get this to work but it is hanging up in the authenticate once it receives the PIN. It should be displaying another form that can be submitted to complete the final authentication step but instead the panel content remains empty. I will continue to work on it and see if there is something wrong in the html that it is trying to display but if anyone has already overcome this, please let me know.

Share this post


Link to post
Share on other sites

Hi,

I have been unable to understand this. Sometimes the below mentioned error and sometimes just before the msgbox.

To be honest -both the for-loops have gone way over my head.

Regards

Deltarocked

Error :

Variable must be of type "Object".:

for $each_attribute in $entry_attribute

for $each_attribute in $entry_attribute^ ERROR

Code:

for $each in $entry
  MsgBox(0,'EaCh',$each)
 
  $entry_attribute = StringSplit($each, @LF, 1)
  _ArrayDelete($entry_attribute, 0)
  _ArrayDelete($entry_attribute, 0)
  _ArrayDelete($entry_attribute, UBound($entry_attribute - 2))
  _ArrayDelete($entry_attribute, UBound($entry_attribute - 2))
  for $each_attribute in $entry_attribute
   if StringInStr($each_attribute, ">") > 0 And (StringInStr($each_attribute, ">") <> StringLen($each_attribute)) Then
    $each_attribute_part = StringSplit($each_attribute, "<>")
    ;_ArrayDisplay($each_attribute_part)
    $search_result.item("entry" & $entry_num & "." & $each_attribute_part[2]) = $each_attribute_part[3]
   EndIf
  Next
  $entry_num = $entry_num + 1
Next

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

Hi,

for those users who want to build their own twitter client . Register on twitter and get the auto generated values and tweet.

Since everything is stored in plain text - exercise caution / use encryption.

regards
Deltarocked

Global Variables:
 

Global $sTwitter_status_id = IniRead('Twitter.ini', 'TwitterPost', 'status_id', '')
Global $sTwitter_post_title = IniRead('Twitter.ini', 'TwitterPost', 'post_title', '')
Global $sTwitter_post_time = IniRead('Twitter.ini', 'TwitterPost', 'post_time', '')
Global $sTwitter_oAuth_Consumer_key, $sTwitter_oAuth_Token, $sTwitter_ConsumerSecret, $sTwitter_TokenSecret

Ini File:

[TwitterPost]
status_id=(?i)(?:<[\s*]{0,1}link type="text[^>]*)href[\s*]?=[\s*]?["']{0,1}(.*?)['"]{0,1}(?: |>|\s)
post_title=(?i)(?:(?s)<title>*)(.*)(?:</title>)
post_time=(?i)(?:(?s)<published>*)(.*)(?:</published>)

Modified :
missed out on Quotes - added = Silly Mistake
Added : Search
 

Func _GUICtrlTwitter_UpdateStatus(ByRef $twitter, $message, $lat = "", $long = "")
    GUICtrlSetState($twitter_ctrl, $GUI_SHOW)
    _Twitter_Initialize()
    _IENavigate($twitter, "about:blank")
    $_Twitter_message_html = "    message:        <input name=""status""                 type=""text"" size=""64"" value=""" & $message & """/><br/>" & @CRLF
    $_Twitter_url_html = "    URL:            <input name=""URL""                   type=""text"" size=""80"" value=""https://api.twitter.com/statuses/update.xml""/><br/>" & @CRLF
    $_Twitter_oauth_consumer_key_html = "     consumer key:  <input name=""oauth_consumer_key""  type=""text"" size=""64"" value=""" & $sTwitter_oAuth_Consumer_key & """/><br/>" & @CRLF
    $_Twitter_oauth_signature_method_html = "     signature method: <input name=""oauth_signature_method"" type=""text"" value=""HMAC-SHA1""/>" & @CRLF
    $_Twitter_oauth_token_html = "    request token:    <input name=""oauth_token""         type=""text"" size=""64"" value=""" & $sTwitter_oAuth_Token & """/><br/>" & @CRLF
    $_Twitter_token_secret_html = "   token secret:  <input name=""tokenSecret""            type=""text"" size=""64"" value=""" & $sTwitter_TokenSecret & """/>" & @CRLF
    $_Twitter_oauth_timestamp_html = "                      <input name=""oauth_timestamp""     type=""hidden""/>" & @CRLF
    $_Twitter_oauth_nonce_html = "                      <input name=""oauth_nonce""         type=""hidden""/>" & @CRLF
    $_Twitter_oauth_signature_html = "                      <input name=""oauth_signature""     type=""hidden""/>" & @CRLF
    $_Twitter_consumer_secret_html = "    consumer secret:  <input name=""consumerSecret""       type=""text"" size=""64"" value=""" & $sTwitter_ConsumerSecret & """/><br/>" & @CRLF
    $html = $_Twitter_html1 & $_Twitter_message_html & $_Twitter_oauth_consumer_key_html & $_Twitter_oauth_token_html & $_Twitter_oauth_signature_method_html & $_Twitter_oauth_timestamp_html & $_Twitter_oauth_nonce_html & $_Twitter_oauth_signature_html & $_Twitter_html2 & $_Twitter_url_html & $_Twitter_consumer_secret_html & $_Twitter_token_secret_html & $_Twitter_html3
    _IELoadWait($twitter)
    _IEDocWriteHTML($twitter, $html)
    ; Submit the form
    $form = _IEFormGetObjByName($twitter, "request")
    $submit = _IEFormElementGetObjByName($form, "submit")
    _IEAction($submit, "click")
EndFunc   ;==>_GUICtrlTwitter_UpdateStatus

Func _Twitter_Initialize()
$sTwitter_oAuth_Consumer_key = IniRead('Twitter.ini', 'TwitterAPI', 'oAuth_Consumer_key', '')
$sTwitter_oAuth_Token = IniRead('Twitter.ini', 'TwitterAPI', 'oAuth_Token', '')
$sTwitter_ConsumerSecret = IniRead('Twitter.ini', 'TwitterAPI', 'ConsumerSecret', '')
$sTwitter_tokenSecret = IniRead('Twitter.ini', 'TwitterAPI', 'TokenSecret', '')
If $sTwitter_oAuth_Consumer_key == '' Then
$sTwitter_oAuth_Consumer_key = InputBox("oAuth_Consumer_Key", "Please provide oAuth_Consumer_Key", "", " M", "250", "125")
Select
Case @error = 0 ;OK - The string returned is valid
IniWrite('Twitter.ini', 'TwitterAPI', 'oAuth_Consumer_key', $sTwitter_oAuth_Consumer_key)
Case @error = 1 ;The Cancel button was pushed
Exit
Case @error = 3 ;The InputBox failed to open
Exit
EndSelect
EndIf
If $sTwitter_oAuth_Token == '' Then
$sTwitter_oAuth_Token= InputBox("oAuth_Token", "Please provide oAuth_Token", "", " M", "250", "125")
Select
Case @error = 0 ;OK - The string returned is valid
IniWrite('Twitter.ini', 'TwitterAPI', 'oAuth_Token', $sTwitter_oAuth_Token)
Case @error = 1 ;The Cancel button was pushed
Exit
Case @error = 3 ;The InputBox failed to open
Exit
EndSelect
EndIf
If $sTwitter_ConsumerSecret == '' Then
$sTwitter_ConsumerSecret = InputBox("ConsumerSecret", "Please provide ConsumerSecret", "", " M", "250", "125")
Select
Case @error = 0 ;OK - The string returned is valid
IniWrite('Twitter.ini', 'TwitterAPI', 'ConsumerSecret', $sTwitter_ConsumerSecret)
Case @error = 1 ;The Cancel button was pushed
Exit
Case @error = 3 ;The InputBox failed to open
Exit
EndSelect
EndIf
If $sTwitter_TokenSecret == '' Then
$sTwitter_TokenSecret = InputBox("TokenSecret", "Please provide TokenSecret", "", " M", "250", "125")
Select
Case @error = 0 ;OK - The string returned is valid
IniWrite('Twitter.ini', 'TwitterAPI', 'TokenSecret', $sTwitter_TokenSecret)
Case @error = 1 ;The Cancel button was pushed
Exit
Case @error = 3 ;The InputBox failed to open
Exit
EndSelect
EndIf
EndFunc ;==>_Twitter_Initialize

Func _GUICtrlTwitter_Search($Search_text, $result_type = "mixed")
Local $search_result, $ini, $BASE64
Local $aTwitter_status_id, $aTwitter_post_title, $aTwitter_post_time
Local $i, $j, $aSearch_text
$Search_text = StringStripWS($Search_text, 7)
$Search_text = StringReplace($Search_text, " ", "+")
$oHTTP = ObjCreate("winhttp.winhttprequest.5.1")
$oHTTP.Open("GET", "http://search.twitter.com/search.atom?q=" & $Search_text & "&result_type=" & $result_type)
$oHTTP.Send()
$HTMLSource = $oHTTP.Responsetext
$entry = StringSplit($HTMLSource, "<entry>", 1)
_ArrayDelete($entry, 1)
_ArrayDelete($entry, 0)
If UBound($entry) > 0 Then
For $i = 0 To UBound($entry) - 1 Step 1
$aTwitter_post_title = StringRegExp($entry[$i], $sTwitter_post_title, 3)
If IsArray($aTwitter_post_title) Then
If StringInStr($aTwitter_post_title[0], '@', 2) == 0 Or StringInStr($aTwitter_post_title[0], 'RT', 2) == 0 Then
$aTwitter_status_id = StringRegExp($entry[$i], $sTwitter_status_id, 3)
$aTwitter_post_time = StringRegExp($entry[$i], $sTwitter_post_time, 3)
If StringInStr($Search_text, '+') Then
$aSearch_text = StringSplit($Search_text, '+')
For $k = 0 To UBound($Search_text) - 1 Step 1
$aTwitter_post_title[0] = StringReplace($aTwitter_post_title[0], $Search_text[$k], '')
Next
Else
$aTwitter_post_title[0] = StringReplace($aTwitter_post_title[0], $Search_text, '')
EndIf
$aTwitter_post_title[0] = StringStripWS($aTwitter_post_title[0], 7)
If StringInStr($aTwitter_post_title[0], ' ') Then
$aTwitter_post_title = StringSplit($aTwitter_post_title[0], ' ', 3)
EndIf
For $j = 0 To UBound($aTwitter_post_title) - 1 Step 1
$aTwitter_post_title[$j] = StringStripWS($aTwitter_post_title[$j], 8)
If StringLeft($aTwitter_post_title[$j], 1) <> '#' And (StringLower(StringLeft($aTwitter_post_title[$j], 7)) == 'http://' Or StringLower(StringLeft($aTwitter_post_title[$j], 7)) == 'https://' Or StringLower(StringLeft($aTwitter_post_title[$j], 4)) == 'h00p' Or StringLower(StringLeft($aTwitter_post_title[$j], 4)) == 'hxxp') Then
$BASE64 = StringReplace(_Base64Encode($aTwitter_post_title[$j]), '=', '')
$ini = IniRead('process_tweet.ini', 'Tweets', $BASE64, 'default')
If $ini == 'default' Then
IniWrite('process_tweet.ini', 'Tweets', $BASE64, $aTwitter_post_time[0] & '|' & $aTwitter_status_id[0] & '|' & $aTwitter_post_title[$j])
FileWrite('process_tweet.txt', $aTwitter_post_time[0] & '|' & $aTwitter_status_id[0] & '|' & $aTwitter_post_title[$j] & @CRLF)
EndIf
EndIf
Next
EndIf
EndIf
Next
EndIf
Return
EndFunc ;==>_GUICtrlTwitter_Search

[uPDATE]

Please do not use the Search Function provided as the method has been depreciated . will update accordingly.

Thanks to NickNick for pointing this out.

Edited by DeltaRocked

Share this post


Link to post
Share on other sites

Added - Send DM

Func _GuiCtrlTwitter_SendDM(ByRef $twitter, $message, $twitter_ctrl, $twitter_to)
GUICtrlSetState($twitter_ctrl, $GUI_HIDE)
_IENavigate($twitter, "about:blank")
$_Twitter_message_html = " message: 
" & @CRLF
$_Twitter_message_html &= " to: 
" & @CRLF
$_Twitter_url_html = " URL: 
" & @CRLF
$_Twitter_oauth_consumer_key_html = " consumer key: 
" & @CRLF
$_Twitter_oauth_signature_method_html = " signature method: " & @CRLF
$_Twitter_oauth_token_html = " request token: 
" & @CRLF
$_Twitter_token_secret_html = " token secret: " & @CRLF
$_Twitter_oauth_timestamp_html = " " & @CRLF
$_Twitter_oauth_nonce_html = " " & @CRLF
$_Twitter_oauth_signature_html = " " & @CRLF
$_Twitter_consumer_secret_html = " consumer secret: 
" & @CRLF
$html = $_Twitter_html1 & $_Twitter_message_html & $_Twitter_oauth_consumer_key_html & $_Twitter_oauth_token_html & $_Twitter_oauth_signature_method_html & $_Twitter_oauth_timestamp_html & $_Twitter_oauth_nonce_html & $_Twitter_oauth_signature_html & $_Twitter_html2 & $_Twitter_url_html & $_Twitter_consumer_secret_html & $_Twitter_token_secret_html & $_Twitter_html3
_IELoadWait($twitter)
_IEDocWriteHTML($twitter, $html)
_IELoadWait($twitter)
$form = _IEFormGetObjByName($twitter, "request")
$submit = _IEFormElementGetObjByName($form, "submit")
_IEAction($submit, "click")
If @error == 0 Then
_IELoadWait($twitter)
Return SetError(@error)
Else
Return SetError(@error)
EndIf
EndFunc ;==>_GuiCtrlTwitter_SendDM

Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

Contains:

HMAC-SHA1 - SkinnyWhiteGuy

_Epoch_encrypt - trancexx

URLEncode - Kafu

_Base64Encode - unable to find it as of this moment. Ward

Direct Messages Sent by the authenticating user

#include "WinHttp.au3"
#include <Crypt.au3>
#include <encodebase64.au3>
#include <Date.au3>
$sTwitter_oAuth_Consumer_key = ''
$sTwitter_ConsumerSecret = ''
$sTwitter_oAuth_Token = ''
$sTwitter_TokenSecret = ''
$header = gen_sig_base()
$header = StringSplit($header, '|', 2)
Local $arr = _WinHttpGetIEProxyConfigForCurrentUser()
If $arr[2] <> '' Then
$hOpen = _WinHttpOpen('Mozilla/5.0', $WINHTTP_ACCESS_TYPE_NAMED_PROXY, $arr[2])
Else
$hOpen = _WinHttpOpen('Mozilla/5.0')
EndIf
$hConnect = _WinHttpConnect($hOpen, "api.twitter.com", $INTERNET_DEFAULT_HTTPS_PORT)
$header[2] = URLEncode(_Base64Encode(BinaryToString($header[2])))
ConsoleWrite('epoch  ' & $header[0] & @CRLF)
ConsoleWrite('nonce  ' & $header[1] & @CRLF)
ConsoleWrite('signature ' & $header[2] & @CRLF)
$hRequestSSL = _WinHttpSimpleSendSSLRequest($hConnect, 'GET', "1.1/direct_messages/sent.json?count=10", Default, Default, 'Authorization: OAuth ' _
& 'oauth_consumer_key="' & $sTwitter_oAuth_Consumer_key & '", ' & 'oauth_nonce="' & $header[1] & '", ' _
& 'oauth_signature="' & $header[2] & '", ' & 'oauth_signature_method="HMAC-SHA1", ' _
& 'oauth_timestamp="' & $header[0] & '", ' & 'oauth_token="' & $sTwitter_oAuth_Token & '", ' _
& 'oauth_version="1.0"')
$sReturned = _WinHttpSimpleReadData($hRequestSSL)
ConsoleWrite($sReturned & @CRLF)
_WinHttpCloseHandle($hRequestSSL)
_WinHttpCloseHandle($hConnect)
_WinHttpCloseHandle($hOpen)
Func gen_sig_base()
Local $epoch, $nonce, $SignatureBase, $since_id, $Signature
$tCur = _Date_Time_GetSystemTime()
$date = _Date_Time_SystemTimeToDateTimeStr($tCur, 1)
$epoch = _Epoch_encrypt($date)
_Crypt_Startup()
$nonce = StringTrimLeft(_Crypt_HashData($epoch & $sTwitter_oAuth_Consumer_key, $CALG_MD5),2)
_Crypt_Shutdown()
$since_id = IniRead('Twitter.ini', 'TwitterAPI', 'since_id_dm', '')
$SignatureBase = 'GET&https%3A%2F%2Fapi.twitter.com%2F1.1%2Fdirect_messages%2Fsent.json&count%3D10%26oauth_consumer_key%3D' & $sTwitter_oAuth_Consumer_key & '%26oauth_nonce%3D' & $nonce & '%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D' & $epoch & '%26oauth_token%3D' & $sTwitter_oAuth_Token & '%26oauth_version%3D1.0'
$Signature = hmac($sTwitter_ConsumerSecret & '&' & $sTwitter_TokenSecret, $SignatureBase, 'sha1')
Return $epoch & '|' & $nonce & '|' & $Signature
EndFunc ;==>gen_sig_base
;~ By Trancexx
Func _Epoch_encrypt($date)
Local $main_split = StringSplit($date, " ")
If $main_split[0] - 2 Then
Return SetError(1, 0, "") ; invalid time format
EndIf
Local $asDatePart = StringSplit($main_split[1], "/")
Local $asTimePart = StringSplit($main_split[2], ":")
If $asDatePart[0] - 3 Or $asTimePart[0] - 3 Then
Return SetError(1, 0, "") ; invalid time format
EndIf
If $asDatePart[2] < 3 Then
$asDatePart[2] += 12
$asDatePart[1] -= 1
EndIf
Local $i_aFactor = Int($asDatePart[1] / 100)
Local $i_bFactor = Int($i_aFactor / 4)
Local $i_cFactor = 2 - $i_aFactor + $i_bFactor
Local $i_eFactor = Int(1461 * ($asDatePart[1] + 4716) / 4)
Local $i_fFactor = Int(153 * ($asDatePart[2] + 1) / 5)
Local $aDaysDiff = $i_cFactor + $asDatePart[3] + $i_eFactor + $i_fFactor - 2442112
Local $iTimeDiff = $asTimePart[1] * 3600 + $asTimePart[2] * 60 + $asTimePart[3]
Return SetError(0, 0, $aDaysDiff * 86400 + $iTimeDiff)
EndFunc ;==>_Epoch_encrypt
; from somewhere
Func URLEncode($urlText)
$url = ""
For $i = 1 To StringLen($urlText)
$acode = Asc(StringMid($urlText, $i, 1))
Select
Case ($acode >= 48 And $acode <= 57) Or _
     ($acode >= 65 And $acode <= 90) Or _
     ($acode >= 97 And $acode <= 122)
$url = $url & StringMid($urlText, $i, 1)
Case $acode = 32
$url = $url & "+"
Case Else
$url = $url & "%" & Hex($acode, 2)
EndSelect
Next
Return $url
EndFunc ;==>URLEncode
Func sha1($message)
Return _Crypt_HashData($message, $CALG_SHA1)
EndFunc
Func md5($message)
Return _Crypt_HashData($message, $CALG_MD5)
EndFunc
Func hmac($key, $message, $hash="md5")
Local $blocksize = 64
Local $a_opad[$blocksize], $a_ipad[$blocksize]
Local Const $oconst = 0x5C, $iconst = 0x36
Local $opad = Binary(''), $ipad = Binary('')
$key = Binary($key)
If BinaryLen($key) > $blocksize Then $key = Call($hash, $key)
For $i = 1 To BinaryLen($key)
     $a_ipad[$i-1] = Number(BinaryMid($key, $i, 1))
     $a_opad[$i-1] = Number(BinaryMid($key, $i, 1))
Next
For $i = 0 To $blocksize - 1
     $a_opad[$i] = BitXOR($a_opad[$i], $oconst)
     $a_ipad[$i] = BitXOR($a_ipad[$i], $iconst)
Next
For $i = 0 To $blocksize - 1
     $ipad &= Binary('0x' & Hex($a_ipad[$i],2))
     $opad &= Binary('0x' & Hex($a_opad[$i],2))
Next
Return Call($hash, $opad & Call($hash, $ipad & Binary($message)))
EndFunc

Direct Messages sent to the authenticating User

#include "WinHttp.au3"
#include <Crypt.au3>
#include <encodebase64.au3>
#include <Date.au3>
$sTwitter_oAuth_Consumer_key = ''
$sTwitter_ConsumerSecret = ''
$sTwitter_oAuth_Token = ''
$sTwitter_TokenSecret = ''
$header = gen_sig_base()
$header = StringSplit($header, '|', 2)
Local $arr = _WinHttpGetIEProxyConfigForCurrentUser()
If $arr[2] <> '' Then
$hOpen = _WinHttpOpen('Mozilla/5.0', $WINHTTP_ACCESS_TYPE_NAMED_PROXY, $arr[2])
Else
$hOpen = _WinHttpOpen('Mozilla/5.0')
EndIf
$hConnect = _WinHttpConnect($hOpen, "api.twitter.com", $INTERNET_DEFAULT_HTTPS_PORT)
$header[2] = URLEncode(_Base64Encode(BinaryToString($header[2])))
ConsoleWrite('epoch  ' & $header[0] & @CRLF)
ConsoleWrite('nonce  ' & $header[1] & @CRLF)
ConsoleWrite('signature ' & $header[2] & @CRLF)
$hRequestSSL = _WinHttpSimpleSendSSLRequest($hConnect, 'GET', "1.1/direct_messages.json?count=10", Default, Default, 'Authorization: OAuth ' _
& 'oauth_consumer_key="' & $sTwitter_oAuth_Consumer_key & '", ' & 'oauth_nonce="' & $header[1] & '", ' _
& 'oauth_signature="' & $header[2] & '", ' & 'oauth_signature_method="HMAC-SHA1", ' _
& 'oauth_timestamp="' & $header[0] & '", ' & 'oauth_token="' & $sTwitter_oAuth_Token & '", ' _
& 'oauth_version="1.0"')
$sReturned = _WinHttpSimpleReadData($hRequestSSL)
ConsoleWrite($sReturned & @CRLF)
_WinHttpCloseHandle($hRequestSSL)
_WinHttpCloseHandle($hConnect)
_WinHttpCloseHandle($hOpen)
Func gen_sig_base()
Local $epoch, $nonce, $SignatureBase, $since_id, $Signature
$tCur = _Date_Time_GetSystemTime()
$date = _Date_Time_SystemTimeToDateTimeStr($tCur, 1)
$epoch = _Epoch_encrypt($date)
_Crypt_Startup()
$nonce = StringTrimLeft(_Crypt_HashData($epoch & $sTwitter_oAuth_Consumer_key, $CALG_MD5),2)
_Crypt_Shutdown()
$since_id = IniRead('Twitter.ini', 'TwitterAPI', 'since_id_dm', '')
$SignatureBase = 'GET&https%3A%2F%2Fapi.twitter.com%2F1.1%2Fdirect_messages.json&count%3D10%26oauth_consumer_key%3D' & $sTwitter_oAuth_Consumer_key & '%26oauth_nonce%3D' & $nonce & '%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D' & $epoch & '%26oauth_token%3D' & $sTwitter_oAuth_Token & '%26oauth_version%3D1.0'
$Signature = hmac($sTwitter_ConsumerSecret & '&' & $sTwitter_TokenSecret, $SignatureBase, 'sha1')
Return $epoch & '|' & $nonce & '|' & $Signature
EndFunc ;==>gen_sig_base
;~ By Trancexx
Func _Epoch_encrypt($date)
Local $main_split = StringSplit($date, " ")
If $main_split[0] - 2 Then
Return SetError(1, 0, "") ; invalid time format
EndIf
Local $asDatePart = StringSplit($main_split[1], "/")
Local $asTimePart = StringSplit($main_split[2], ":")
If $asDatePart[0] - 3 Or $asTimePart[0] - 3 Then
Return SetError(1, 0, "") ; invalid time format
EndIf
If $asDatePart[2] < 3 Then
$asDatePart[2] += 12
$asDatePart[1] -= 1
EndIf
Local $i_aFactor = Int($asDatePart[1] / 100)
Local $i_bFactor = Int($i_aFactor / 4)
Local $i_cFactor = 2 - $i_aFactor + $i_bFactor
Local $i_eFactor = Int(1461 * ($asDatePart[1] + 4716) / 4)
Local $i_fFactor = Int(153 * ($asDatePart[2] + 1) / 5)
Local $aDaysDiff = $i_cFactor + $asDatePart[3] + $i_eFactor + $i_fFactor - 2442112
Local $iTimeDiff = $asTimePart[1] * 3600 + $asTimePart[2] * 60 + $asTimePart[3]
Return SetError(0, 0, $aDaysDiff * 86400 + $iTimeDiff)
EndFunc ;==>_Epoch_encrypt
; from somewhere
Func URLEncode($urlText)
$url = ""
For $i = 1 To StringLen($urlText)
$acode = Asc(StringMid($urlText, $i, 1))
Select
Case ($acode >= 48 And $acode <= 57) Or _
     ($acode >= 65 And $acode <= 90) Or _
     ($acode >= 97 And $acode <= 122)
$url = $url & StringMid($urlText, $i, 1)
Case $acode = 32
$url = $url & "+"
Case Else
$url = $url & "%" & Hex($acode, 2)
EndSelect
Next
Return $url
EndFunc ;==>URLEncode
Func sha1($message)
Return _Crypt_HashData($message, $CALG_SHA1)
EndFunc
Func md5($message)
Return _Crypt_HashData($message, $CALG_MD5)
EndFunc
Func hmac($key, $message, $hash="md5")
Local $blocksize = 64
Local $a_opad[$blocksize], $a_ipad[$blocksize]
Local Const $oconst = 0x5C, $iconst = 0x36
Local $opad = Binary(''), $ipad = Binary('')
$key = Binary($key)
If BinaryLen($key) > $blocksize Then $key = Call($hash, $key)
For $i = 1 To BinaryLen($key)
     $a_ipad[$i-1] = Number(BinaryMid($key, $i, 1))
     $a_opad[$i-1] = Number(BinaryMid($key, $i, 1))
Next
For $i = 0 To $blocksize - 1
     $a_opad[$i] = BitXOR($a_opad[$i], $oconst)
     $a_ipad[$i] = BitXOR($a_ipad[$i], $iconst)
Next
For $i = 0 To $blocksize - 1
     $ipad &= Binary('0x' & Hex($a_ipad[$i],2))
     $opad &= Binary('0x' & Hex($a_opad[$i],2))
Next
Return Call($hash, $opad & Call($hash, $ipad & Binary($message)))
EndFunc
Edited by DeltaRocked

Share this post


Link to post
Share on other sites

Ok, so hopefully it's not too much against the website rules to reply to this topic after so long. Sorry for doing so but I really need some help.

I have created a topic of my own about this but I was just wondering if anybody could adapt this UDF to work with the new Twitter API v1.1 which now only supports JSON and not XML as the UDF currently uses. I have got the function working again by changing the URL the form is POSTed to, but now a File Download dialog appears wanting to download the JSON response which we obviously don't want to happen.

Fortunately, the authentication function still works, however I have adapted this so that once a user has logged in once the OAuth tokens are stored in a file and used whenever the program is run again.

Share this post


Link to post
Share on other sites

#15 ·  Posted (edited)

Hi MeiSandy,

Will verify the modified UDF and revert back.

rgds

Deltarocked.

[uPDATE]

Replied to this query in post id

Edited by DeltaRocked

Share this post


Link to post
Share on other sites

#16 ·  Posted (edited)

I got the same problem as "Chrshea" when I loged in and allowed the app I get a pin code,

I dont know what to do, When i click next it it get a new window with: "computing software-devlopment"

has somebody alread found the solution for this?

Edited by Arclite86

Share this post


Link to post
Share on other sites

Hello Fellow AutoIt Fans,

Does anyone have an example of some code, that they are willing and able to share herein, that actually allows you to successfully get an oAuth authentication and successfully perform a Search of Tweets using the Twitter API V1.1?

I have tried using the code that DeltaRocked referenced in the Post at:

However, I have discovered that the value of $nonce being returned by the statement = $nonce = StringTrimLeft(_Crypt_HashData($epoch & $sTwitter_oAuth_Consumer_key, $CALG_MD5), 2) in the gen_sig_base Function is different from the oauth_nonce returned by Twitter’s OAuth Tool at: https://dev.twitter.com/oauth/tools/signature-generator

And even if I set $nonce equal to the oauth_nonce returned by Twitter’s OAuth Tool and $epoch equal to the oauth_timestamp returned by Twitter’s OAuth Tool, the $Signature  returned by the statement = $Signature = hmac( $sTwitter_oAuth_Consumer_key & ':' & $sTwitter_ConsumerSecret, $SignatureBase, 'sha1') in the gen_sig_base Function is different from the oauth_signature returned by Twitter’s OAuth Tool … Does anyone know why?

And I subsequently always get a response $sReturned ={"errors":[{"message":"Could not authenticate you","code":32}]}, @error =0 from the request using the values of $nonce and $Signature returned by the gen_sig_base Function.

However, I was previously able to successfully get the Tweet Search results returned if I “hardcoded” the oauth_nonce and oauth_signature values returned by Twitter’s OAuth Tool into the request so …

Does anyone know what is wrong in/with the gen_sig_base Function? And/or changed in the Twitter API V1.1? causing these authentication failures? And/or the values of $nonce  and $Signature returned by the gen_sig_base Function being different from the oauth_nonce and oauth_signature values returned by Twitter’s OAuth Tool, for the same $epoch value?

Any and all of your responses and assistance with being able to successfully automate Twitter Searches using AutoIt would be Most Appreciated!

Thank you and Have a Great Day!

- Michael S. DeVries

Share this post


Link to post
Share on other sites

Hello again Fellow AutoIt Fans,

I have again been (very frustratingly) trying to perform an automated Twitter Search via AutoIt, and …

I believe that I have narrowed down the authentication issues, mentioned above, to something wrong in/with the hmac function in the aforementioned gen_sig_base function, as the Signature that the gen_sig_base function returns differs from that returned by the OAuth Tool using the same values for $epoch and $nonce.

I have also tried converting the VBA code from https://greglib.org/tweeting-with-vba/ to AutoIt code, but the following statements are not returning the required Objects:

$oAsc = ObjGet("","System.Text.UTF8Encoding")
$oEnc = ObjGet("","System.Security.Cryptography.HMACSHA1")

 … so the Base64_HMACSHA1 function from there fails ;(
Does anyone know how to fix those ObjGet statements above to successfully return the required Objects?, or better yet …

Does anyone have any working AutoIt code that they are willing and able to share to successfully complete the oAuth Authentication with the Twitter API?

Any and all of your responses and assistance with being able to successfully automate Twitter Searches using AutoIt would be Most Appreciated!

Thank you for all of your help and participation and Have a Great Day!

- Michael S. DeVries

Share this post


Link to post
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