くりにっき

フルスタックキュアエンジニアです

rubicure v1.1.2リリース

はぐプリでは公式HP*1のキャラ紹介に誕生日が載っていなくててっきり誕生日設定がないのかと思っていたのですが、プリティストアのTwitterアカウントからキュアエトワールの誕生日情報が流れてきたので対応しました。

キュアラインを作った

注)タイトルは半分釣りです

LINE TIMELINEスクレイピングするためのgemを作りました。

github.com

使い方

READMEからの抜粋ですがこんな感じ

# read https://timeline.line.me/user/_dYbbV3vmaJrvqBoV5ZlpCbPN2CWUZdDQayBvjBE
user = CureLine.user("_dYbbV3vmaJrvqBoV5ZlpCbPN2CWUZdDQayBvjBE")

user.info
#=> {"mid"=>"_dYbbV3vmaJrvqBoV5ZlpCbPN2CWUZdDQayBvjBE",
# "nickname"=>"プリキュア",
# "pictureUrl"=>"https://profile.line-scdn.net/0hU_sA3K0gCnBOOCZuQUx1J3J9BB05Fgw4Nl9BQmxsUEZjCU0jewlCFWo-UEk3CRhxdQtCQ20_VRBk",
# "userValid"=>true,
# "writerMid"=>"_dYbbV3vmaJrvqBoV5ZlpCbPN2CWUZdDQayBvjBE"}

user.header_url
#=> "https://obs.line-scdn.net/htzWKFLgwN1RRXiRaCAgwLR0sfTZOB28EU1VjYxs0IWYTAjkDUFViZhhgJjJHUmRR"

post = user.posts.first 

post.nickname
#=> "プリキュア"

post.picture_url
#=> "https://profile.line-scdn.net/0hU_sA3K0gCnBOOCZuQUx1J3J9BB05Fgw4Nl9BQmxsUEZjCU0jewlCFWo-UEk3CRhxdQtCQ20_VRBk"

post.post_url
#=> "https://timeline.line.me/post/_dYbbV3vmaJrvqBoV5ZlpCbPN2CWUZdDQayBvjBE/1152127900305060448"

post.text
#=> "プリキュアになってから、さあやとほまれとますます仲良くなれて、\n超うれしー!!\(^o^)/\n今日はビューティーハリーで、お互いに洋服をコーディネイトし合ったんだ~。\n\nさあやは、大人っぽいデザインのスカートがめっちゃ似合ってた!\nう~ん、絵のモデルさんになれそうなくらい素敵!( *´艸`)\n\nほまれはオシャレ上級者しか着こなせないような、最先端のオールインワンがぴったり!\n背が高くて、足が長い人はいいな~、うぅ……(T_T)\n\nはぐたんはくまさんの耳がついたフードをかぶって……。\nきゃ、きゃ、きゃわたん~~~~(・´з`・)\n拝みたくなる可愛さでした♡\n\nで……私は!?私は何が似合うかな!?\nえっ……ハリーおすすめのどデカイ虎の絵が描いてあるトレーナー!!?\nみんな、似合ってるって言ってくれるけど……お腹抱えて笑ってるじゃん!!ヽ(`Д´)ノプンプン\n\nう~ん、でも言われてみれば、たしかに似合ってるような……。\nこれを着こなせるって、逆にすごいかも☆(^ε^)\nはぁ~、今日もいい一日でした!"

post.created_time
#=> 2018-03-17 18:30:03 +0900

post.updated_time
#=> 2018-03-17 18:30:03 +0900

post.photo_urls
#=> ["https://obs.line-scdn.net/h5XG4_2KndnZXIWV4GHdxDwZTY0ZUe34iR3snQghNNkNUfSx0Qy4lRF9PPERUeS8iQy9gFwtOYENTfg"]

動いてる様子

個人Slackでプリキュアのタイムラインを通知するのに使ってます

f:id:sue445:20180321161742p:plain

元々はcure_line自体も個人Slackのボットの一機能だったのですが、今回gem化してロジックを外部に切り出しています

関連商品

ハピネスチャージプリキュア! キュアライン

ハピネスチャージプリキュア! キュアライン

自分のスライドのリンク集を作った

「リンク集」って響きに懐かしさを感じるオッサンです(挨拶)

自分の勉強会のスライドの公開先はSlideshareやSpeakerDeckやGitHub Pagesなどその時の気分で変わるんですが*1、後から探す時に不便だったのでまとめました。ご査収ください

github.com

関連リンク集

qiita.com

sue445's CI Badges

これ系のリンク集があると人に見せやすいのでおすすめ。特に前者の1人AdventCalendarは自分のプロダクト紹介でよく使ってます

*1:最近だとmaekdownで書きたい派なのでreveal.jsで書いてGitHub Pagesにupすることが多いです

ChatWorkMentionTaskを作った #megurorb

Meguro.rb#12 で趣味アプリについてのLTしたので資料を上げておきます

megurorb.connpass.com

スライド版

sue445.github.io

エントリ版

ChatWorkMentionTaskとは

f:id:sue445:20180226235644p:plain

動作風景

  • 自分宛にきたメンションが自動的に別部屋にタスク化され、一覧表示される
  • 重要なものや後で対応必要なものだけ残して、それ以外のタスクを完了にする運用

f:id:sue445:20180226235658p:plain

所感

  • 半月くらい人柱運用してるけど日々の仕事がむっちゃ捗ってる!!!
  • ぶっちゃげChatWork本体に欲しい機能なんだが、3年前から要望は出ている がいまだに実装されていないので諦めて自分で作った

技術的なこと

仕組み

  1. ChatWorkMentionTaskにChatWorkのアカウントでOAuth認証
  2. ChatWorkの自分のアカウントにChatWorkMentionTaskのwebhookを登録
  3. メンションがきたらwebhookが飛んできてタスク化される

頑張ったこと

ChatWorkのAPIのリフレッシュトークンの有効期限は2週間なので、リフレッシュトークンが切れる3日前にリマインド用にタスクを作るようにした

f:id:sue445:20180226235725p:plain

webhookの params[:body] にチャット本文が入っていて、それがログに出るのが嫌だったのでパスワード同様フィルタリングするようにした。

f:id:sue445:20180226235744p:plain

f:id:sue445:20180226235756p:plain

https://github.com/sue445/chatwork_mention_task/commit/ec3e2583044e2c132ef1de9ef0c656f1e74dcac1

副産物の紹介

  • omniauth-chatwork 💎
  • chatwork 💎
  • chatwork_webhook_verify 💎
  • dockerfile-heroku-cli 🐳
  • dockerhub-slack-webhook 🐳

omniauth-chatwork 💎

https://github.com/sue445/omniauth-chatwork

実際の設定

Railsだとこんな風に書いておくだけでいい感じにChatWorkのOAuth認証が使えるようになる

# config/initializers/omniauth.rb
Rails.application.config.middleware.use OmniAuth::Builder do
  provider :chatwork, ENV["CHATWORK_CLIENT_ID"], ENV["CHATWORK_CLIENT_SECRET"], scope: ["users.profile.me:read", "rooms.tasks:write", "rooms.info:read"]
end

https://github.com/sue445/chatwork_mention_task/blob/10dd0c197060fbc62016fe33b60a2089dfb74261/config/initializers/omniauth.rb

chatwork 💎

https://github.com/asonas/chatwork-ruby

やったこと

f:id:sue445:20180226235815p:plain

頑張ったこと

実際のテストコード

  • stub_chatwork_requestit_behaves_like :a_chatwork_api でramlを利用
  • APIクライアントではテストデータの生成が面倒なのでそこを公式が提供しているデータを使って自動化できて便利
describe ".create", type: :api do
  subject { ChatWork::Message.create(room_id: room_id, body: body, &block) }

  let(:room_id) { 123 }
  let(:body)    { "Hello ChatWork!" }

  before do
    stub_chatwork_request(:post, "/rooms/#{room_id}/messages", "/rooms/{room_id}/messages")
  end

  it_behaves_like :a_chatwork_api, :post, "/rooms/{room_id}/messages"
end

https://github.com/asonas/chatwork-ruby/blob/v0.8.0/spec/lib/chatwork/message_spec.rb#L24-L35

chatwork_webhook_verify 💎

# app/controllers/webhook_controller.rb
class WebhookController < ApplicationController
  before_action :verify_chatwork_webhook_signature!
end

リクエストごとにtokenを変えて検証する必要がある場合はこんな感じ

class WebhookController < ApplicationController
  before_action :set_user
  before_action :verify_signature!

  private

    def verify_signature!
      return unless Global.app.verify_signature?

      verify_chatwork_webhook_signature!(@user.webhook_token)
    end
end

https://github.com/sue445/chatwork_mention_task/blob/10dd0c197060fbc62016fe33b60a2089dfb74261/app/controllers/webhook_controller.rb

dockerfile-heroku-cli 🐳

  • https://github.com/sue445/dockerfile-heroku-cli
  • https://hub.docker.com/r/sue445/heroku-cli/
  • CircleCIからherokuにデプロイする時に毎回 heroku/cli をダウンロードしたくなかったのでインストール済のイメージを作った
  • alpineに必要最低限のパッケージやバイナリしか入れてないので47MBしかない超軽量イメージ
    • Docker Hubを検索してると似たようなイメージを作ってる人はたくさんいるけど、自分が見た範囲では sue445/heroku-cli が最軽量

頑張ったこと

常に最新のheroku/cliをDockerイメージで使いたかったので、heroku/cliの更新を自動検知してDockerイメージを自動ビルドする仕組を作った

  1. CircleCIのスケジューラが週1で起動
  2. heroku cliのバージョンが上がっていればCircleCIがファイルをコミットしてGitHubにpush
  3. GitHubにpushされればDocker Hubの automated builds でビルドがされる

https://github.com/sue445/dockerfile-heroku-cli/blob/fd4517b1b252e182d7b318fed74fe95fbe79e782/.circleci/config.yml#L64-L79

dockerhub-slack-webhook 🐳

  • https://github.com/sue445/dockerhub-slack-webhook
  • Docker Hubでビルドした後にSlackに通知するためのwebhook
  • ビルドしたイメージがいつビルド終わるか分からないので、Slackに手軽に通知できるようにしたかった

f:id:sue445:20180226235907p:plain

頑張ったこと

Deploy to Herokuボタンに対応してるので、Herokuのアカウントさえあればワンクリックでデプロイできる

f:id:sue445:20180226235917p:plain

まとめ

  • ChatWorkを使ってる場合はChatWorkMentionTaskは便利なので是非使ってください
  • RubyでChatWorkをハックする技術はだいたい制覇できた感あるw

2018/8/9 追記

ChatWorkのAPIのリフレッシュトークンの有効期限は2週間なので、リフレッシュトークンが切れる3日前にリマインド用にタスクを作るようにした

リフレッシュトークンの期限を無期限に設定できるようになったので上記処理は不要になりました

sue445.hatenablog.com

OSS雑メンテ #railsdm

Rails Developers Meetup 2017 というイベントで「OSS雑メンテ」という発表をしたのでスライドをシェアさせていただきます

スライド

発表中の反応

他の人のスライド

他の人のスライドは下記をご覧ください

railsdm.github.io

chatwork-rubyのメンテナになった

注意:アドベントカレンダーとは全く関係ないエントリです

github.com

https://rubygems.org/gems/chatwork

chatwork-rubyにPRを送りまくってたら気づいたらメンテナになっていました

他にも Jenkins ChatWork Plugin のメンテナにもなったし*1omniauth-chatwork も作ってるので、日本におけるChatWork APIのヘビーユーザと言っても過言ではなさそう(過言)

chatwork-rubyの方は権限周りの動作確認も兼ねてOAuth対応版をリリースしておきました

今後のこと

プライベートが色々ごたついているので、落ち着いたらテスト周りの整備をしつつ対応してないエンドポイントの対応をしておこうと思ってます。