GoogleReaderAPIを使って広告を非表示にしよう!
はじめまして、新規事業推進部のセイカイです。
最近猫を飼い始めて幸せな毎日です。
さて、自分は日々の情報収集にGoogleリーダーを使っていますが、広告が結構入ってきて若干鬱陶しいなと思う今日この頃です。
邪魔なものは消してしまえば良いよねというこで、「PR:」「AD:」という文言を拾って全部既読にしちゃいましょう。
デフォルトの機能ではフィルタ等は無いようなので、API経由でなんとかします。
流れとしては
- ClientLoginしてAuthキーを取得します
- Feedを検索して該当するIDの一覧を取得します
- 編集用のTokenを取得します
- 該当IDのエントリーを既読にします
GoogleReaderのAPI仕様に関しては、下記などが参考になるかと思います
- 原文:http://code.google.com/p/pyrfeed/wiki/GoogleReaderAPI
- 翻訳:http://colo-ri.jp/develop/2009/12/google-reader-apiapi.html
そんなこんなで、なんとなくコードを書いてみました。
gitに公開されているgooglereaderが環境的に上手く動かなかったので、参考にしつつ必要な部分だけの実装です。
普段Rubyは書かないので、コード的にアレなのは大目に見て下さい。
続きを読む
実装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
[sourcecode lang="text"] require <span style="color: #009900;">'uri'</span> require <span style="color: #009900;">'net/https'</span> require <span style="color: #009900;">'net/http'</span> require <span style="color: #009900;">'rubygems'</span> require <span style="color: #009900;">'json'</span> <span style="color: #000099;">class</span> GoogleReader URL = <span style="color: #009900;">'http://www.google.com'</span> LOGIN_URL = <span style="color: #009900;">'https://www.google.com:443/accounts/ClientLogin'</span> READER_URL = URL + <span style="color: #009900;">'/reader/api/0'</span> TOKEN_URL = READER_URL + <span style="color: #009900;">'/token'</span> SEARCH_IDS_URL = READER_URL + <span style="color: #009900;">'/search/items/ids'</span> EDIT_TAG_URL = READER_URL + <span style="color: #009900;">'/edit-tag'</span> <span style="color: #000099;">def</span> initialize(account, password) authenticate account, password <span style="color: #000099;">end</span> <span style="color: #990000;"># GoogleReaderにログインして認証キーを取得</span> <span style="color: #000099;">def</span> authenticate(account, password) response = request <span style="color: #009900;">'post'</span>, LOGIN_URL, :form_data =&gt; { <span style="color: #009900;">'service'</span> =&gt; <span style="color: #009900;">'reader'</span>, <span style="color: #009900;">'source'</span> =&gt; <span style="color: #009900;">'googlereader.rb/0.1'</span>, <span style="color: #009900;">'Email'</span> =&gt; account, <span style="color: #009900;">'Passwd'</span> =&gt; password, <span style="color: #009900;">'continue'</span> =&gt; URL, } m = /Auth=(.*)/i.match(response) @auth = m ? m[<span style="color: #009900;">1</span>] : <span style="color: #000099;">nil</span> <span style="color: #000099;">end</span> <span style="color: #990000;"># 編集用のトークンを取得</span> <span style="color: #000099;">def</span> token <span style="color: #000099;">if</span> @token == <span style="color: #000099;">nil</span> response = request(<span style="color: #009900;">'get'</span>, TOKEN_URL) @token = response <span style="color: #000099;">end</span> @token <span style="color: #000099;">end</span> <span style="color: #990000;">#Feedの検索</span> <span style="color: #000099;">def</span> search(keyword, num=<span style="color: #009900;">1000</span>) response = request <span style="color: #009900;">'get'</span>, SEARCH_IDS_URL, :query_hash =&gt; { <span style="color: #009900;">'num'</span> =&gt; num, <span style="color: #009900;">'output'</span> =&gt; <span style="color: #009900;">'json'</span>, <span style="color: #009900;">'q'</span> =&gt; keyword, } JSON.parse(response)[<span style="color: #009900;">'results'</span>] <span style="color: #000099;">end</span> <span style="color: #990000;">#既読にする</span> <span style="color: #000099;">def</span> mark_read(id) request <span style="color: #009900;">'post'</span>, EDIT_TAG_URL, :form_data =&gt; { <span style="color: #009900;">'T'</span> =&gt; @token, <span style="color: #009900;">'i'</span> =&gt; id, <span style="color: #009900;">'a'</span> =&gt; <span style="color: #009900;">'user/-/state/com.google/read'</span> } <span style="color: #000099;">end</span> <span style="color: #000099;">def</span> request(method, url, o={}) options = { :form_data =&gt; <span style="color: #000099;">nil</span>, :query_hash =&gt; <span style="color: #000099;">nil</span>, :qsi =&gt; <span style="color: #009900;">'?'</span> }.merge(o) url += hash_to_query_string(options[:query_hash], options[:qsi]) <span style="color: #000099;">unless</span> options[:query_hash].nil? url = URI.parse(URI.escape(url)) <span style="color: #000099;">if</span> @auth != <span style="color: #000099;">nil</span> headers = { <span style="color: #009900;">'Authorization'</span> =&gt; <span style="color: #009900;">"GoogleLogin auth=#{@auth}"</span>, } <span style="color: #000099;">end</span> req = <span style="color: #000099;">if</span> method == <span style="color: #009900;">'post'</span> Net::HTTP::Post.new(url.request_uri, headers) <span style="color: #000099;">else</span> Net::HTTP::Get.new(url.request_uri, headers) <span style="color: #000099;">end</span> req.set_form_data(options[:form_data]) <span style="color: #000099;">if</span> options[:form_data] http = Net::HTTP.new(url.host, url.port) http.use_ssl = <span style="color: #000099;">true</span> <span style="color: #000099;">if</span> url.port == <span style="color: #009900;">443</span> result = http.start() { |conn| conn.request(req) } <span style="color: #000099;">return</span> result.body <span style="color: #000099;">end</span> <span style="color: #000099;">def</span> hash_to_query_string(hash, initial_value=<span style="color: #009900;">"?"</span>) hash.inject(initial_value) { |qs, h| qs += <span style="color: #009900;">"#{h[0]}=#{h[1]}&amp;"</span> qs } <span style="color: #000099;">end</span> <span style="color: #000099;">end</span> reader = GoogleReader.new(<span style="color: #009900;">'your_email'</span>, <span style="color: #009900;">'your_password'</span>) <span style="color: #990000;">#100件の該当エントリーIDを取得して既読にする</span> reader.search(<span style="color: #009900;">'PR:'</span>, <span style="color: #009900;">100</span>).each { |res| reader.mark_read res[<span style="color: #009900;">'id'</span>] } [/sourcecode] |
※例外などは処理していませんので必要に応じて追加する必要があります。
あとはバッチなどで数時間おきに回せば、快適なFeed閲覧ができますね。
ということで、とりあえず猫の写真貼っときます。
ではでは、またの機会に