Help us understand the problem. What is going on with this article?

Lambda for Ruby を使って勤怠ボタンを作ってみた

More than 1 year has passed since last update.

概要

弊社では勤怠の管理に jobcan というサービスを利用しています。slack連携で特定のコマンドを入力すると出勤・退勤ができるっていうグッドでナイスな感じのサービスなのですが、人は怠惰なものでもはや出勤時にslackに /jobcan_touch の13文字を打つのすらめんどい。

そこでせっかくなので先日発表された「AWS Support for Ruby」を利用して更に楽に出勤してみるをしてみることにしました。

lambda for ruby をちょっと触ってみたい人にも参考になると幸いです。

仕組み

すでに下記とほぼ同内容の仕組みが IFTTT 版で動いてるためその時にpythonで書いてたものをrubyでやってみるという感じです。

参考: 物理出勤ボタンを作った - レタスのかわをぜんぶむく

やりたい仕組みの流れ

オフィスのドアを開ける → ポケットからiPhoneを取り出す → IFTTT Button を押す → (ここから自動) → AWS API Gatewayで設定したURLにPOSTする → フックされた Lambda が動く→ slack にcommand を投稿する → jobcan連携が飛ぶ → 出勤!

をオフィスに入ってから自席につくまでにやる、です。親指がslack開く(1)・チャネル開く(1)・13文字打つ(13)の15アクションの削減ですね。

手順

下記の手順でやったことを書いていきますが、IFTTTのアカウント作成はたぶん興味ある人いないと思うし、AWSのアカウントも迷うことなく登録できると思うし、太字のところから書いていこうと思います。

  • IFTTTアカウントを作成する
  • AWSアカウントを作成する
  • Rubyコードを書く
  • lambdaの準備
  • IFTTT ボタンの設定
  • 実行

Rubyコードを書く

ハマりどころ

Rubyでslackに投稿するコードを書いていきます。上に上げたリンクにも書いてあるんですが2つほど注意点があります。

1つ目は、「レガシートークンを使う」です。
今回の投稿はslackの連携commandを使うので本人の投稿として認識させる必要があります。そのためIncomming Webhookが使えません。レガシートークンの取得はちょっと調べれば出てくると思います。

2つ目は、「ドキュメントに記載されてないAPIの chat.command にあたる命令をする必要がある」です。
今回 以下のgemを使ってますが、公式のドキュメントに記載がないAPIなのでこのgemのリファレンスにも乗ってないコマンドだったりします。

https://github.com/slack-ruby/slack-ruby-client

どちらも公式が推奨してない感じがプンプンしているので、いつか使えなくなる日が来るかも知れないんですがその頃にはjobcanさんがAPIを公開していただけるとありがたいです。出勤だけでいいので。

コード

さて、コードはこんな感じです。

# Gemfile
source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
gem 'slack-ruby-client'
lambda_function.rb
require 'slack-ruby-client'

TOKEN_ID = ENV['TOKEN_ID']

def lambda_handler(event:, context:)
  Slack.configure do |config|
    config.token = TOKEN_ID
  end

  client = Slack::Web::Client.new
  begin
    client.chat_command(
      channel: '#times_katsumata',
      command: '/jobcan_touch',
      text: 'by AWS Lmabda for Ruby via IFTTT',
      as_user: true
    )
  rescue => e
    {statusCode: 422, body: JSON.generate({class: e.class, message: e.message})}
  end

  {statusCode: 200, body: JSON.generate({message: 'ok'})}
end

コードのとおりなのですが、注意点としては

  • lambdaのコード実行のスタートが lambda_function.rbdef lambda_handler から実行されます。そのためこれがないとlambdaにファイルを上げた時に警告がでます。
  • 3行目: lambdaは環境変数が登録できるのでトークンは環境変数に登録してます
  • 12行目: client.chat_command が先程のドキュメントに載ってないAPIのメソッド
  • 13行目: 投稿チャネル
  • 14行目: jobcanの出勤するスラック連携のコマンドtextだと文章として認識してしまうため、別にcommandで指定する必要があります。
  • 16行目: as_user: true で本人としてslackに投稿ができるようになります。

という感じです。非公式コマンドのところは参考にしたサイトを見つけられなかったら確実に諦めてた案件でした。

lambdaの準備

アップロードファイルの準備

lambdaの準備をしていきます。
今回外部ライブラリを使用しているので、AWS lambdaのエディタを使うことができません。そのためzipにしてファイルをアップロードする必要があります。また、今回は4.3MBぐらいだったので必要なかったんですが、10MBを超えるとlambdaでのアップロードができません。その場合はS3にアップロードをする方向で対応してみてください( 参考: Announcing Ruby Support for AWS Lambda )

bundle installしてローカルにgemを用意する

$ bundle install
$ bundle install --deployment # ./vender/bundle にgemが入る

ファイルツリーの様子

./
├── Gemfile
├── Gemfile.lock
├── lambda_function.rb
└── vendor # gem が入ってる

ファイル構造がこんな感じになっているはずなので、この4つを選択してzipファイルにしてあげてください。

AWSでlambdaの作成

AWSでlambdaを作っていきます。

lambdaのページを開いて関数の作成を押す。

image.png

一から作成で項目を入力しランタイムでRubyを選択する。2018/12/02時点だと ruby2.5 のランタイムのみ用意されているようですね。

image.png

以下のような画面が出てくると思うので(※画面はすでに動いてる関数のものなので実際の画面とは異なります)、一番上のファイル名のところが選択されている状態になっているとページの下部に関数コードの編集画面が出ていると思います。

image.png

コードエントリタイプで.zipファイルをアップロードを選択し、先程zipに固めたファイルをアップロードします。アップロード選択し終わったらページ上部の保存を押すようにしてください。毎回忘れてあれ?ってなる。今回ライブラリを含んでいるので下記画像のようなinfoが出ていて、インラインコードの編集はできなくなってる。

image.png

次に環境変数の登録です。書いたコードに合わせて環境変数を登録します。値にしてしているのは、先程のslackのレガシートークンです。

image.png

最後にAPI Gatewayの設定をします。ない人はトリガーの追加からAPI Gatewayの設定を行ってください。
ここで作ったAPI エンドポイントが IFTTT Buttonで登録する値になります。
ちなみにlambdaはメソッドの投稿テストができるので、実際に全体で動かして見る前に関数のテストを試せるので便利です。

image.png

IFTTT Buttonの設定

あとは特に説明するほどではないのでキャプチャだけ。設定はbuttonからwebhookです。

image.png

で、iPhoneの方でIFTTTのアプリをダウンロードしてボタンを設定してあげるとこのような感じに。

image.png

これで準備完了です!(実装中に一回間違えてボタンを押してしまって、出勤してしまったため勤怠修正申請しなきゃいけない...)

実行

ボタンを押すとslackの投稿がこんな感じでされてよっしゃ。

image.png

以上lambda for ruby を使った勤怠ボタンの作成でした。

lambda for rubyですが個人的に待望の機能追加でずっと待ってたので先日の発表は歓喜でした。サーバ上から何かを実行し用とすると環境の準備がネックになって作るのやめっちゃったりとかのハードルがぐっと下がりそう。簡単なwebアプリケーションも動かせたりと夢が広がりまくりな感じがあるので、lambda for ruby 活用していきたいところ。

参考リンク

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away