SQLの窓

2014年03月08日


WSH : VBScript と JavaScript で Twitter に投稿する

▼ 最新版 
OneDrive へ移動

crypto-js が新しくなっていて、Twitter API で使う上において、SCRIPT 要素で読み込むだけで良いようになっています。

CryptoJS v3.1.2.zip は同梱しており、必要な js は、hmac-sha1.js と enc-base64-min.js だけなので、twitter_post_v2.wsf と同じ場所で実行できるようにしています。

実行は以下のような感じです。
cscript twitter_post_v2.wsf "CryptoJS v3.1.2 を使用して、コマンドプロンプトから投稿しています"





ソースコードは長くなるのでこちらから
▼ Twitter 部分は変わりませんが、crypto-js が古いです OneDrive へ移動 VBScript : Twitter API を呼び出して投稿する で書いた内容を一つ にまとめたソースコードにしました。 ※ ある程度関数化してあります。 必要なものは、以下の4つと投稿データです。 ( 88行目 )
oauth_consumer_key = "Consumer key"
oauth_consumer_secret = "Consumer secret"
oauth_token = "Access Token"
oauth_secret = "Access Token Secret"
上記データは、自分のアプリケーションを登録すると、全てその場で取得する事ができます。 ( Twitter Applications | dev.twitter.com ) ▼ 取得方法をまとめました Twitter アプリの登録方法と、API キーの利用 投稿データは、バッチファイルに書き込むようにしてテストしています。 使用例 : twitter.bat cscript twitter_post.wsf "新しくアプリを作ってバッチ投稿テスト"
<JOB>
<COMMENT>
************************************************************
■著作権その他

このプログラムはフリーです。どうぞ自由に御使用ください。
著作権は作者である私(lightbox)が保有しています。
また、本ソフトを運用した結果については、作者は一切責任を
負えせんのでご了承ください。
************************************************************
</COMMENT>

<OBJECT id="objHTTP" progid="Msxml2.ServerXMLHTTP" />
<OBJECT id="Stream1" progid="ADODB.Stream" />
<OBJECT id="Stream2" progid="ADODB.Stream" />
<OBJECT id="StreamBin" progid="ADODB.Stream" />

<SCRIPT language="JavaScript">
/*
 * Crypto-JS v2.0.0
 * http://code.google.com/p/crypto-js/
 * Copyright (c) 2009, Jeff Mott. All rights reserved.
 * http://code.google.com/p/crypto-js/wiki/License
 */
var Crypto;

(function(){var c="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";var d=Crypto={};var a=d.util={rotl:function(h,g){return(h<<g)|(h>>>(32-g))},rotr:function(h,g){return(h<<(32-g))|(h>>>g)},endian:function(h){if(h.constructor==Number){return a.rotl(h,8)&16711935|a.rotl(h,24)&4278255360}for(var g=0;g<h.length;g++){h[g]=a.endian(h[g])}return h},randomBytes:function(h){for(var g=[];h>0;h--){g.push(Math.floor(Math.random()*256))}return g},bytesToWords:function(h){for(var k=[],j=0,g=0;j<h.length;j++,g+=8){k[g>>>5]|=h[j]<<(24-g%32)}return k},wordsToBytes:function(i){for(var h=[],g=0;g<i.length*32;g+=8){h.push((i[g>>>5]>>>(24-g%32))&255)}return h},bytesToHex:function(g){for(var j=[],h=0;h<g.length;h++){j.push((g[h]>>>4).toString(16));j.push((g[h]&15).toString(16))}return j.join("")},hexToBytes:function(h){for(var g=[],i=0;i<h.length;i+=2){g.push(parseInt(h.substr(i,2),16))}return g},bytesToBase64:function(h){if(typeof btoa=="function"){return btoa(e.bytesToString(h))}for(var g=[],l=0;l<h.length;l+=3){var m=(h[l]<<16)|(h[l+1]<<8)|h[l+2];for(var k=0;k<4;k++){if(l*8+k*6<=h.length*8){g.push(c.charAt((m>>>6*(3-k))&63))}else{g.push("=")}}}return g.join("")},base64ToBytes:function(h){if(typeof atob=="function"){return e.stringToBytes(atob(h))}h=h.replace(/[^A-Z0-9+\/]/ig,"");for(var g=[],j=0,k=0;j<h.length;k=++j%4){if(k==0){continue}g.push(((c.indexOf(h.charAt(j-1))&(Math.pow(2,-2*k+8)-1))<<(k*2))|(c.indexOf(h.charAt(j))>>>(6-k*2)))}return g}};d.mode={};var b=d.charenc={};var f=b.UTF8={stringToBytes:function(g){return e.stringToBytes(unescape(encodeURIComponent(g)))},bytesToString:function(g){return decodeURIComponent(escape(e.bytesToString(g)))}};var e=b.Binary={stringToBytes:function(j){for(var g=[],h=0;h<j.length;h++){g.push(j.charCodeAt(h))}return g},bytesToString:function(g){for(var j=[],h=0;h<g.length;h++){j.push(String.fromCharCode(g[h]))}return j.join("")}}})();(function(){var f=Crypto,a=f.util,b=f.charenc,e=b.UTF8,d=b.Binary;var c=f.SHA1=function(i,g){var h=a.wordsToBytes(c._sha1(i));return g&&g.asBytes?h:g&&g.asString?d.bytesToString(h):a.bytesToHex(h)};c._sha1=function(o){if(o.constructor==String){o=e.stringToBytes(o)}var v=a.bytesToWords(o),x=o.length*8,p=[],r=1732584193,q=-271733879,k=-1732584194,h=271733878,g=-1009589776;v[x>>5]|=128<<(24-x%32);v[((x+64>>>9)<<4)+15]=x;for(var z=0;z<v.length;z+=16){var E=r,D=q,C=k,B=h,A=g;for(var y=0;y<80;y++){if(y<16){p[y]=v[z+y]}else{var u=p[y-3]^p[y-8]^p[y-14]^p[y-16];p[y]=(u<<1)|(u>>>31)}var s=((r<<5)|(r>>>27))+g+(p[y]>>>0)+(y<20?(q&k|~q&h)+1518500249:y<40?(q^k^h)+1859775393:y<60?(q&k|q&h|k&h)-1894007588:(q^k^h)-899497514);g=h;h=k;k=(q<<30)|(q>>>2);q=r;r=s}r+=E;q+=D;k+=C;h+=B;g+=A}return[r,q,k,h,g]};c._blocksize=16})();

/*
 * Crypto-JS v2.0.0
 * http://code.google.com/p/crypto-js/
 * Copyright (c) 2009, Jeff Mott. All rights reserved.
 * http://code.google.com/p/crypto-js/wiki/License
 */
(function(){var e=Crypto,a=e.util,b=e.charenc,d=b.UTF8,c=b.Binary;e.HMAC=function(l,m,k,h){if(m.constructor==String){m=d.stringToBytes(m)}if(k.constructor==String){k=d.stringToBytes(k)}if(k.length>l._blocksize*4){k=l(k,{asBytes:true})}var g=k.slice(0),n=k.slice(0);for(var j=0;j<l._blocksize*4;j++){g[j]^=92;n[j]^=54}var f=l(g.concat(l(n.concat(m),{asBytes:true})),{asBytes:true});return h&&h.asBytes?f:h&&h.asString?c.bytesToString(f):a.bytesToHex(f)}})();

// *********************************************************
// JavaScript メソッドのラッパー
// *********************************************************
function hash_hmac(str1,str2) {

	// ここで使用します
	return Crypto.HMAC(Crypto.SHA1, str1, str2,{ asString: true } ); 

}
function hash_hmac_bin(str1,str2) {

	// ここでは使用しません( 整数の配列が戻されます )
	return Crypto.HMAC(Crypto.SHA1, str1, str2,{ asBytes: true } ); 

}
// stringToBytes の結果を渡します
function bytesToBase64(data) {

	// ここで使用します
	return Crypto.util.bytesToBase64(data); 
}

function stringToBytes(data) {

	// ここで使用します
	return Crypto.charenc.Binary.stringToBytes(data)
}

// JavaScript のメソッドを VBScript から利用
function encodeJsUri( str ) {
	return encodeURIComponent( str );
}

function getTwitpicJson( json ) {

	var obj = eval("("+json+")" );

	return obj["url"];

}
function getTwitterJson( json ) {

	var obj = eval("("+json+")" );

	return obj["data"]["url"];

}
</SCRIPT>

<SCRIPT language="VBScript">

oauth_consumer_key = ""
oauth_consumer_secret = ""
oauth_token = ""
oauth_secret = ""

strPost = WScript.Arguments(0)

PostTwitter(strPost)

' ***********************************************************
' 文字列前後の漢字スペースを含むホワイトスペースの削除
' ***********************************************************
Function RegTrim( strValue )

	Dim regEx, str

	Set regEx = New RegExp
	regEx.IgnoreCase = True
	regEx.Pattern = "^[ \s]+"
	str = regEx.Replace( strValue, "" )
	regEx.Pattern = "[ \s]+$"
	RegTrim = regEx.Replace( str, "" )

End Function

' **********************************************************
' Twitter に自分のアプリケーションで投稿
' **********************************************************
Function PostTwitter( postdata )

	Dim twitter_url
	Dim oauth_nonce,oauth_timestamp,oauth_signature_method,oauth_version
	Dim str,oauth_signature,headerAuth,strData,strRet

	' **************************************
	' Twitter 投稿用 API URL
	' **************************************
	twitter_url = "https://api.twitter.com/1.1/statuses/update.json"

	oauth_nonce = Nonce()
	oauth_timestamp = DateDiff("s", "1970/1/1 0:00:00",DateAdd("h",-9,now))
	oauth_signature_method = "HMAC-SHA1"
	oauth_version = "1.0"

	base_s = "POST"
	base_s = base_s & "&" & rfc3986_convert(URLEncode(twitter_url))
	base_s = base_s & "&"
	base_s = base_s & "oauth_consumer_key" & "%3D" & oauth_consumer_key
	base_s = base_s & "%26"
	base_s = base_s & "oauth_nonce" & "%3D" & oauth_nonce & "%26"
	base_s = base_s & "oauth_signature_method" & "%3D" & oauth_signature_method & "%26"
	base_s = base_s & "oauth_timestamp" & "%3D" & oauth_timestamp & "%26"
	base_s = base_s & "oauth_token" & "%3D" & oauth_token & "%26"
	base_s = base_s & "oauth_version" & "%3D" & oauth_version & "%26"
	base_s = base_s & "status" & "%3D" & _
		rfc3986_convert(URLEncode(rfc3986_convert(URLEncode(postdata))))

	str = hash_hmac(base_s,oauth_consumer_secret & "&" & oauth_secret)
	oauth_signature = bytesToBase64(stringToBytes(str))
	Call objHTTP.Open( "POST",twitter_url, False )
	Call objHTTP.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
'	Call objHTTP.setRequestHeader("Expect", "")
	headerAuth = "OAuth " & _
	"oauth_consumer_key="""&oauth_consumer_key&"""," & _
	"oauth_token="""&oauth_token&"""," & _
	"oauth_nonce="""&oauth_nonce&"""," & _
	"oauth_timestamp="""&oauth_timestamp&"""," & _
	"oauth_signature_method="""&oauth_signature_method&"""," & _
	"oauth_version="""&oauth_version&"""," & _
	"oauth_signature="""&rfc3986_convert(URLEncode(oauth_signature))&""""
	Call objHTTP.setRequestHeader("Authorization", headerAuth)
	strData = "status=" & rfc3986_convert(URLEncode(postdata))
	Call objHTTP.SetRequestHeader("Content-Length",Len(strData))

	Dim lResolve : lResolve = 60 * 1000
	Dim lConnect : lConnect = 60 * 1000
	Dim lSend : lSend = 60 * 1000
	Dim lReceive : lReceive = 60 * 1000
	Call objHTTP.setTimeouts(lResolve, lConnect, lSend, lReceive)
	Call objHTTP.Send(strData)
	PostTwitter = objHTTP.responseText

End Function

' ***********************************************************
' ランダムな文字列
' ***********************************************************
Function Nonce(  )

	Dim base_str,str,I,nLen,Random
	base_str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
	base_str = base_str & "abcdefghijklmnopqrstuvwxyz0123456789"

	nLen = Len(base_str)

	str = ""
	For I = 1 to 32
		Randomize
		Random = 1 + Int(Rnd * nLen)
		str = str & Mid(base_str,Random,1)
	Next

	Nonce = str

End function

' ***********************************************************
' SHIFT_JIS を UTF-8 に変換して URLエンコード
' ※ 全ての文字をパーセントエンコーディングします
' ***********************************************************
Function URLEncode(str)

	Stream1.Open
	Stream1.Charset = "shift_jis"
	' shift_jis で入力文字を書き込む
	Stream1.WriteText str
	' コピーの為にデータポインタを先頭にセット
	Stream1.Position = 0
 
	Stream2.Open
	Stream2.Charset = "utf-8"
	' shift_jis を utf-8 に変換
	Stream1.CopyTo Stream2
	Stream1.Close

	' コピーの為にデータポインタを先頭にセット
	Stream2.Position = 0

	' バイナリで開く
	StreamBin.Open
 	StreamBin.Type = 1

	' テキストをバイナリに変換
	Stream2.CopyTo StreamBin
	Stream2.Close

	' 読み込みの為にデータポインタを先頭にセット
	StreamBin.Position = 0

	Buffer = ""
	StreamBin.Read(3)
	Do while not StreamBin.EOS
		LineBuffer = StreamBin.Read(16)
 
		For i = 1 to LenB( LineBuffer )
			CWork = MidB(LineBuffer,i,1)
			Cwork = AscB(Cwork)
			Cwork = Hex(Cwork)
			Cwork = Ucase(Cwork)
			if Len(Cwork) = 1 then
				Buffer = Buffer & "%0" & Cwork
			else
				Buffer = Buffer & "%" & Cwork
			end if
		Next
 
	Loop

	StreamBin.Close

	URLEncode = Buffer

End Function

' ***********************************************************
' 仕様を明確にする為に単純変換
' ***********************************************************
Function rfc3986_convert(str)

	Dim strResult,I,strWork

	strResult = str

	strResult = Replace(strResult,"%2D", "-")
	strResult = Replace(strResult,"%2E", ".")

	' 0〜9
	For I = &H30 to &H39
		strWork = Hex(I)
		strWork = "%" & Ucase(strWork)
		strResult = Replace(strResult,strWork, Chr(I))
	Next

	' A〜Z
	For I = &H41 to &H5A
		strWork = Hex(I)
		strWork = "%" & Ucase(strWork)
		strResult = Replace(strResult,strWork, Chr(I))
	Next

	strResult = Replace(strResult,"%5F", "_")

	' a〜z
	For I = &H61 to &H7A
		strWork = Hex(I)
		strWork = "%" & Ucase(strWork)
		strResult = Replace(strResult,strWork, Chr(I))
	Next

	strResult = Replace(strResult,"%7E", "~")
	
	rfc3986_convert = strResult

End Function

</SCRIPT>
</JOB>

更新履歴
2012-12-31 : 初回投稿
2013-06-02 : API 1.1 で動作確認
2013-07-11 : 再確認

関連する記事

Twitter API の自分のアプリのトークンを使って投稿するだけの class VS2010_Twitter

Twitter API の自分のアプリのトークンを使って投稿するだけの class VS2012_Twitter

Twitter API の自分のアプリのトークンを使って投稿するだけの class Android_Twitter

PHP : Twitter 投稿関数( twitter_update ) / cURL 関数



タグ:twitter API
posted by lightbox at 2014-03-08 15:01 | VBS + インターネット | このブログの読者になる | 更新情報をチェックする
バッチ処理

Microsoft Office
container 終わり

フリーフォントで簡単ロゴ作成
フリーフォントでボタン素材作成
フリーフォントで吹き出し画像作成
フリーフォントではんこ画像作成
ほぼ自由に利用できるフリーフォント
フリーフォントの書体見本とサンプル
画像を大きく見る為のウインドウを開くボタンの作成

Android SDK ポケットリファレンス
改訂版 Webデザイナーのための jQuery入門
今すぐ使えるかんたん ホームページ HTML&CSS入門
CSS ドロップシャドウの参考デモ
PHP正規表現チェッカー
Google Hosted Libraries
cdnjs
BUTTONS (CSS でボタン)
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり