GoogleReaderAPIを使って広告を非表示にしよう!

GoogleReaderAPIを使って広告を非表示にしよう!

  • このエントリーをはてなブックマークに追加

はじめまして、新規事業推進部のセイカイです。
最近猫を飼い始めて幸せな毎日です。

さて、自分は日々の情報収集にGoogleリーダーを使っていますが、広告が結構入ってきて若干鬱陶しいなと思う今日この頃です。
邪魔なものは消してしまえば良いよねというこで、「PR:」「AD:」という文言を拾って全部既読にしちゃいましょう。
デフォルトの機能ではフィルタ等は無いようなので、API経由でなんとかします。

流れとしては

  1. ClientLoginしてAuthキーを取得します
  2. Feedを検索して該当するIDの一覧を取得します
  3. 編集用のTokenを取得します
  4. 該当IDのエントリーを既読にします

GoogleReaderのAPI仕様に関しては、下記などが参考になるかと思います

そんなこんなで、なんとなくコードを書いてみました。
gitに公開されているgooglereaderが環境的に上手く動かなかったので、参考にしつつ必要な部分だけの実装です。
普段Rubyは書かないので、コード的にアレなのは大目に見て下さい。

続きを読む

実装

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>]
}

※例外などは処理していませんので必要に応じて追加する必要があります。
あとはバッチなどで数時間おきに回せば、快適なFeed閲覧ができますね。
ということで、とりあえず猫の写真貼っときます。

ではでは、またの機会に

  • このエントリーをはてなブックマークに追加

記事作成者の紹介

セイカイ(フロントエンジニア)

新規事業推進部のセイカイです。猫を飼い始めて幸せな毎日を送っています。

関連するSONICMOOVのサービス

フロントエンドエンジニア募集中!

×

SNSでも情報配信中!ぜひご登録ください。

×

SNSでも
情報配信中!
SONICMOOV Facebookページ SONICMOOV Twitter
フロントエンドエンジニア募集中!

新着の記事

mautic is open source marketing automation