読者です 読者をやめる 読者になる 読者になる

めも帖

「めも帖」代わりにダラダラと書いていったり、めもしたりしているだけです。

ChatWorkの未読数を表示するChromeの拡張機能を作ってみた

Chrome拡張機能

ChatWork を使い始めました。通知に関するところが気になり、Chrome 拡張機能を作ってみる事にしました。

ChatWork の通知方法

Skypeや、GoogleTalk(Hangout)とは異なり、メッセージごとに、Chrome からの通知がされます*1。設定で通知を自分宛(To)だけにすることもできるんですが、Toが使われていないと通知されません(設定通りなんですけれど)。

まとめると

  • 席を離れていると通知されない(Windowsだけかも?)
  • 全部通知か、自分だけかの二択
    • チャットルームへの参加が増えるとどうなるのか?
    • 例えば、リリース用のチャットに参加してて、リリースに関係ない時は、リリース時に大量の通知がくる

という感じです。 そこで、ChatWorkからの通知は、自分宛(To)だけにして、それ以外はChrome上に未読数をだしてやれば、いいんじゃないか?と思いました。未読数がわかれば、読みにいけばいいし、Toが来ているなら、自分宛なのが明確です。

作るときの課題

APIの利用

API 利用の申請

ChatWorkは、APIを申請すると利用できます。KDDIのだとまた違うみたいですが、普通のアカウントだとちょっと時間がかかります。

認証

OAuth かなあ...と思ったら、HTTPリクエストヘッダ に書け、ということでした。そんなことJavaScriptで出来るの?と思ったら、Chrome 拡張機能APIには書き換えの機能がありました。便利。気になるのは、OAuth 2.0 の提供予定と書かれているのですが、今後はどうなるんでしょうか?(もう、だいぶ更新されていない)

Chrome 拡張機能でのjsonの取得とパース

jsonでデーターの取得…って、クロスサイトだから...と思ったんですが、拡張機能は大丈夫でした。jsonpじゃなくてもいいのか…

json のパース

jQuery じゃなくて、JSON オブジェクトを利用します。ふと、気づいたんですが、これってECMAScript由来なんでしょうか?

数値の表示方法

赤い背景色に白文字の数字は、Chrome 拡張機能API がありました。HTML で書くのか?と思ったんですがらくちん。

定期処理

だいたい、「Backgournd は使うな Event Pages(https://developer.chrome.com/extensions/event_pages)を使え」とあります。でも、ChatWork のhttpヘッダーでのAPIキー送信の認証のためには使う必要があり、Background ページでsetInterval() を利用することになります。

setInterval()

はまりどころでした。こんな感じに書いたら動きませんでした。

function foo(){
     console.log("foo");
}

setInterval(foo(), 1000);

動いたのはこっち

setInterval(function(){
     console.log("foo");

}, 1000);

出来上がり

f:id:d4-1977:20140730013125p:plain

作ってみて

API トークンを保存する機能とか作れば汎用的になるんだと思います。ただ、今はこれでもいいかな...と思っています。作る気力が湧かない、というのが正しいかも。というのも、API トークンを発行するのに手間なので、使う人が限られそう、と思ってしまったから。

書籍

自分がいなくてもうまくいく仕組み

自分がいなくてもうまくいく仕組み

ソース

manifest.json

{
  "name": "ChatWork_Checker",
  "version": "0.0.1",
  "manifest_version": 2,
"content_security_policy": "script-src 'self'; object-src 'self'",
  "description": "ChatWork の拡張機能です",
  "author": "Your name",
  "background": {
    "scripts": ["background.js"]
  },
    
  //"permissions": ["tabs", "http://*/*", "https://*/*"],
  //"permissions": ["webRequest", "*://*.chatwork.com/*", "http://*/*"],
"permissions": ["webRequest", "webRequestBlocking", "http://*/", "https://*/"],

  "content_scripts": [
    {
      "matches": ["http://*/*", "https://*/*", "<all_urls>"],
      "js": ["jquery.min.js"],
      "run_at": "document_end"
    }
  ],

  "browser_action": {
    "default_icon": "icon.png",
"name": "This is Badge Sample"
  }
}

background.js

setInterval(function(){
     var count = 0;
     var api_token    = ’foobar';
     var api_base_url = 'https://api.chatwork.com/v1';
    
     //
     var endpoint_url = api_base_url + '/my/status';

     // 認証処理
     chrome.webRequest.onBeforeSendHeaders.addListener(
          function(details){
               details.requestHeaders.push({
                    name: "X-ChatWorkToken",
                    value: api_token
               });
    
               return {requestHeaders:details.requestHeaders};
          },
          {
               urls: ["<all_urls>"],
               types: ["main_frame", "xmlhttprequest"]
          },
          [
               "requestHeaders", "blocking"
          ]
     );
    
    
     //
     var xhr = new XMLHttpRequest();
     xhr.open('GET', endpoint_url, true);
     xhr.onload = function(e) {
          console.log('成功');
     };
     xhr.send();
    
     xhr.onreadystatechange = function() {
          if (xhr.readyState == 4) {
                // JSON.parse であれば、スクリプトは実行されない
               var resp = JSON.parse(xhr.responseText);
               console.log(resp);
    
               if(resp.unread_num > 0)
               {
                    count = resp.unread_num;
               }
    
               if( count > 0)
               {
                    chrome.browserAction.setBadgeText({text:String(count)});
               }
          }
     }
    

},5000);

*1:Chrome のデスクトップ通知は、Googleの部分と、WebKitのことがあったりでよくわかっておりません