Twitter風? Live Messengerアプリ
今回は、
作成するアプリケーションは図1のような画面のアプリケーションです。サインイン後、
![図1 Twitter風?Live Messengerアプリ 図1 Twitter風?Live Messengerアプリ](/assets/images/dev/serial/01/wl-sdk/0037/thumb/TH800_001.png)
実装する機能はそう多くありません。次の機能を実装します。
- サインインユーザーの表示
- オンラインメンバーの表示
- メッセージの送信
- メッセージの受信
- メッセージの表示
- Bingの検索結果表示
少しオリジナルな機能として
検索を除いて基本的な機能ばかりですが、
ベースとなる部分はこれまでと同じようにSDKに含まれるASP.
画面の作成
最初に本題ではない、
<!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"
xml:lang="ja-jp"
xmlns:msgr="http://messenger.live.com/2009/ui-tags">
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
<title>Live Messenger Web Toolkit</title>
<script src="http://ajax.microsoft.com/ajax/jquery/jquery-1.4.2.min.js" type="text/javascript"></script>
<script src="http://www.wlmessenger.net/api/3.7/loader.js" type="text/javascript"></script>
<script type="text/javascript">
// ここにコードを追加
Microsoft.Live.Core.Loader.load(['messenger.ui.styles.core', 'messenger.ui']);
</script>
<style type="text/css">
body {
background-color: #cde; }
#content {
margin: 30px auto;
width: 800px;
background-color: White; }
#console {
padding: 20px; }
#consoleLeft {
float: left;
width: 520px; }
#consoleRight {
float:right;
width: 220px; }
#userPicture {
float: left;
width: 30px;
height: 30px; }
#userMessage {
clear:both; }
#text {
margin: 10px 0 10px 0; }
#sendButton {
float:right;
width: 120px;
height: 30px; }
#messages {
clear: both;
margin-top: 50px; }
#messages ul {
margin: 0;
padding: 20px 20px 50px 20px;
list-style: none; }
#messages li {
clear: left;
border-top: 1px solid #ccc;
padding: 5px; }
#messages .picture {
float: left;
width: 55px;
height: 54px; }
#messages .name {
padding-right: 5px; }
</style>
</head>
<body>
<!-- Messenger Appliaction コントロール -->
<msgr:app
id="appTag"
application-verifier-token="<%= ApplicationVerifier %>"
privacy-url="Privacy.html"
channel-url="Channel.html"
token-url="RefreshMessengerToken.aspx"
onAuthenticated="onAuthenticated"
onSignedIn="onSignedIn"
onSignedOut="onSignedOut">
</msgr:app>
<div id="content">
<div id="console" style="clear: both;">
<div id="consoleLeft">
<!-- コンタクトリストの表示とテキスト入力エリア -->
<form action="#">
<select id="onlineContacts"><option /></select>
<span>にインスタントメッセージを送る。</span>
<div><textarea id="text" cols="30" rows="2" style="width:512px;"></textarea></div>
<input id="sendButton" type="button" value="送信" disabled="disabled" />
</form>
</div>
<div id="consoleRight">
<!-- サインイン ユーザーの情報表示エリア -->
</div>
</div>
<div id="messages">
<ul>
<!-- インスタントメッセージ表示エリア -->
</ul>
</div>
</div>
<!-- for Debug -->
<msgr:bar></msgr:bar>
</body>
</html>
Messenger Applicationコントロールについては第34回を参考にしてください。Messenger Web Barコントロールは、
ここまでのVisual Studioの環境は図2のようになっています。
![図2 Visual Studio 画面 図2 Visual Studio 画面](/assets/images/dev/serial/01/wl-sdk/0037/thumb/TH800_002.png)
サインイン処理とユーザー情報の表示・編集
ユーザーのサインイン処理
XHTMLのサインイン ユーザーの情報表示エリア部分を次のように編集します。
<!-- サインイン ユーザーの情報表示エリア -->
<!-- Sign In コントロール -->
<msgr:sign-in size="medium" theme="blue"></msgr:sign-in>
<msgr:if cid="$user" condition="online"><!-- If コントロール -->
<!-- 表示アイコン Display Picture コントロール -->
<div id="userPicture"><msgr:display-picture cid="$user" presence-enabled="false" size="small"></msgr:display-picture></div>
<!-- 名前 Display Name コントロール -->
<div><msgr:display-name cid="$user" linked="true"></msgr:display-name></div>
<!-- 表示メッセージ Personal Message コントロール -->
<div id="userMessage"><msgr:personal-message cid="$user"></msgr:personal-message></div>
</msgr:if>
Display Pictureコントロールのpresence-enabled属性をfalseにすると、
サインインしていないときの画面は図3のようになります。
![図3 サインインしていない場合の画面 図3 サインインしていない場合の画面](/assets/images/dev/serial/01/wl-sdk/0037/thumb/TH800_003.png)
Live Messenger Library
ここまではUI Controlsの設置だけでした。ここからはLive Messenger Libraryを利用してJavaScriptコードを記述していきます。Live Messenger Libraryを利用すると、
ユーザーオブジェクトの取得
Live Messengerのほとんどの操作はサインインしたユーザーに対して行います。Live Messenger Libraryでは、
Windows Liveサービスとの認証完了後にUserオブジェクトを取得します。Messenger ApplicationコントロールのonAuthenticated属性に認証完了後に呼ばれる関数を指定してあります。ここでUserオブジェクトを取得しましょう。次のJavaScriptのコードを追記します。
var User;
function onAuthenticated(e) {
// 認証完了
// User オブジェクト取得
User = e.get_user();
}
オンラインメンバーの表示
次にユーザーのコンタクトリストのうちオンラインのメンバーのみを取得し、
ユーザーのサインインとサインアウトのイベントはMessenger Applicationコントロールを使い通知を受けます。onSignedInとonSignedOut属性にそれぞれサインイン・
オンラインのコンタクトリストは、
上記の内容をコードで書いてみましょう。サインイン・
function onSignedIn(e) {
// 送信ボタンの有効化
$("#sendButton").removeAttr("disabled");
// オンラインのメンバーに更新があった場合に呼ぶ関数を指定
User.get_onlineContacts().add_collectionChanged(onlineContactsCollectionChanged);
// 会話コレクションに更新があった場合に呼ぶ関数を指定
User.get_conversations().add_collectionChanged(conversationCollectionChanged);
}
function onSignedOut(e) {
// 送信ボタンの無効化
$("#sendButton").attr("disabled", "disabled");
}
オンラインのコンタクトはUser.
上記コードでは、
オンラインコンタクトの内容に変更があった場合、
function onlineContactsCollectionChanged() {
var list = $("#onlineContacts"); // <select>要素
var selectedCid = list.val(); // 選択されている項目の value 属性値を取得
var existed = false;
list.children().remove(); // 一度 <select>要素内の項目を削除
// オンラインのメンバー列挙
for (var i = 0; i < User.get_onlineContacts().get_count(); ++i) {
var c = User.get_onlineContacts().get_item(i);
var cid = c.get_cid(); // メンバーの CID 取得
if (cid == selectedCid) {
existed = true;
}
// <option>要素の追加 value属性には CID を指定し、表示テキストはメンバーの名前を指定
list.append($("<option>").attr("value", cid).text(c.get_displayName()));
}
if (existed) {
// 一覧の更新前に選択されていた項目を選択
list.val(selectedCid);
}
}
メッセージの送信
続いて、
メッセージを送信するコードは次のようになります。ここでは、
function sendMessage(cid, text) {
if (!cid || !text) return;
var contact = User.get_onlineContacts().findByCid(cid);
if (!contact) return;
// メッセージの作成
var message = new Microsoft.Live.Messenger.TextMessage(text);
// 会話の作成とメッセージの送信
var conv = User.get_conversations().create(contact);
conv.sendMessage(message);
// メッセージの表示
var userCid = User.get_presence().get_imAddress().get_cid(); // サインインユーザーの CID
showMessage(userCid, text);
}
送信するメッセージは文字列からTextMessageオブジェクトを生成して使います。TextMessageクラス以外にもシェイクを表すNudeMessageクラスやアプリケーション独自のメッセージを定義できるApplicationMessageクラスがライブラリーには用意されています。
会話はConversationクラスで表します。User.
同じユーザー相手へのメッセージでも毎回新たに会話を作成するように見えますが、
送信ボタンをクリックすると上記の関数を実行するようにしておきましょう。
$(function () {
$("#sendButton").click(
function () {
if (!User) return false;
var cid = $("#onlineContacts").val();
var text = $("#text").val();
// メッセージの送信
sendMessage(cid, text);
// 入力されたテキストから検索
search(text, cid);
$("#text").val("");
return false;
});
});
メッセージの受信
次はインスタントメッセージの受信です。これも送信と同じくConversationオブジェクトを使います。メッセージを受信するとConversationクラスのMessageReceivedイベントが起きるので、
コレクションの変更イベントは、
User.get_conversations().add_collectionChanged(conversationCollectionChanged);
関連付けたconversationCollectionChanged関数は次のように追記します。
function conversationCollectionChanged(sender, e) {
// 追加された Conversation オブジェクト取得
var items = e.get_newItems();
// MessageReceived イベントと関連付け
$.each(items, function () {
if (!this.get_closed()) {
this.add_messageReceived(messageReceived);
}
});
}
そしてMessageReceivedイベントで呼ばれる関数は次のように記述します。
function messageReceived(sender, e) {
switch (e.get_message().get_type()) {
case Microsoft.Live.Messenger.MessageType.textMessage:
// Message オブジェクト参照
var message = e.get_message();
// 送信者の Contact オブジェクト取得
var contact = User.get_contacts().findByAddress(message.get_sender());
if (contact) {
var cid = contact.get_cid(); // 送信者の CID
var text = message.get_text(); // 受信メッセージのテキスト
// 受信メッセージの表示
showMessage(cid, text);
// メッセージのテキストから検索
search(text, cid);
}
break;
default:
break;
}
}
受信したメッセージの種類を調べ、
メッセージの表示
インスタントメッセージを送受信したときに、
<li>
<div class="picture"><msgr:display-picture cid="..." presence-enabled="false" size="medium"></msgr:display-picture></div>
<div class="name"><msgr:display-name cid="..." editable="false" linked="true"></msgr:display-name></div>
<span class="message">メッセージ</span>
</li>
実際のコードは以下の通りです。メッセージの表示
function showMessage(cid, text) {
var li = $("<li>");
var pic = $("<div>").addClass("picture");
$create(Microsoft.Live.UI.Messenger.DisplayPictureControl,
{ cid: cid, presenceEnabled: false, size: "medium" },
null, null, pic.get(0));
li.append(pic);
var name = $("<div>").addClass("name");
$create(Microsoft.Live.UI.Messenger.DisplayNameControl, { cid: cid }, null, null, name.get(0));
li.append(name);
li.append($("<span>").addClass("message").text(text));
$("#messages>ul").prepend(li);
}
この動的なUI Controlsの作成は第35回でも紹介しています。
Bingで検索
最後に送受信したメッセージテキスト内に
Bingでの検索はBing APIを利用します。Bing APIについては本連載で扱っていいませんが、
コードは次の通りです。search関数の引数には送受信メッセージのテキストと送信者のCIDを渡すようにします。
var appId = "取得したApplication ID";
function search(text, cid) {
if (!text.match(/(.+)で検索/) || RegExp.$1.match(/で検索/)) {
return false;
}
// Bing で検索
$.ajax({
type: "GET",
url: "http://api.bing.net/json.aspx",
dataType: "jsonp",
data: {
AppId: appId,
Version: 2.2,
Market: "ja-JP",
Query: RegExp.$1,
Sources: "web",
"Web.Count": 1,
JsonType: "callback"
},
success: function (data, dataType) {
procSearchResult(data, cid);
},
jsonp: "JsonCallback"
});
}
「○○で検索」
検索結果を元にメッセージを送信する関数は次のようになります。
function procSearchResult(response, cid) {
if (response.SearchResponse.Errors) {
var text = "";
$.each(response.SearchResponse.Errors, function () {
text += this.Message + "\n";
});
alert(text); // error!
return false;
}
var text = "";
if (response.SearchResponse.Web.Total == 0) {
text = response.SearchResponse.Query.SearchTerms + "の検索結果 (0件)";
} else {
text = response.SearchResponse.Query.SearchTerms + "の検索結果 (" +
response.SearchResponse.Web.Total + "件)\n" +
response.SearchResponse.Web.Results[0].Title + "\n" +
response.SearchResponse.Web.Results[0].Url;
}
// 検索結果を送信
sendMessage(cid, text);
}
以上で完了です。実際にアプリケーションをWebに配置して確認してみましょう。
おわりに
いかがでしたでしょうか。今回はここまでです。Live Messenger Web Toolkit連載のまとめというわけではないですが、
今回のアプリケーションは、