メモ代わり。てきとーに。 いや、ですからてきとーですって。 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を定義。(前やったけどやりなおし。)

  1. JsonRpcContainer.prototype.requestShareApp = function(recipientIds, reason,  
  2.      opt_callback, opt_params) {  
  3.    var callbackId = "cId_" + Math.random();  
  4.   
  5.    var self = this;  
  6.    var callback = function(success, recip, title, body) {  
  7.      var req = opensocial.newDataRequest();  
  8.      var viewer = new opensocial.IdSpec({'userId' : 'VIEWER'});  
  9.      var rpc = { method : "messages.modify" };  
  10.      rpc.params = self.translateIdSpec(viewer);  
  11.      rpc.params.appId = "@app";  
  12.   
  13.      FieldTranslations.translateNetworkDistance(viewer, rpc.params);  
  14.   
  15.      rpc.params.msgCollId = 'shareApp';  
  16.      rpc.params.entity = {};  
  17.      rpc.params.entity["title"] = title;  
  18.      rpc.params.entity["body"]  = body;  
  19.      rpc.params.entity["recipients"] = recip  
  20.   
  21.      var shareAppRequest = new JsonRpcRequestItem(rpc);  
  22.   
  23.      req.add(shareAppRequest, 'key');  
  24.      req.send(function(response) {  
  25.         opt_callback(response.get('key'));  
  26.      });  
  27.    };  
  28.    callbackIdStore[callbackId] = callback;  
  29.   
  30.    var body = gadgets.util.unescapeString(reason.getField(  
  31.        opensocial.Message.Field.BODY));  
  32.   
  33.    if (!body || body.length === 0) {  
  34.      var bodyMsgKey = gadgets.util.unescapeString(reason.getField(  
  35.        opensocial.Message.Field.BODY_ID));  
  36.      body = gadgets.Prefs.getMsg(bodyMsgKey);  
  37.    }  
  38.   
  39.    /* 修正ここから */  
  40.    /* 友達一覧を取得する */  
  41.    var friendsArray = [];  
  42.    var handleGetFriends = function(data) {  
  43.      var friends = data.get("get_friends");  
  44.      if (friends.hadError()) {  
  45.        return;  
  46.      }  
  47.      var data = friends.getData();  
  48.      data.each(function(friend) {  
  49.        var tmp = {};  
  50.        tmp.thumbnailUrl = friend.getField(opensocial.Person.Field.THUMBNAIL_URL);  
  51.        tmp.nickname     = friend.getField(opensocial.Person.Field.NICKNAME     );  
  52.        tmp.id           = friend.getField(opensocial.Person.Field.ID           );  
  53.        friendsArray.push(tmp);  
  54.      });  
  55.      gadgets.rpc.call('..''shindig.requestShareApp',  
  56.          null,  
  57.          callbackId,  
  58.          friendsArray,  
  59.          body);  
  60.    };  
  61.    var getfriends = function() {  
  62.      var params = {};  
  63.      params[opensocial.DataRequest.PeopleRequestFields.PROFILE_DETAILS] = [  
  64.        opensocial.Person.Field.ID,  
  65.        opensocial.Person.Field.NICKNAME,  
  66.        opensocial.Person.Field.THUMBNAIL_URL,  
  67.        opensocial.Person.Field.PROFILE_URL  
  68.      ];  
  69.      var req = opensocial.newDataRequest();  
  70.      var idSpecParam = {};  
  71.      idSpecParam[opensocial.IdSpec.Field.USER_ID]  = opensocial.IdSpec.PersonId.VIEWER;  
  72.      idSpecParam[opensocial.IdSpec.Field.GROUP_ID] = opensocial.IdSpec.GroupId.FRIENDS;  
  73.      var idSpec = opensocial.newIdSpec(idSpecParam);  
  74.   
  75.      req.add(req.newFetchPeopleRequest(idSpec, params), "get_friends");  
  76.      req.send(handleGetFriends);  
  77.    };  
  78.    getfriends();  
  79.  };  

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

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

で、友達一覧を取得し終わったら、
gadgets.rpc.callで親フレームのrequestShareAppをコールする。
次は親フレームのrequestShareApp。
  1. gadgets.IfrGadgetService.prototype.requestShareApp = function(rpc, callbackId, friends, body) {  
  2.   if (!gadgets.container.gadgetService.shareAppDialog_) {  
  3.     return;  
  4.   }  
  5.   var title = gadgets.container.getGadget(this.getGadgetIdFromModuleId(rpc.f))  
  6.     .title + 'はお勧めだよ!';  
  7.   var shareAppDialog = gadgets.container.gadgetService.shareAppDialog_;  
  8.   var onSubmit = function() {  
  9.     var friendsIds = this.getData().shareAppDialog_friendsId;  
  10.     var recipients = [];  
  11.     if (typeof friendsIds === 'boolean') {  
  12.       if (friendsIds) {  
  13.         recipients = [friends[0].id];  
  14.       }  
  15.     }  
  16.     else {  
  17.       var len = friendsIds.length;  
  18.       for (var ii=0; ii<len; ii++) {  
  19.         if (friendsIds[ii]) {  
  20.           recipients.push(friends[ii].id);  
  21.         }  
  22.       }  
  23.     }  
  24.     if (callbackId) {  
  25.       window.setTimeout(function() {  
  26.         gadgets.rpc.call(rpc.f,  
  27.                          'shindig.requestShareApp_callback',  
  28.                          null,  
  29.                          callbackId,  
  30.                          true,  
  31.                          recipients,  
  32.                          title,  
  33.                          body);  
  34.       }, 0);  
  35.     }  
  36.     this.cancel();  
  37.   };  
  38.   var onCancel = function() {  
  39.     if (callbackId) {  
  40.       window.setTimeout(function() {  
  41.         gadgets.rpc.call(rpc.f,  
  42.                          'shindig.requestShareApp_callback',  
  43.                          null,  
  44.                          callbackId,  
  45.                          false,  
  46.                          [],  
  47.                          title,  
  48.                          body);  
  49.       }, 0);  
  50.     }  
  51.     this.cancel();  
  52.   };  
  53.   document.getElementById('shareAppDialog_title').innerHTML = title;  
  54.   document.getElementById('shareAppDialog_body').innerHTML = body;  
  55.   var ul = document.createElement('ul');  
  56.   var fc = 0;  
  57.   document.getElementById('shareAppDialog_friends').innerHTML = '';  
  58.   for (xx in friends) {  
  59.     var li = document.createElement('li');  
  60.     li.innerHTML = '<label>' + friends[xx].id + 'さん</label>'  
  61.       + '<img src="' + friends[xx].thumbnailUrl + '">'  
  62.       + '<input type="checkbox" name="shareAppDialog_friendsId" value="' + friends[xx].id + '">';  
  63.     ul.appendChild(li);  
  64.     fc++;  
  65.   }  
  66.   if (fc == 0) {  
  67.     document.getElementById('shareAppDialog_friends').innerHTML = 'ひとりぼっちだよ';  
  68.   }  
  69.   else {  
  70.     document.getElementById('shareAppDialog_friends').appendChild(ul);  
  71.   }  
  72.   
  73.   shareAppDialog.setHeader('確認');  
  74.   shareAppDialog.cfg.queueProperty("icon",YAHOO.widget.SimpleDialog.ICON_WARN);  
  75.   shareAppDialog.cfg.queueProperty("buttons", [  
  76.     {text: "送信", handler: onSubmit, isDefault: true},  
  77.     {text: "キャンセル", handler: onCancel}  
  78.   ]);  
  79.   shareAppDialog.registerForm();  
  80.   shareAppDialog.render();  
  81.   shareAppDialog.show();  
  82. };  

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


次に、ガジェット側requestShareApp_callback。
これはまた戻ってきてjsonrpccontainer.jsに記述した。
  1. JsonRpcContainer.requestShareAppCallback_ = function(callbackId,  
  2.     success, recipientIds, title, body) {  
  3.   callback = callbackIdStore[callbackId];  
  4.   if (callback && success) {  
  5.     callbackIdStore[callbackId] = null;  
  6.     callback(success, recipientIds, title, body);  
  7.   }  
  8. };  

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

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

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


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

ちなみにDialogはYUIを使用。

そんだけ。
.

0 コメント: