今回はDMM.com 金沢事業所をお借りして開催!
kzrb.doorkeeper.jp
当初は自分含めて2人しか参加表明してなくて不安でしたが最終的には11人の参加になりました。わいわい。
Scala関西Summit 2018に行ってきた話
www.blogaomu.com
↑の話をベースに写真も追加したスライドを作って発表しました。コンセプトとしてはScala関西Summitに行った気になれる、だったんですが、いろいろ詰め込みすぎてだいぶ時間を取ってしまいました(すいません)。Scalaは可愛いを広めることができてよかったです。
Bufferを操作する
Kanazawa.rb告知用のSNS投稿をBufferで行っているとのことで、これをCLIでやれたらいろいろ捗るのでは?という考えから今回のもくもくタイムではBuffer APIを触ってみました。
APIを触る前にBuffer自体を使ったことが無かったのでアカウントを作っていろいろ試して概念を理解するところから始めました。
- 1アカウントに対して複数のSNSアカウントをひもづけられる。ひもづいたSNSアカウントのことをProfileと呼んでいる
- 投稿はQueueというものに格納され、特定の時刻になったらSNSアカウントを通して接続先のSNSに投稿される
- 投稿時にQueueに入れる(Add to Queue)、即時にSNS投稿する(Share now)、任意の日時に投稿する(Schedule post)、の3つから選択できる
- Queueに入った投稿は1件ずつ時刻(Posting times)が割り振られ、その時刻になると接続先のSNSに投稿される
投稿に関する概念はざっとこんな感じだと思います。詳しくはこの辺を見ると良さそう。 Managing your Queue - Buffer FAQ
概念を理解したところで、プログラムからBuffer APIを呼ぶ場合には公式のgemがあるのでこれを利用すると良さげです。
github.com
Buffer APIを利用する場合、先にアプリケーションの登録をサイト上で行う必要があります。画面に従って入力していけばOKです。ここで発行されたAccess tokenを使用します。
buffer.com
先ほど発行されたAccess tokenを環境変数 BUFFER_ACCESS_TOKEN
に入れておいて、replでいろいろ操作してみます。
> require 'buffer'
> client = Buffer::Client.new(ENV['BUFFER_ACCESS_TOKEN'])
> profiles = client.profiles
=> [{"_id"=>"5bef956a4b1be7784607d225",
"avatar"=>
"http://pbs.twimg.com/profile_images/835761987728502784/QMKQ3UYI_normal.jpg",
"avatar_https"=>
"https://pbs.twimg.com/profile_images/835761987728502784/QMKQ3UYI_normal.jpg",
"can_see_content_library"=>false,
"counts"=>
{"sent"=>4, "drafts"=>0, "daily_suggestions"=>25, "reminders"=>0, "pending"=>0},
"cover_photo"=>
"https://d3ijcis4e2ziok.cloudfront.net/default-cover-photos/blurry-blue-background-iii_facebook_timeline_cover.jpg",
"created_at"=>1542428010,
"default"=>true,
"disabled"=>false,
"disabled_features"=>[],
"disconnected"=>false,
"formatted_service"=>"Twitter",
"formatted_username"=>"@TAKAyuki_atkwsk",
"id"=>"5bef956a4b1be7784607d225",
"is_analyze_enabled"=>false,
"is_on_business_v2"=>false,
"locked"=>false,
"paused"=>false,
"paused_schedules"=>[],
"preferences"=>{},
"reports_logo"=>nil,
"schedules"=>
[{"days"=>["sun"], "times"=>["09:55", "14:25", "16:44", "19:32"]},
{"days"=>["mon"], "times"=>["09:55", "14:25", "16:44", "19:32"]},
{"days"=>["tue"], "times"=>["09:55", "14:25", "16:44", "19:32"]},
{"days"=>["wed"], "times"=>["09:55", "14:25", "16:44", "19:32"]},
{"days"=>["thu"], "times"=>["09:55", "14:25", "16:44", "19:32"]},
{"days"=>["fri"], "times"=>["09:55", "14:25", "16:44", "19:32"]},
{"days"=>["sat"], "times"=>["09:55", "14:25", "16:44", "19:32"]}],
"service"=>"twitter",
"service_id"=>"77184067",
"service_type"=>"profile",
"service_username"=>"TAKAyuki_atkwsk",
"shortener"=>{"domain"=>"buff.ly"},
"statistics"=>{"followers"=>785},
"timezone"=>"Asia/Tokyo",
"timezone_city"=>"Tokyo - Asia",
"user_id"=>"5bef953a4b1be777074c2b05",
"utm_tracking"=>"disabled",
"verb"=>"tweet"},
...]
> client.create_update(
* body: {
* text: 'お腹吹田',
* profile_ids: [profiles.find {|profile| profile.service == "twitter" }.id],
* }
* )
=> {"updates"=>
[{"_id"=>"5befaff6dd5072291b2a9b93",
"client_id"=>"5befa27c4b1be72ec04037b3",
"created_at"=>1542434806,
"day"=>"Today",
"due_at"=>1542450720,
"due_time"=>"7:32 pm",
"id"=>"5befaff6dd5072291b2a9b93",
"is_video_processing"=>false,
"library_update_id"=>"",
"needs_approval"=>false,
"organization_id"=>"5bef953a4b1be777074c2b07",
"perm_approvable"=>false,
"perm_editable"=>true,
"pinned"=>false,
"profile_id"=>"5bef956a4b1be7784607d225",
"profile_service"=>"twitter",
"shared_now"=>false,
"status"=>"buffer",
"text"=>"お腹吹田",
"text_formatted"=>"お腹吹田",
"text_md5"=>"e01909236cf97670e3f23a95e52c7072",
"type"=>"text",
"updated_at"=>1542434806,
"user_id"=>"5bef953a4b1be777074c2b05",
"via"=>"api"}],
"buffer_percentage"=>20,
"buffer_count"=>2,
"success"=>true,
"message"=>"One more tweet in your Buffer. Keep it topped up!",
"code"=>false}
> client.create_update(body: {text: "こんにちは", profile_ids: profiles.map(&:id)})
=> (略)
> client.create_update(body: {text: 'hogehoge', profile_ids: [profiles.find {|profile| profile.service == "twitter" }.send(:id)], scheduled_at: "20181117T19:00:00+09:00"})
=> (略)
ひとまず複数の投稿形式を試して思った通りに動作しました。 profile_ids
を取ってくるところで少しハマりましたが、後はAPIパラメーターを調べつついけました。このあとはCLIとして操作できれば良いなと考えているのでthorと組み合わせて実装してみようと思っています。
懇親会
www.hotpepper.jp
www.hotpepper.jp
一次会は手羽先食べ放題コース!過去にいくつかの食べ放題に勝ってきたkzrb勢も手羽先には勝てなかった...。
二次会は安定の丸二。唐揚げがでかいぜ!
懇親会で、作業部屋のCO2濃度を計測して可視化およびアラートを出す仕組みを作りたいと相談したところ、まともな濃度センサーはお高いらしく中国から輸入するのが良さそう?とのことでした。また、Withingsの体重計でCO2濃度も測れるやつがあるらしく、可視化ならこれでもいいのではという話も。
次回のKanazawa.rbは年末恒例のLT大会です!