はじめに
今回も前回 に引き続いてLive SpacesのAPI/SDKについてです。前回は、Live Spaces MetaWeblog APIを利用してブログへ記事の投稿をしました。その際に認証方法としてメール投稿用のユーザー名とパスワードを使用しましたが、今回はWindows Live IDアカウントを使用した認証を使ってみましょう。また、投稿以外の操作も行います。
クライアント認証
Windows Live IDアカウントによる認証方法は、チケットと呼ばれる文字列をWindows Live ID認証サーバーから取得して、そのチケットを利用して対象のLiveサービスにアクセスします(図1 ) 。今回対象となるLiveサービスはLive Spacesです。PC上で動作するクライアントアプリケーションでこのような認証を行うためにLive ID Client SDKという開発者ツールが提供されています。アプリケーションはこのSDKで提供されるサインイン ダイアログを利用してユーザー認証を行います。
図1 クライアント認証の仕組み
今回はLive ID Client SDKを使用しますので下記を参考にインストールを行ってください。
開発環境
Live ID Client SDK
Live ID Client SDKは、ダウンロードページ からWLIDClientSDK.msiをダウンロードしてインストールします。
インストーラーを実行すると、ライブラリーとサンプアプリケーションがインストールされます。通常、ライブラリーはC:\Program Files\Common Files\microsoft shared\WLIDClientにインストールされます(64bit Windowsの場合は、Program Files (x86)フォルダー) 。サンプルは、ドライブ直下にWLID Client Sampleフォルダーが作られ、実行ファイルとソースコードが配置されます。
64bit Windows環境にインストールする場合は少し注意が必要です。SDKのインストール後にサンプルアプリケーションが自動で起動しますが、このアプリケーションが64bitに対応していないため強制終了してしまいます。サンプルアプリケーションを確認するためには、サンプルのソースコードのプロジェクトをVisual Studioで開き、プロジェクトのプロパティからプラットフォームのターゲットをx86に指定し、ビルドしなおすことで可能です(図2 ) 。
図2 プラットフォームターゲットの指定
プロジェクトの作成とライブラリーの参照
本記事ではVisual Studio 2010とVisual Basicを使用しますが、もちろんC#でもSDKは利用できます(SDK付属のサンプルはC#です) 。また、バージョンも2008で問題ありません。
まずは、コンソールアプリケーションなどの適当なWindowsプロジェクトを作成します。次に、ライブラリーの参照の追加をします。メニューの「プロジェクト」の「参照の追加」を選択し、開いたウィンドウの.NETタブから「Microsoft.WindowsLive.Id.Client」を選びます。もしこの項目がない場合は、参照タブからSDKのインストール先から直接「Microsoft.WindowsLive.Id.Client.dll」を選択します。
サインイン処理
それでは、Live ID Client SDKを利用して、Windows Live IDアカウントを使用してLive Spacesにアクセスするためのコードを書いていきます。
最初にサインイン ダイアログ(図3 )を表示してサインインを行うコードを記述します。サインインや認証処理はライブラリーに任せ、アプリケーションはダイアログ表示の呼び出しを行います。ユーザーは表示されたダイアログにWindows Live IDアカウントのメールアドレスとパスワードを入力しサインインすることになります。ユーザーの認証に成功した場合、サインインユーザーのメールアドレスなどは参照できますが、パスワード自体は参照できません。
図3 サインイン ダイアログ
この処理にはIdentity クラスとIdentityManager クラスを使います。Identityクラスはユーザーを表します。Identityクラスのインスタンス生成にIdentityManagerクラスを使用します。Liveサービスの認証サーバーとのやりとりもIdentityManagerが使われます。Identityオブジェクトの作成とサインイン ダイアログの表示するコードは次のようになります。
Dim manager = IdentityManager . CreateInstance ( "LiveSpacesSample;***@live.jp;Live Spaces Sample" , "Live Spaces Sample" )
Dim identity = manager . CreateIdentity
If Not identity . IsAuthenticated Then
If identity . Authenticate Then
Else
End If
End If
IdentityManagerのインスタンスは、CreateInstance メソッドにアプリケーションIDとアプリケーション名を渡すことで取得します。アプリケーションIDは、組織名・メールアドレス・アプリケーション名を「;」で区切った文字列です。IDの登録などの作業は必要なく、適切と思われる値を設定します。
Identityのインスタンスは、IdentityManager オブジェクトのCreateIdentity メソッドの戻り値として得ます。Identity オブジェクトのAuthenticate メソッドを呼び出すことでサインイン ダイアログが表示されます。
チケットの取得
サインインが完了し認証されている状態のとき、IdentityクラスのGetTicket メソッドを使用して特定のLiveサービスへのチケットの取得ができます。Live Spacesのアクセスに必要となるチケットを取得するコードは次のようになります。
Dim ticket = Identity . GetTicket ( "storage.msn.com" , "MBI" , True )
GetTicketメソッドの引数は、アクセス先・認証ポリシー・ローカルにキャッシュがある場合もサーバーからチケットを入手するか否かです。
このチケットの値を、HTTPのAuthorizationヘッダーに指定することで、Live Spaces MetaWeblog APIの場合、パスワードなしでアクセスが可能になります。
ここまでのコードをまとめると次のようになります。IdentityManagerオブジェクトとIdentityオブジェクトを格納する変数はPrivate変数に変更しています。サインイン関連の処理で例外が発生した場合、WLLogOnExceptionがスローされます。
Private Manager As IdentityManager
Private Identity As Identity
Function GetTicket () As String
Try
Manager = IdentityManager . CreateInstance ( "LiveSpacesSample;***@live.jp;Live Spaces Sample" , "Live Spaces Sample" )
Identity = Manager . CreateIdentity
Catch ex As WLLogOnException
Throw
End Try
If Not Identity . IsAuthenticated Then
If Identity . Authenticate Then
Try
Dim ticket = Identity . GetTicket ( "storage.msn.com" , "MBI" , True )
Return ticket
Catch ex As WLLogOnException
Throw
End Try
Else
End If
End If
Return Nothing
End Function
実際にチケットを使用しているコードはこの後に紹介します。
カテゴリーの取得
さて前回 はLive Spaces MetaWeblog APIを利用して記事の投稿を行いましたが、今回はまずカテゴリーの取得をしてみましょう。MetaWeblog APIについては前回の内容を参照してください。
新しい記事の投稿はmetaWeblog.getCategories メソッドを使用します。必要なパラメーターは次の通りです。
blogid
ブログID
Live Spacesの場合自分のブログを表す「MyBlog」に固定
username
ユーザー名
password
パスワード
パスワードの値は、チケットによる認証を使用する場合、長さ0の文字列を指定します。
カテゴリー取得の場合、サーバーからは次のようなXMLが返ってきます。
<methodResponse xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd = "http://www.w3.org/2001/XMLSchema" >
<params>
<param>
<value>
<array>
<data>
<value>
<struct>
<member>
<name> description </name>
<value> Test Posts </value>
</member>
<member>
<name> htmlUrl </name>
<value />
</member>
<member>
<name> rssUrl </name>
<value />
</member>
<member>
<name> title </name>
<value> Test Posts </value>
</member>
</struct>
</value>
<value>
<struct>
<member>
<name> description </name>
<value> Books </value>
</member>
<member>
<name> htmlUrl </name>
<value />
</member>
<member>
<name> rssUrl </name>
<value />
</member>
<member>
<name> title </name>
<value> Books </value>
</member>
</struct>
</value>
</data>
</array>
</value>
</param>
</params>
</methodResponse>
カテゴリーの数だけ構造体を表す<struct>要素が含まれています。その中の、descriptionとtitleの両方カテゴリー名が格納されています。上記の場合、カテゴリー名はTest PostsとBooksです。
カテゴリーを取得するコードは次のようになります。
Sub GetCategories ()
Dim blogId = "MyBlog"
Dim userName = "***"
Dim password = ""
Dim requestXml =
<? xml version = "1.0" encoding = "utf-8" ?>
<methodCall>
<methodName> metaWeblog.getCategories </methodName>
<params>
<param><value><string> <% = blogId %> </string></value></param>
<param><value><string> <% = userName %> </string></value></param>
<param><value><string> <% = password %> </string></value></param>
</params>
</methodCall>
Dim doc = GetResponse ( requestXml )
For Each m In doc ...< member >
If m .< name >. Value = "title" Then
Console . WriteLine ( m .< value >. Value )
End If
Next
End Sub
送信するXMLにはメソッド名としてmetaWeblog.getCategoriesが<methodName>要素に指定されているのがわかります。カテゴリーの列挙はtitleに指定されている値を表示するようにしています。XML文書を送信して応答を受信している部分のGetResponseメソッドは次のようになります。
Function GetResponse ( ByVal requestXml As XDocument ) As XDocument
Dim serviceEndpoint = "https://storage.msn.com/storageservice/MetaWeblog.rpc"
Dim data () As Byte
Using ms = New System . IO . MemoryStream
requestXml . Save ( ms )
data = ms . ToArray
End Using
Dim client = New WebClient
client . Headers . Add ( HttpRequestHeader . ContentType , "text/xml" )
Dim ticket = GetTicket ()
client . Headers . Add ( HttpRequestHeader . Authorization , "WLID1.0 " & ticket )
Dim responseData = client . UploadData ( serviceEndpoint , data )
Dim responseStream = New System . IO . MemoryStream ( responseData )
Dim bom = System . Text . Encoding . UTF8 . GetPreamble
Dim includesBom = True
For Each b In bom
If responseStream . ReadByte <> b Then
includesBom = False
responseStream . Seek ( 0 , System . IO . SeekOrigin . Begin )
Exit For
End If
Next
Dim doc As XDocument
If includesBom Then
Dim buf ( Convert . ToInt32 ( responseStream . Length - bom . Length - 1 )) As Byte
For i = 0 To buf . Length - 1
buf ( i ) = CByte ( responseStream . ReadByte )
Next
doc = XDocument . Parse ( System . Text . Encoding . UTF8 . GetString ( buf ))
Else
doc = XDocument . Parse ( System . Text . Encoding . UTF8 . GetString ( responseStream . ToArray ))
End If
responseStream . Close ()
Return doc
End Function
上記コードの多くの部分は、前回 の記事投稿のコードと同じです。異なる部分はチケットを使用した認証部分です。先ほど示したGetTicketメソッドからチケットを取得し、WebClientオブジェクトのリクエストヘッダーにチケットの値を指定しています。次のようにHTTP Authorizationヘッダーには、チケットの値の前に「WLID1.0」を付ける必要があります。
Authorization: WLID1.0 ticket_data
ここまでを実行して正しくカテゴリーが取得できたでしょうか? 指定しているパラメーターなどが誤っている場合、サーバーからはエラー内容が記述されたXMLが応答されますので、その内容を確認して対処します。
記事の取得と編集
カテゴリーの取得以外に、MetaWeblog APIを利用して次の操作もしてみましょう。
最近投稿したブログの記事や下書きの記事一覧の取得
指定した記事の取得
記事の編集
最近の記事一覧の取得
最近投稿した下書きを含む記事を取得してみましょう。前回 紹介したmetaWeblog.newPost メソッドによる記事の投稿では、投稿に成功した場合、記事のIDを戻り値として受信していました。このように投稿した記事には ひとつひとつIDが付いています。このIDは、最近の記事一覧を取得することでも各IDがわかります。
最近の記事一覧の取得は、metaWeblog.getRecentPosts メソッドを使います。パラメーターは次の通りです。
blogid
ブログID
Live Spacesの場合自分のブログを表す「MyBlog」に固定
username
ユーザー名
password
パスワード
numberOfPosts
取得する記事数(最大20)
戻り値、つまりサーバーからの応答には次の情報が、記事の数だけ含まれています。
title
記事のタイトル
description
記事の本文
postid
記事のID
dateCreated
投稿日時
categories
記事のカテゴリーの配列
publish
記事が公開済みの場合1、下書きの場合0
実際のコードは次のようになります。
Sub GetRecentPosts ()
Dim blogId = "MyBlog"
Dim userName = "***"
Dim password = ""
Dim numberOfPosts = 20
Dim requestXml =
<? xml version = "1.0" encoding = "utf-8" ?>
<methodCall>
<methodName> metaWeblog.getRecentPosts </methodName>
<params>
<param><value><string> <% = blogId %> </string></value></param>
<param><value><string> <% = userName %> </string></value></param>
<param><value><string> <% = password %> </string></value></param>
<param><value><i4> <% = numberOfPosts %> </i4></value></param>
</params>
</methodCall>
Dim doc = GetResponse ( requestXml )
End Sub
指定した記事の取得
記事の投稿や最近の記事一覧の取得などにより記事のIDがわかれば、メソッドを使用して、特定のひとつの記事の情報のみ取得できます。パラメーターは次の通りです。これまでと違い、blogidには記事のIDを指定します。
blogid
記事のID
username
ユーザー名
password
パスワード
戻り値は、指定したIDの記事の情報です。取得できる項目は、metaWeblog.getRecentPostsメソッドを呼び出したときと同じです。
コードは次のようになります。
Sub GetPost ()
Dim blogId = "xxx"
Dim userName = "***"
Dim password = ""
Dim requestXml =
<? xml version = "1.0" encoding = "utf-8" ?>
<methodCall>
<methodName> metaWeblog.getPost </methodName>
<params>
<param><value><string> <% = blogId %> </string></value></param>
<param><value><string> <% = userName %> </string></value></param>
<param><value><string> <% = password %> </string></value></param>
</params>
</methodCall>
Dim doc = GetResponse ( requestXml )
End Sub
記事の編集
今回の最後は記事の編集です。記事の編集、つまり既に投稿済みの記事の更新は、metaWeblog.editPost メソッドを使います。パラメーターは以下のものがあります。これらの項目は、metaWeblog.newPostメソッドのものと同じです。blogidに指定する値が、ブログIDか記事のIDかで異なっています。
blogid
記事のID
username
ユーザー名
password
パスワード
content
記事の情報の構造体
publish
公開する場合1、下書きにする場合0
content構造体の項目は次の通りです。
title
記事のタイトル
description
記事の本文
dateCreated
投稿日時
categories
記事のカテゴリーの配列
正常に処理が完了したときの戻り値は、次のXMLが返ってきます。常にtrueを返します。
<methodResponse xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd = "http://www.w3.org/2001/XMLSchema" >
<params>
<param>
<value>
<boolean> 1 </boolean>
</value>
</param>
</params>
</methodResponse>
コードは次のようになります。
Sub EditPost ()
Dim blogId = "xxx"
Dim userName = "***"
Dim password = ""
Dim publish = True
Dim categories = New List ( Of String ) From { "Books" }
Dim title = "編集したタイトル"
Dim description = "編集した本文"
Dim dateCreated = DateTime . UtcNow
Dim requestXml =
<? xml version = "1.0" encoding = "utf-8" ?>
<methodCall>
<methodName> metaWeblog.editPost </methodName>
<params>
<param><value><string> <% = blogId %> </string></value></param>
<param><value><string> <% = userName %> </string></value></param>
<param><value><string> <% = password %> </string></value></param>
<param>
<value>
<struct>
<member>
<name> title </name>
<value><string> <% = title %> </string></value>
</member>
<member>
<name> description </name>
<value><string> <% = description %> </string></value>
</member>
<member>
<name> categories </name>
<value>
<array>
<% = From c In categories
Select <data><value><string> <% = c %> </string></value></data>
%>
</array>
</value>
</member>
<member>
<name> dateCreated </name>
<value><dateTime.iso8601> <% = dateCreated . ToString ( "s" ) %> </dateTime.iso8601></value>
</member>
</struct>
</value>
</param>
<param><value><boolean> <% = If ( publish , 1 , 0 ) %> </boolean></value></param>
</params>
</methodCall>
Dim doc = GetResponse ( requestXml )
Process . Start ( "http://" & userName & ".spaces.live.com/blog/cns!" & blogId & ".entry" )
End Sub
今回は以上です。前回 の内容とあわせると、Live Spacesのブログ投稿や編集を行う自作クライアントソフトの作成もできますね。次回ももう少しLive Spacesについて扱う予定です。