opensocial.requestSendMessageの実装をしてみる。
とりあえず、JavaScript。
方針
ざっと実装方針。
GadgetXML内でrequestSendMessageがコールされると、
ダイアログが出て、送信していいか確認する。
確認後、message.postmessages.createを発行する。
ってな感じ。
ダイアログはYUIをしてみる。
ガジェットXML
ガジェットXMLはこんな感じ。
- <?xml version="1.0" encoding="UTF-8" ?>
- <Module>
- <ModulePrefs title="opensocial.Message">
- <Require feature="opensocial-0.8" />
- </ModulePrefs>
- <Content type="html" view="home,profile,canvas">
- <![CDATA[
- <script type="text/javascript">
- function sendMessage() {
- var opt_params = [];
- opt_params[opensocial.Message.Field.TITLE] = 'タイトルだよーん';
- opt_params[opensocial.Message.Field.TYPE] = opensocial.Message.Type.PRIVATE_MESSAGE;
- var body = 'テストメッセージだよーん';
- var msg = opensocial.newMessage(body, opt_params);
- opensocial.requestSendMessage(opensocial.IdSpec.PersonId.OWNER, msg, call_back);
- }
- function call_back(status) {
- if (status.hadError()) {
- document.getElementById('result').innerHTML = '失敗したよ:' + status.getErrorCode();
- } else {
- document.getElementById('result').innerHTML = '送ったよ';
- }
- }
- </script>
- <div id="result"></div>
- <input type="button" value="メッセージ送信" onclick="sendMessage();" />
- ]]>
- </Content>
- </Module>
TITLEとBODYをセットしてrequestSendMessageをコールするだけ。
サーバ側ContainerのJavaScript
さて、1.1-SNAPSHOTのデフォルトだとrequestSendMessageは、NOTIMPLEMENTを返すだけ
なんだけど、どうも動作しない。
動作しないものはほっといて、jsonrpccontainer.jsなどをいじくってみる。
以下いじった結果。
GadgetからrequestSendMessageがコールされると、jsonrpccontainer.jsの
requestSendMessageが呼ばれるようにする。
Gadgetはiframeの中にいて、jsonrpccontainer.jsも同じiframeの中にいる。
jsonrpccontainer.jsのrequestSendMessageは、ダイアログを出すために、
iframeの親のrequestSendMessageをコールする。ここでgadgets.rpcを使用する。
親のrequestSendMessageではYUIのダイアログを表示後、OKを押下されたなら、
今度はiframeの方のrequestSendMessageCallback_関数をコールする。
ここでもgadgets.rpcを使用。
ということで、まずjsonrpccontainer.jsのrequestSendMessage。
- JsonRpcContainer.prototype.requestSendMessage = function(recipientIds, message, opt_callback, opt_params) {
- opt_callback = opt_callback || function(){};
- opt_params = opt_params || {}; /* 使わないよ */
- var body = gadgets.util.unescapeString(message.getField(
- opensocial.Message.Field.BODY));
- var title = gadgets.util.unescapeString(message.getField(
- opensocial.Message.Field.TITLE));
- if (!body || body.length === 0) {
- var bodyMsgKey = gadgets.util.unescapeString(message.getField(
- opensocial.Message.Field.BODY_ID));
- body = gadgets.Prefs.getMsg(bodyMsgKey);
- }
- if (!title || title.length === 0) {
- var titleMsgKey = gadgets.util.unescapeString(message.getField(
- opensocial.Message.Field.TITLE_ID));
- title = gadgets.Prefs.getMsg(titleMsgKey);
- }
- var self = this;
- var callback = function() {
- var req = opensocial.newDataRequest();
- var viewer = new opensocial.IdSpec({'userId' : 'VIEWER'});
- var rpc = { method : "messages.create" };
- rpc.params = self.translateIdSpec(viewer);
- rpc.params.appId = "@app";
- FieldTranslations.translateNetworkDistance(viewer, rpc.params);
- /* ここから、とりあえず版。後でちゃんとする */
- rpc.params.message = {};
- rpc.params.message["title"] = title;
- rpc.params.message["body"] = body;
- rpc.params.message["recipients"] = self.translateIdSpec(self.makeIdSpec(recipientIds))["userId"];
- /* ここまで、とりあえず版。後でちゃんとする */
- var messageRequest = new JsonRpcRequestItem(rpc);
- req.add(messageRequest, 'key');
- req.send(function(response) {
- opt_callback(response.get('key'));
- });
- };
- var callbackId = "cId_" + Math.random();
- callbackIdStore[callbackId] = callback;
- gadgets.rpc.call(null, 'requestSendMessage',
- null,
- callbackId,
- recipientIds,
- title,
- body);
- };
callbackIdStoreにcallbackを入れておきたいので、
callbackIdStoreが定義されている、
- (function() {
- })();
の中に定義。
実際にサーバにデータを送信するコードをコールバックとして生成し、
gadgets.rpc.callを読んで親の'requestSendMessage'をコールする。
ちなみに、gadgets.rpc.callの第一引数がnullになっているが、
これは親(というか'..'というかルートというか)
という意味。
で、クロスドメイン間通信で親'requestSendMessage'がコールされると。
で以下親の方のrequestSendMessage。
- gadgets.IfrGadgetService.prototype.requestSendMessage = function(rpc, callbackId, recipients, title, body) {
- if (gadgets.container.gadgetService.sendMessageDialog_) {
- /* 以下YUI前提 */
- var onSubmit = function() {
- if (callbackId) {
- window.setTimeout(function() {
- gadgets.rpc.call(rpc.f, 'requestSendMessage_callback', null, callbackId, recipients, title, body);
- }, 0);
- }
- this.cancel();
- };
- var onCancel = function() {
- this.cancel();
- };
- gadgets.container.gadgetService.sendMessageDialog_.cfg.queueProperty("buttons", [
- {text: "OK", handler: onSubmit, isDefault: true},
- {text: "キャンセル", handler: onCancel}
- ]);
- document.getElementById('sendMessageDialog_title').innerHTML = title;
- document.getElementById('sendMessageDialog_body').innerHTML = body;
- gadgets.container.gadgetService.sendMessageDialog_.render();
- gadgets.container.gadgetService.sendMessageDialog_.show();
- }
- else {
- if (callbackId) {
- window.setTimeout(function() {
- gadgets.rpc.call(rpc.f, 'requestSendMessage_callback', null, callbackId, recipients, title, body);
- }, 0);
- }
- }
- };
な感じ。
多分これじゃだめで、jsonrpccontainer.jsのrequestSendMessageをコールした際に
積み上げたcallbackIdStoreをクリアさせなきゃいけない。
とりあえず、おいといて、
gadgets.container.gadgetService.sendMessageDialog_
というのはYUIのダイアログ。
"OK"ボタンが押下されると、
- gadgets.rpc.call(rpc.f, 'requestSendMessage_callback', null, callbackId, recipients, title, body);
がコール。
gadgets.rpc.callの第一引数にrpc.fが指定されているが、これは
呼び出し元のwindow.nameが入っている。
意味的には、gadgetの'requestSendMessage_callback'をコールせよ、といった感じか。
gadgets.IfrGadgetService.prototype.requestSendMessage
のパラメータはGadget内でのgadgets.rpc.call時と違うんだけど、これは
- gadgets.rpc.register('requestSendMessage', function(callbackId, recipients, title, body) {
- self.requestSendMessage.apply(self, [this, callbackId, recipients, title, body]);
- });
と定義したから。
第一引数に呼び出し元を判断するために、rpcがわたるようになっている。
でrequestSendMessage_callbackは、、
JsonRpcContainer.requestSendMessageCallback_ = function(callbackId, recipients, title, body) {
var callback = callbackIdStore[callbackId];
if (callback) {
callbackIdStore[callbackId] = null;
callback();
}
};
こんだけ。で完了。
で実行してみると、サーバ側にリクエストが飛ぶ。
今はまだサーバ側の実装はしていないので、
org.apache.shindig.protocol.ProtocolException: The method message.post is not implemented
at jp.qsdn.gms.social.protocol.SpringHandlerRegistry.getRpcHandler(SpringHandlerRegistry.java:137)
ってなExceptionが出ている。
message.postというものをハンドラから実装してみる。
messages.createが正解。ハンドらから実装する必要なかった。。
ちなみに、
"message.post"という文字列などは、
http://www.mail-archive.com/shindig-dev@incubator.apache.org/msg08286.html
を参考にした。
--
間違えた。
message.postじゃなくて、messages.post。
0.8.1じゃなく、Apache Shindig-1.0とのこと。
OpenSocialの仕様にはsendしかないらしい。
--
さらに間違えた。
messages.postじゃなくて、messages.create。
.
0 コメント:
コメントを投稿