デスクネッツにVBでデータを自動登録する

■Visual Basic系の開発環境で任意のWebフォームにデータを送信・登録できるようになると、社内の任意のWebアプリケーションにデータを登録できる。ただし言うまでもないことだが、下手にPOSTでデータを送信するとそのWebアプリケーションに負荷をかけるばかりか、とんでもない不正データを誤って大量に登録する原因ともなる。飽くまで慎重に実施して頂きたい。
さて、標的となるWebアプリケーションはデスクネッツ・スタンダード版である。その中でも電子会議室を使って、自動的にスレッドを立てる処理を書いてみたい。デスクネッツは最初の画面でユーザ名とパスワードを入力してログインする処理が必要だが、MSXML2.XMLHTTPオブジェクトの同一のインスタンスを一貫して使えば、ログインも簡単に出来てしまう。
デスクネッツにはGETメソッドでログインできる。「uid」に自分のユーザID(注意:ログインIDではなく、デスクネッツ内部で付番されているユニークな番号のこと。デスクネッツの「ユーザ名簿」で自分の画面を開くと、URLの中に「id」というパラメータがあるはずだ。これが自分のユーザIDである)、「_word」にパスワード、「cmd」には固定で「certify」という文字列をわたす。つまり下記のようなURLでログインできてしまう。
http://サーバ名/dnet.exe?uid=14&_word=PASSWORD&cmd=certify
これはユーザIDが「14」でパスワードが「PASSWORD」の例である。したがってプログラムにすると下記の2行でデスクネッツへのログイン完了だ。
oHttp.Open “GET”, “http://サーバ名/dnet.exe?” & _
uid=14&_word=PASSWORD&cmd=certify”, False
oHttp.Send
続けて特定の電子会議室に新規投稿する画面に直接ジャンプする場合もGETメソッドで対応できる。今度は「dnet.exe」ではなく「xforum.exe」というCGIプログラムを呼び出す。「id」というパラメータに電子会議室のID(これは対象の電子会議室を開くとURLの中にやはり「id」というパラメータがあるはずだ。これがその電子会議室のIDである)、「page」というパラメータには固定の文字列「formartentry」(おそらくForm for article entryの略)をわたす。つまり下記のようなURLで新規投稿画面が開く。
http://サーバ名/xforum.exe?id=25&page=forumartentry
ログイン画面でログインした後、25番の電子会議室の新規投稿画面に飛ぶという一連の処理は下記のようなプログラムになる。
oHttp.Open “GET”, “http://サーバ名/dnet.exe?” & _
“uid=14&_word=PASSWORD&cmd=certify”, False
oHttp.Send
oHttp.Open “GET”, “http://サーバ名/xforum.exe?” & _
“id=25&page=forumartentry”, False
oHttp.Send
あまりに簡単すぎる。次にこの電子会議室にそのまま投稿データを送信して、スレッドを一つ立ててみよう。呼び出すCGIプログラムは同じく「xforum.exe」だが、今度はGETメソッドではなくPOSTメソッドで送信する。しかし送信データの組み立て方はGETメソッドとまったく同じである。
「cmd」パラメータには固定の文字列「forumcmdartentry」(おそらくForum command for article entryの略)、「id」には電子会議室のID、「title」には投稿の題名、「contr」には投稿者名、匿名投稿にしたい場合は「anonymouse」に「1」をセットする(デスクネッツの開発者たちはanonymousという正しいつづりを知らなかったようだ)。そして「memo」に投稿内容の本文をわたす。
「title」「contr」「memo」の部分には必ず漢字が入ってくるはずなのでURLエンコード処理が必須になる。また「memo」の部分には改行が必ず入ってくるはずなので、1行ずつURLエンコードした上で、各行の末尾に「%0D%0A」というURLエンコードされた改行コードを付加する処理が必要だ。
LotusScriptでVariant型のデータに、パラメータ名とURLエンコードされた値をつなげていく関数を作ってみると下記のようになる。
Function AppendToSendData(vData As Variant, sName As String, _
vValue As Variant) As Variant
Dim vTmp As Variant
Dim I As Integer
If Datatype(vValue) = 8 Then
vTmp = Evaluate(“@URLEncode(“”Shift_JIS””;””” & vValue & “””)”)
vData = vData & sName & “=” & vTmp(0)
Else
vData = vData & sName & “=”
For I = 0 To Ubound(vValue)
vTmp = Evaluate(“@URLEncode(“”Shift_JIS””;””” & vValue(I) & “””)”)
vData = vData & vTmp(0) & “%0D%0A”
Next
End If
If Right(vData, 6) = “%0D%0A” Then vData = Left(vData, Len(vData) – 6)
vData = vData & “&”
AppendToSendData = vData
End Function
この関数を呼び出しながら、投稿データを組み立てていけばよい。いったんデータ送信用のVariant変数vDataをクリアしてから送信データを組み立てていく。「memo」というパラメータにわたす投稿の本文部分は文字列の配列変数にしてみた。本文の各行を配列の各インデックスに代入して上記に定義したAppendToSendData関数にわたすと、URLエンコードしつつ「%0D%0A」で改行コードも付加してくれるというわけだ。
Dim sMemo() As String
vData = “”
Call AppendToSendData(vData, “cmd”, “forumcmdartentry”)
Call AppendToSendData(vData, “id”, “25”)
Call AppendToSendData(vData, “title”, “テストの自動投稿です”)
Call AppendToSendData(vData, “contr”, “自動投稿者”)
Redim sMemo(2) As String
sMemo(0) = “ちゃんと改行されるか、”
sMemo(1) = “検証中 http://www.yahoo.co.jp/”
Call AppendToSendData(vData, “memo”, sMemo)
vData = vData & “s_ok”
oHttp.Open “POST”, “http://サーバ名/xforum.exe”, False
oHttp.Send vData
ここでなかなか気づかないのが最後の「s_ok」というパラメータである。このパラメータには値をわたさず、パラメータ名だけを送信する。このパラメータがないとデスクネッツのCGIプログラムは送信されたデータをPOSTデータと見なしてくれない。送信データの組み立てが終われば、今度は1番目の引数を「POST」にしてOpenメソッドを呼び出せばいい。POSTメソッドなので2番目の引数のURLに余計なパラメータはいらない。シンプルに「http://サーバ名/xforum.exe」だけで問題ない。最後のFalseは例によって同期処理という意味で、Webページの処理が終わるまでプログラムは待ち状態になる。
CGIプログラム側で厳しいセキュリティチェックをしていない限り、Webアプリケーションに対しては同じような方法でログインし、データを送信・登録することができる。どんなパラメータにどのような値をわたせばよいのかは、WebアプリケーションのHTMLのソースを注意深く分析すれば大抵のことは分かると考えていい。