メモ代わり。てきとーに。 いや、ですからてきとーですって。 2年前ぐらいにPythonあたりでメールくれた方、ごめんなさい。メール紛失してしまい無視した形になってしまいました。。。

2009年7月29日水曜日

[Apache Shindig][お勉強][OpenSocial] メモ102 opensocial.requestShareAppのサーバ側実装をしてみる(1)

opensocial.requestShareAppをサーバ側まで含めて動かしてみる。

方針は、
1) requestShareAppがコールされると、ダイアログを表示する。
2) ダイアログには友達一覧が表示され、requestShareApp先を選択できる。
3) ダイアログで「送信」ボタンを押下すると、messages.modifyがサーバ側へ発行される。
4) サーバ側はmessageサービスのmodifyメソッドにて処理する。
5) DBに保存。
といった感じ。

requestSendMessageと分けるために、msgCollIdにrequestShareAppから来たデータで
あることが分かるような値をセットする。

まずは
features/opensocial-jsonrpc/jsonrpccontainer.jsで、ガジェットと同じフレームで
実行されるrequestShareAppを定義。(前やったけどやりなおし。)


JsonRpcContainer.prototype.requestShareApp = function(recipientIds, reason,
opt_callback, opt_params) {
var callbackId = "cId_" + Math.random();

var self = this;
var callback = function(success, recip, title, body) {
var req = opensocial.newDataRequest();
var viewer = new opensocial.IdSpec({'userId' : 'VIEWER'});
var rpc = { method : "messages.modify" };
rpc.params = self.translateIdSpec(viewer);
rpc.params.appId = "@app";

FieldTranslations.translateNetworkDistance(viewer, rpc.params);

rpc.params.msgCollId = 'shareApp';
rpc.params.entity = {};
rpc.params.entity["title"] = title;
rpc.params.entity["body"] = body;
rpc.params.entity["recipients"] = recip

var shareAppRequest = new JsonRpcRequestItem(rpc);

req.add(shareAppRequest, 'key');
req.send(function(response) {
opt_callback(response.get('key'));
});
};
callbackIdStore[callbackId] = callback;

var body = gadgets.util.unescapeString(reason.getField(
opensocial.Message.Field.BODY));

if (!body || body.length === 0) {
var bodyMsgKey = gadgets.util.unescapeString(reason.getField(
opensocial.Message.Field.BODY_ID));
body = gadgets.Prefs.getMsg(bodyMsgKey);
}

/* 修正ここから */
/* 友達一覧を取得する */
var friendsArray = [];
var handleGetFriends = function(data) {
var friends = data.get("get_friends");
if (friends.hadError()) {
return;
}
var data = friends.getData();
data.each(function(friend) {
var tmp = {};
tmp.thumbnailUrl = friend.getField(opensocial.Person.Field.THUMBNAIL_URL);
tmp.nickname = friend.getField(opensocial.Person.Field.NICKNAME );
tmp.id = friend.getField(opensocial.Person.Field.ID );
friendsArray.push(tmp);
});
gadgets.rpc.call('..', 'shindig.requestShareApp',
null,
callbackId,
friendsArray,
body);
};
var getfriends = function() {
var params = {};
params[opensocial.DataRequest.PeopleRequestFields.PROFILE_DETAILS] = [
opensocial.Person.Field.ID,
opensocial.Person.Field.NICKNAME,
opensocial.Person.Field.THUMBNAIL_URL,
opensocial.Person.Field.PROFILE_URL
];
var req = opensocial.newDataRequest();
var idSpecParam = {};
idSpecParam[opensocial.IdSpec.Field.USER_ID] = opensocial.IdSpec.PersonId.VIEWER;
idSpecParam[opensocial.IdSpec.Field.GROUP_ID] = opensocial.IdSpec.GroupId.FRIENDS;
var idSpec = opensocial.newIdSpec(idSpecParam);

req.add(req.newFetchPeopleRequest(idSpec, params), "get_friends");
req.send(handleGetFriends);
};
getfriends();
};


な感じ。callbackはここでは実行せずcallbackIdStoreに入れておく。
親フレームでダイアログ表示後、「送信」ボタンが押下されたときに、
callbackを実行する。callbackではダイアログで選択された友達のID一覧を
受け取り、messages.modifyを発行する。
このcallbackは、親フレームからのクロスドメイン通信により、requestShareAppCallback_がコールされたときにコールされる。

callbackをつくり終わったら、友達一覧を取得する。
これは親フレームで表示するダイアログに友達一覧として出力するため。

で、友達一覧を取得し終わったら、
gadgets.rpc.callで親フレームのrequestShareAppをコールする。
次は親フレームのrequestShareApp。

gadgets.IfrGadgetService.prototype.requestShareApp = function(rpc, callbackId, friends, body) {
if (!gadgets.container.gadgetService.shareAppDialog_) {
return;
}
var title = gadgets.container.getGadget(this.getGadgetIdFromModuleId(rpc.f))
.title + 'はお勧めだよ!';
var shareAppDialog = gadgets.container.gadgetService.shareAppDialog_;
var onSubmit = function() {
var friendsIds = this.getData().shareAppDialog_friendsId;
var recipients = [];
if (typeof friendsIds === 'boolean') {
if (friendsIds) {
recipients = [friends[0].id];
}
}
else {
var len = friendsIds.length;
for (var ii=0; ii<len; ii++) {
if (friendsIds[ii]) {
recipients.push(friends[ii].id);
}
}
}
if (callbackId) {
window.setTimeout(function() {
gadgets.rpc.call(rpc.f,
'shindig.requestShareApp_callback',
null,
callbackId,
true,
recipients,
title,
body);
}, 0);
}
this.cancel();
};
var onCancel = function() {
if (callbackId) {
window.setTimeout(function() {
gadgets.rpc.call(rpc.f,
'shindig.requestShareApp_callback',
null,
callbackId,
false,
[],
title,
body);
}, 0);
}
this.cancel();
};
document.getElementById('shareAppDialog_title').innerHTML = title;
document.getElementById('shareAppDialog_body').innerHTML = body;
var ul = document.createElement('ul');
var fc = 0;
document.getElementById('shareAppDialog_friends').innerHTML = '';
for (xx in friends) {
var li = document.createElement('li');
li.innerHTML = ''
+ ''
+ '';
ul.appendChild(li);
fc++;
}
if (fc == 0) {
document.getElementById('shareAppDialog_friends').innerHTML = 'ひとりぼっちだよ';
}
else {
document.getElementById('shareAppDialog_friends').appendChild(ul);
}

shareAppDialog.setHeader('確認');
shareAppDialog.cfg.queueProperty("icon",YAHOO.widget.SimpleDialog.ICON_WARN);
shareAppDialog.cfg.queueProperty("buttons", [
{text: "送信", handler: onSubmit, isDefault: true},
{text: "キャンセル", handler: onCancel}
]);
shareAppDialog.registerForm();
shareAppDialog.render();
shareAppDialog.show();
};


とりあえず動かしたかったのでfiles/container/gadgets.jsに追加した。
ガジェット側フレームのrequestShareAppから渡された友達一覧を、
ダイアログに展開し、ダイアログを表示する。
「送信」ボタンが押下されたら、選択された友達のIDを配列にして、
ガジェット側フレームワークへクロスドメイン間通信により、渡す。


次に、ガジェット側requestShareApp_callback。
これはまた戻ってきてjsonrpccontainer.jsに記述した。

JsonRpcContainer.requestShareAppCallback_ = function(callbackId,
success, recipientIds, title, body) {
callback = callbackIdStore[callbackId];
if (callback && success) {
callbackIdStore[callbackId] = null;
callback(success, recipientIds, title, body);
}
};


こんだけ。
Shindigのデフォルト状態からちょっと修正。
requestShareAppで登録されたコールバックをコールするだけ。

これでサーバ側へmessages.modifyが発行される。

次にサーバ側。
サーバ側はrequestSendMessageを実装してみたときのまま。


で、実行すると、DBに登録された。

ちなみにDialogはYUIを使用。

そんだけ。
.

0 コメント: