Messenger Library アプリケーションの作成
前回に引き続きWindows Live Messenger Libraryを利用してWebページ上にLive Messengerの機能を実装していきます。はじめに今回作成するアプリケーションを示しておきましょう

前回に用意した環境と作成したファイルを使って進めていきます。前回はSign-in Controlをホストするところまで行いました。その状態から、
Deafult.htmの編集
Default.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Live Messenger Library Sample</title>
<link rel="stylesheet" href="Style.css" type="text/css" />
<script type="text/javascript" src="http://settings.messenger.live.com/api/1.0/messenger.js"></script>
<script type="text/javascript" src="Main.js"></script>
</head>
<body onload="Gihyo.LiveSample.pageLoaded();">
<div id="frame">
<div id="signInFrame"></div>
<div id="userInfo">
<div id="displayPicture"></div>
<div id="status"></div>
<div id="displayName"></div>
<div id="personalMessage"></div>
</div>
<div>Contact List</div>
<div id="contacts"></div>
<div>Active Conversations</div>
<div id="conversations"></div>
<div><input id="message" type="text" /> <input type="button" value="Send" onclick="Gihyo.LiveSample.sendMessage();" /></div>
<div id="messages"></div>
</div>
</body>
</html>
body {
font-family: メイリオ;
font-size: 0.8em;
}
#frame {
width: 400px;
}
#signInFrame {
height: 120px;
}
#userInfo {
margin: 10px 0 10px 0;
height: 100px;
}
#displayPicture {
float: left;
margin-right: 5px;
}
#contacts, #conversations, #messages {
margin-bottom: 10px;
border: solid 1px #ccc;
}
プレゼンスの表示
前回はユーザのアカウントアドレスの表示で終わっていましたので、
ユーザのプレゼンスの取得は次の手順で行います。
- Userオブジェクト、
Presenceプロパティ (IMAddressPresenceクラス型) のPropertyChanged イベントの関連付け - IMAddressPresenceクラスの各プロパティ値の取得
以下のコードは、
Gihyo.LiveSample.signInCompleted = function(sender, e) {
if (e.get_resultCode() === Microsoft.Live.Messenger.SignInResultCode.success) {
var address = Gihyo.LiveSample.User.get_address().get_address();
$('userInfo').appendChild(document.createTextNode(address));
}
}
ユーザアカウントを取得・
// var address = Gihyo.LiveSample.User.get_address().get_address();
// $('userInfo').appendChild(document.createTextNode(address));
Gihyo.LiveSample.User.get_presence().add_propertyChanged(Delegate.create(null, Gihyo.LiveSample.userPresencePropertyChanged));
IMAddressPresenceクラスは次のプロパティを使用します。
- DisplayName: 表示名
- PersonalMessage: 表示メッセージ
- DisplayPictureUrl: 表示アイコンのURLアドレス
- Status: 状態
DisplayNameとPersonalMessageは文字列、
Gihyo.
Gihyo.LiveSample.userPresencePropertyChanged = function(sender, e) {
var presence = Gihyo.LiveSample.User.get_presence();
$('displayName').innerHTML = presence.get_displayName();
$('personalMessage').innerHTML = presence.get_personalMessage();
var status = presence.get_status();
$('status').innerHTML = Enum.toString(Microsoft.Live.Messenger.PresenceStatus, status);
if (presence.get_displayPictureUrl() != null) {
$('displayPicture').innerHTML = '<img src="' + presence.get_displayPictureUrl().toString() + '" />';
}
}
以上でサインインしたときにユーザのプレゼンス表示ができました。図2に表示した例を示します。プレゼンスが変化すると作成したメソッドが呼び出されるため、

メンバーの表示
ユーザのプレゼンスの表示の次は、
- UserオブジェクトのContactsプロパティ
(ContactCollectionクラス型) を参照し、 ユーザごとにContactオブジェクトを取得 - 各ContactオブジェクトのCurrentAddressプロパティ
(IMAddressクラス型) のPropertyChanged イベントの関連付け - Contact.
CurrentAddress. Presenceプロパティ (IMAddressPresenceクラス型) の各プロパティ値の取得
メンバーはContactクラスで表されています。メンバーもユーザ同様にIMAddressPresenceオブジェクトがありプレゼンスの取得が可能です。ただし、
Contactsプロパティは列挙フィールド
Gihyo.
var contacts = Gihyo.LiveSample.User.get_contacts().getEnumerator();
while (contacts.moveNext()) {
var c = contacts.get_current();
var address = c.get_currentAddress();
address.get_presence().add_propertyChanged(Delegate.create(null, Gihyo.LiveSample.memberPresencePropertyChanged));
}
Gihyo.
Gihyo.LiveSample.memberPresencePropertyChanged = function(sender, e) {
var contacts = Gihyo.LiveSample.User.get_contacts().getEnumerator();
var sb = new StringBuilder();
while (contacts.moveNext()) {
var c = contacts.get_current();
var address = c.get_currentAddress();
var presence = address.get_presence();
var status = presence.get_status();
var displayName = presence.get_displayName();
sb.append('<li>');
sb.append((displayName != '') ? displayName : address.get_address());
sb.append('(' + Enum.toString(Microsoft.Live.Messenger.PresenceStatus, status) + ')');
sb.append('</li>');
}
$('contacts').innerHTML = '<ul>' + sb.toString() + '</ul>';
}
ここまでを実行すると図3のようになります。メンバーの情報が変更されるたびに表示が更新されると思います。ふたつのアカウントを用いて確認してみてください。

会話の管理
各メンバーとの会話は、
- 会話ごとにConversationオブジェクトの生成
(メッセージ受信により新たに会話が発生した場合は自動で作成される) - ConversationオブジェクトのSendMessageメソッドによるメッセージの送信
- ConversationオブジェクトのMessageReceivedイベントにメソッドを関連付け、
メッセージ受信の処理
今回作成するアプリケーションでは、
以上の点について順に説明していきます。
会話の作成とアクティブな会話の一覧表示
まずは、
会話の作成
ユーザが会話を新たに作る場合について考えます。会話を表すConversationクラスは、
- UserオブジェクトのConversationsプロパティ
(ConversationCollectionクラス型) のCreateメソッド
により作成できます。Createメソッドの引数には、
今回 作成するアプリケーションでは、
sb.append('<li>');
sb.append('<a href="#" onclick="Gihyo.LiveSample.createConversation(' +
"'" + address.get_address() + "'," + address.get_type() + ');return false;">');
sb.append((displayName != '') ? displayName : address.get_address());
sb.append('(' + Enum.toString(Microsoft.Live.Messenger.PresenceStatus, status) + ')');
sb.append('</a>');
sb.append('</li>');
2行追加しました。Conversationオブジェクトを生成するためIMAddressオブジェクトが引数に欲しいところですが、
Gihyo.
Gihyo.LiveSample.createConversation = function(address, type) {
var contact = Gihyo.LiveSample.User.get_contacts().find(address, type);
if (contact != null) {
Gihyo.LiveSample.User.get_conversations().create(contact.get_currentAddress());
}
}
以上で会話を作成する部分はできました。
アクティブな会話の一覧表示
作成された会話を以下の手順により一覧表示してみましょう。
- Userオブジェクト、
ConversationsプロパティのCollectionChangedイベントの関連付け - Conversationsプロパティから各Conversationオブジェクトの取得
- ConversationオブジェクトのRosterプロパティから会話に参加しているユーザの取得・
表示
Conversationsプロパティもコレクションとして扱えます。コレクションの内容が変化したときのイベント、
Gihyo.LiveSample.User.get_conversations().add_collectionChanged(Delegate.create(null, Gihyo.LiveSample.conversationsCollectionChanged));
Conversationには、
Gihyo.LiveSample.conversationsCollectionChanged = function(sender, e) {
var userAddress = Gihyo.LiveSample.User.get_address().get_address();
var sb = new StringBuilder();
var conversations = Gihyo.LiveSample.User.get_conversations().getEnumerator();
var index = 0;
while (conversations.moveNext()) {
var c = conversations.get_current();
// 会話に参加しているメンバーを列挙
var roster = c.get_roster().getEnumerator();
var names = new Array();
while (roster.moveNext()) {
var address = roster.get_current().get_address();
if (address == userAddress) {
// ユーザーは除外
continue;
}
// ユーザの表示名を取得 空文字だった場合はアドレスを使用
var displayName = roster.get_current().get_presence().get_displayName();
if (displayName != '') {
names.add(displayName);
} else {
names.add(address);
}
}
sb.append('<li>');
sb.append('<a href="#" onclick="Gihyo.LiveSample.selectConversation(' + index + ');return false;">');
sb.append(names.join(', '));
sb.append('</a>');
sb.append(' [<a href="#" onclick="Gihyo.LiveSample.closeConversation(' + index + ');return false;">close</a>]');
sb.append('</li>');
++index;
}
$('conversations').innerHTML = '<ul>' + sb.toString() + '</ul>';
}
この後の処理も考えた記述も含んでいます。会話の選択と終了のためのリンクです。indexという変数を作成してループ中にインクリメントし、
ここまでで、

メッセージの受信と表示
作成するアプリケーションでは、
会話一覧から会話を選択したときに呼ばれるメソッドを記述します。手順は次のとおりです。
- 選択していた会話のConversationオブジェクトからイベントの関連付けを削除
- 新たに選択した会話のConversationオブジェクトのMessageReceivedイベントを関連付け
- ConversationオブジェクトのHistoryプロパティからメッセージの履歴を取得・
表示
選択したConversationオブジェクトを記憶しておく必要があります。次のようにprototypeオブジェクトを使用してselectedConversationプロパティを作って管理するようにしました。
Gihyo.LiveSample.prototype.selectedConversation = null;
Gihyo.
Gihyo.LiveSample.selectConversation = function(index) {
// イベント関連付けの削除
if (Gihyo.LiveSample.selectedConversation != null) {
Gihyo.LiveSample.selectedConversation.remove_messageReceived(Gihyo.LiveSample.messageReceived);
}
// Conversationオブジェクト取得
var conversation = Gihyo.LiveSample.User.get_conversations().get_item(index);
// イベント関連付け
conversation.add_messageReceived(Delegate.create(null, Gihyo.LiveSample.messageReceived));
Gihyo.LiveSample.selectedConversation = conversation; // 選択したConversationオブジェクトを記憶させておく
$('messages').innerHTML = ''; // 会話表示欄をクリア
// 会話の履歴を表示
var history = conversation.get_history().getEnumerator();
while (history.moveNext()) {
Gihyo.LiveSample.displayMessage(history.get_current());
}
}
続いてMessageReceivedイベントに関連付けたGihyo.
Gihyo.LiveSample.messageReceived = function(sender, e) {
Gihyo.LiveSample.displayMessage(e.get_message());
}
最後に会話の履歴表示とメッセージ受信時に呼び出しているGihyo.
Gihyo.LiveSample.displayMessage = function(message) {
if (message.get_type() === Microsoft.Live.Messenger.MessageType.textMessage) {
var span = document.createElement('span');
var name = message.get_sender().get_presence().get_displayName();
span.appendChild(document.createTextNode(name + 'の発言: '));
var div = document.createElement('div');
div.appendChild(span);
div.appendChild(message.createTextElement());
$('messages').appendChild(div);
}
}
受信されるメッセージにはいくつか種類があり、
以上で受信したメッセージの表示までできるようになりました。アクティブな会話一覧から会話を選択すると、

メッセージの送信
ここまでくればメッセージの送信は簡単です。
- TextMessageオブジェクトの生成
- 選択されているConversationオブジェクトのSendMessageメソッドの呼び出し
以上です。コードは次のようになります。
Gihyo.LiveSample.sendMessage = function() {
if (Gihyo.LiveSample.selectedConversation != null) {
var message = new Microsoft.Live.Messenger.TextMessage($('message').value, null);
Gihyo.LiveSample.selectedConversation.sendMessage(message, null);
Gihyo.LiveSample.displayMessage(message);
$('message').value = '';
}
}
SendMessageメッセージの呼び出しの後、
このメソッドはページ上のボタンのクリックイベントで呼ばれるようにしています。Default.
メッセージの送信にはアクティブな会話を選択してから行う必要があります。ページ上では選択している・

会話の終了
アクティブな会話の一覧には、
Gihyo.LiveSample.closeConversation = function(index) {
var conversation = Gihyo.LiveSample.User.get_conversations().get_item(index);
if (Gihyo.LiveSample.selectedConversation == conversation) {
Gihyo.LiveSample.selectedConversation.remove_messageReceived(Gihyo.LiveSample.messageReceived);
Gihyo.LiveSample.selectedConversation = null;
$('messages').innerHTML = '';
}
conversation.close();
}
終了した会話が、
いかがでしたでしょうか。今回はここまでです。作成したアプリケーションはかなり使いにくいユーザインタフェースでしたが、