ツイッターAPIを使ってエクセルVBAからツイートをする方法を紹介します。
※自動化などをするときはツイッターAPIの規約に従って運用を行ってください。
規約を違反した場合はアカウントロックや凍結されることがあると認識して利用してください。
ここで紹介する方法は外部のソフトやライブラリを使わず、VBA内で処理を完結します。
環境条件
条件として
- microsoftエクセル(バージョン未検証)
- ネットにつながった環境
- ツイッターAPIの認証情報
が必要です。
エクセルはもちろんで、ツイート自体はHTTP通信を使って行われますのでネットにつながった環境も必要です。
「ツイッターAPIの認証情報」はAPI認証情報の取得方法をご覧頂き取得をしてください。
またエクセルのVBE画面で「ツール」⇒「参照設定」からライブラリの読み込みをします。
- Microsoft WinHTTP Service version 5.1
- Microsoft XML, v6.0
上記を参照設定でチェックしておきましょう。
シート
簡単にユーザー名と認証情報、ツイートの内容を記載したシートを用意します。
C列に情報を記載しています。
簡単にボタンを設置しています。
ソース
以下はソースです。
標準モジュール
twitter_apiとして
#If VBA7 Then Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal ms As LongPtr) Public Declare PtrSafe Sub GetSystemTime Lib "kernel32" (lpSystemTime As SYSTEMTIME) Public Declare PtrSafe Function SystemTimeToFileTime Lib "kernel32" (lpSystemTime As SYSTEMTIME, lpFileTime As FILETIME) As LongPtr Public Declare PtrSafe Function LocalFileTimeToFileTime Lib "kernel32" (lpLocalFileTime As FILETIME, lpFileTime As FILETIME) As LongPtr Public Declare PtrSafe Function FileTimeToSystemTime Lib "kernel32" (lpFileTime As FILETIME, lpSystemTime As SYSTEMTIME) As LongPtr #Else Public Declare Sub Sleep Lib "kernel32" (ByVal ms As Long) Public Declare Sub GetSystemTime Lib "kernel32" (lpSystemTime As SYSTEMTIME) Public Declare Function SystemTimeToFileTime Lib "kernel32" (lpSystemTime As SYSTEMTIME, lpFileTime As FILETIME) As Long Public Declare Function LocalFileTimeToFileTime Lib "kernel32" (lpLocalFileTime As FILETIME, lpFileTime As FILETIME) As Long Public Declare Function FileTimeToSystemTime Lib "kernel32" (lpFileTime As FILETIME, lpSystemTime As SYSTEMTIME) As Long #End If Public Type FILETIME dwLowDateTime As Long dwHighDateTime As Long End Type Public Type SYSTEMTIME wYear As Integer wMonth As Integer wDayOfWeek As Integer wDay As Integer wHour As Integer wMinute As Integer wSecond As Integer wMilliseconds As Integer End Type Const adTypeBinary = 1 Const adTypeText = 2 Const HT_APIMethodP As String = "POST" Const HT_URLPost As String = "https://api.twitter.com/1.1/statuses/update.json" Const HT_URLStatus As String = "https://api.twitter.com/oauth2/token" Const HT_Method As String = "HMAC-SHA1" Const HT_OauthVersion As String = "1.0" Function HT_Username() As Variant HT_Username = "@" & ThisWorkbook.Worksheets("sheet1").Range("C2").Value End Function Function HT_OauthConsumerKey() As Variant HT_OauthConsumerKey = ThisWorkbook.Worksheets("sheet1").Range("C3").Value End Function Function HT_OauthConsumerSecret() As Variant HT_OauthConsumerSecret = ThisWorkbook.Worksheets("sheet1").Range("C4").Value End Function Function HT_OauthToken() As Variant HT_OauthToken = ThisWorkbook.Worksheets("sheet1").Range("C5").Value End Function Function HT_OauthTokenSecret() As Variant HT_OauthTokenSecret = ThisWorkbook.Worksheets("sheet1").Range("C6").Value End Function Public Function LocalTimeToUTC(dteTime As Date) As Date Dim dteLocalFileTime As FILETIME Dim dteFileTime As FILETIME Dim dteLocalSystemTime As SYSTEMTIME Dim dteSystemTime As SYSTEMTIME dteLocalSystemTime.wYear = CInt(Year(dteTime)) dteLocalSystemTime.wMonth = CInt(Month(dteTime)) dteLocalSystemTime.wDay = CInt(Day(dteTime)) dteLocalSystemTime.wHour = CInt(Hour(dteTime)) dteLocalSystemTime.wMinute = CInt(Minute(dteTime)) dteLocalSystemTime.wSecond = CInt(Second(dteTime)) Call SystemTimeToFileTime(dteLocalSystemTime, dteLocalFileTime) Call LocalFileTimeToFileTime(dteLocalFileTime, dteFileTime) Call FileTimeToSystemTime(dteFileTime, dteSystemTime) LocalTimeToUTC = CDate(dteSystemTime.wMonth & "/" & _ dteSystemTime.wDay & "/" & _ dteSystemTime.wYear & " " & _ dteSystemTime.wHour & ":" & _ dteSystemTime.wMinute & ":" & _ dteSystemTime.wSecond) End Function Public Function get_timestamp() As Variant get_timestamp = DateDiff("s", #1/1/1970#, LocalTimeToUTC(Now)) End Function Public Function EncodeBase64(ByRef arrData() As Byte) As Variant Dim objXML As MSXML2.DOMDocument60 Dim objNode As MSXML2.IXMLDOMElement Set objXML = New MSXML2.DOMDocument60 Set objNode = objXML.createElement("b64") objNode.DataType = "bin.base64" objNode.nodeTypedValue = arrData EncodeBase64 = objNode.Text Set objNode = Nothing Set objXML = Nothing End Function Public Function Base64_HMACSHA1(ByVal sTextToHash As Variant, ByVal sSharedSecretKey As Variant) As Variant Dim asc As Object Dim enc As Object Dim TextToHash() As Byte Dim SharedSecretKey() As Byte Set asc = CreateObject("System.Text.UTF8Encoding") Set enc = CreateObject("System.Security.Cryptography.HMACSHA1") TextToHash = asc.Getbytes_4(sTextToHash) SharedSecretKey = asc.Getbytes_4(sSharedSecretKey) enc.Key = SharedSecretKey Dim bytes() As Byte bytes = enc.ComputeHash_2((TextToHash)) Base64_HMACSHA1 = EncodeBase64(bytes) Set asc = Nothing Set enc = Nothing End Function Public Function get_GUID() As Variant get_GUID = RandomHex(3) + "-" + _ RandomHex(2) + "-" + _ RandomHex(2) + "-" + _ RandomHex(2) + "-" + _ RandomHex(6) End Function Private Function RandomHex(lngCharLength As Long) Dim i As Long Randomize For i = 1 To lngCharLength RandomHex = RandomHex & Right$("0" & Hex(Rnd() * 256), 2) Next End Function Private Function strToByteArray(sText As Variant) As Byte() strToByteArray = StrConv(sText, vbFromUnicode) End Function Public Function UrlEncode(str As Variant) Dim d As Object Dim elm As Object Set d = CreateObject("htmlfile") Set elm = d.createElement("span") str = Replace(str, vbCrLf, vbLf) str = Replace(str, vbLf, "n") elm.setAttribute "id", "result" d.body.appendChild elm Debug.Print str d.parentWindow.execScript "document.getElementById('result').innerText = encodeURIComponent('" & str & "');", "JScript" 'Debug.Print elm.innerText UrlEncode = elm.innerText End Function Public Function get_basestring(strNonce As Variant, strTimestamp As Variant, strStatus As Variant) As Variant Dim HT_tmpbase As Variant HT_tmpbase = "oauth_consumer_key=" & HT_OauthConsumerKey HT_tmpbase = HT_tmpbase & "&" & "oauth_nonce=" & strNonce HT_tmpbase = HT_tmpbase & "&" & "oauth_signature_method=" & HT_Method HT_tmpbase = HT_tmpbase & "&" & "oauth_timestamp=" & strTimestamp HT_tmpbase = HT_tmpbase & "&" & "oauth_token=" & HT_OauthToken HT_tmpbase = HT_tmpbase & "&" & "oauth_version=" & HT_OauthVersion HT_tmpbase = HT_tmpbase & "&" & "status=" & strStatus get_basestring = HT_APIMethodP & "&" & UrlEncode((HT_URLPost)) & "&" & UrlEncode(HT_tmpbase) End Function Public Function get_header(strNonce As Variant, strTimestamp As Variant, strSignature As Variant) As Variant Dim HT_tmpHeader As Variant HT_tmpHeader = "OAuth oauth_consumer_key=" & Chr(34) & HT_OauthConsumerKey & Chr(34) HT_tmpHeader = HT_tmpHeader & ", oauth_nonce=" & Chr(34) & strNonce & Chr(34) HT_tmpHeader = HT_tmpHeader & ", oauth_signature=" & Chr(34) & strSignature & Chr(34) HT_tmpHeader = HT_tmpHeader & ", oauth_signature_method=" & Chr(34) & HT_Method & Chr(34) HT_tmpHeader = HT_tmpHeader & ", oauth_timestamp=" & Chr(34) & strTimestamp & Chr(34) HT_tmpHeader = HT_tmpHeader & ", oauth_token=" & Chr(34) & HT_OauthToken & Chr(34) HT_tmpHeader = HT_tmpHeader & ", oauth_version=" & Chr(34) & HT_OauthVersion & Chr(34) HT_tmpHeader = HT_tmpHeader & ", trim_user=false" get_header = HT_tmpHeader End Function Public Function send_tweet(strStatus As Variant) As Boolean 'ツイート内容をURLエンコードする strStatus = UrlEncode(strStatus) 'nonceを作成 strNonce = get_GUID() 'タイムスタンプを作成 strTimestamp = get_timestamp() '認証ヘッダーの元を作成 strBase = get_basestring(strNonce, strTimestamp, strStatus) 'composite keyを作成 strKey = HT_OauthConsumerSecret & "&" & HT_OauthTokenSecret '認証ヘッダーの元を加工 strOauthSig = UrlEncode(Base64_HMACSHA1(strBase, strKey)) '認証header作成 strHeader = get_header(strNonce, strTimestamp, strOauthSig) 'HTTPでコネクション作成 Dim objRest As WinHttp.WinHttpRequest Set objRest = New WinHttp.WinHttpRequest objRest.Open HT_APIMethodP, HT_URLPost, False objRest.setRequestHeader "Content-Type", "application/x-www-form-urlencoded" objRest.setRequestHeader "Authorization", strHeader objRest.send "status=" & strStatus objRest.waitForResponse ' Debug.Print objRest.Status & " -- " & objRest.statusText ' Debug.Print objRest.responseText If objRest.Status = "200" Then send_tweet = True Else send_tweet = False End If Set objRest = Nothing End Function
本体は「send_tweet」です。
その他は細かいエンコードや暗号化、変換構築機能です。
処理の流れ的には、
API認証情報でHTTPレスポンスヘッダーを作成して、objRest.sendでツイートを送信します。
ヘッダーを作成するときに暗号化やエンコードをいくつか行いますがここが肝です。
ここで正確なヘッダーを作成しないとエラーになってしまいます。カスタムする時は気をつけましょう。
また、認証情報が誤っていてエラーになるケースも多いので注意しましょう。
コマンドボタン
下記はコマンドボタンのソースです。
Private Sub CommandButton1_Click() strStatus = ThisWorkbook.Worksheets("sheet1").Range("C8").Value strStatus = Replace(strStatus, "(", "(") strStatus = Replace(strStatus, ")", ")") strStatus = Replace(strStatus, "*", "*") strStatus = Replace(strStatus, "!", "!") Call send_tweet(strStatus) End Sub
ツイート内容を少々加工しています。
ツイート内容はエンコードして送信しますが、一部半角文字でエラーが出るので全角に変換して送信します。
文字数のチェックは入れていませんが文字数がオーバーしているとエラーになるので注意です。エクセルに入力する時点で判定するなどの方がよろしいかもしれません。
これを利用して自動化やツイート内容の自動生成等が可能になります。
また、画像付きのツイートをしたりすることもできるのですが、少々方法が変わります。
画像付き自動ツイートをご要望の方は当方で販売を行っていますのでご覧いただけると幸いです。
エクセルからツイッターAPIで自動投稿するファイルを販売しています
また、ここでは入っていませんが、フィルターしたツイートを取得する、ツイートを削除するなども実装することが可能です。
こちらはまた違う機会で紹介します。
コメント