Mercari Engineering Blog

We're the software engineers behind Mercari. Check out our blog to see the tech that powers our marketplace.

Slack Commandを使った、分析チームのナレッジを全社に広めるためのAutomation・Karakuri

f:id:tadashi-nemoto0713:20180514163530p:plain


こんにちは、メルカリのAQA(Automation & Quality Assurance)チームで、自動化をぶりぶりしている tadashi0713 です。

私は普段、QAテストの自動化・CI/CD改善・その他社内の生産性を上げるための自動化・ツール作成を行っています。

今回は、社内の分析クエリを簡単に検索・共有できるSlack Commandを最近作ったので、それについてご紹介したいと思います。

実装した背景

弊社のBI(Business Intelligence)チームでは現在、過去の分析クエリをGitHub上に蓄積しています。

分析クエリを蓄積することによって、その知見をBIチームメンバーだけではなく、社内で分析に興味のあるメンバーに共有することが可能です。


https://dvljqgv78zqdf.cloudfront.net/80116d09-019c-4a27-8a35-604dc48b1fb0.jpg https://seleck.cc/ より


詳細に関してはこちらの記事をご覧ください。

seleck.cc

しかし、実際に分析クエリを検索・共有しようとすると、チャットツールのSlackとGitHubを行ったり来たりする必要があり、BIチーム内では多少の煩わしさを感じていました。

具体的には

Slackで質問・相談などのやりとりがある
↓
GitHubのレポジトリのページに移動する
↓
キーワードで検索して分析クエリを見つける
↓
検索で出てきたクエリをコピーする
↓
Slackに貼って共有する

この検索・共有部分をより簡単にできるようになれば、より蓄積された分析クエリが活用されると思い、今回Slack Commandを作成しました。

今回主に使用するもの

簡単ではありますが、今回使用するものについて紹介します。

Slack App

api.slack.com

今回はSlack Appを1つ作り、主に

  • Slash Command
  • Interactive Message

を使います。

AWS Lambda

(以下 Lambda)

サーバーレスで、アップロードしたコードを実行させることができます。

実行された分しかコストがかからないため、今回のようなSlack Commandを作るには便利かと思います。

Lambdaでは複数の言語をサポートしていますが、今回はPython3.6で実装しました。

Amazon API Gateway

(以下 API Gateway)

SlackのSlash CommandやInteractive MessageからLambdaを起動させるには、リクエストを送るURLが必要です。

API Gatewayを使えば、簡単にAPIを定義・Lambdaと繋げることができます。

Step1 Slash command → 非同期で別のLambdaを起動させる

まず1つ目のLambdaとAPI Gatewayのセットを作ります。

作ったAPI GatewayのURLはSlash commandのRequest URLに保存します。

f:id:tadashi-nemoto0713:20180515110041p:plain

これで、Slash CommandからLambdaを起動させることができました。

このSlash CommandからのリクエストにはVerification Tokenが入っています。

Verification Token は Slack Appから確認できるので、Lambda側でリクエストにそれが入っているか確認します。

f:id:tadashi-nemoto0713:20180515110000p:plain

次に、実際にGitHubのAPIを叩き、検索結果を返したいところではありますが、Slash commandは3秒以内にレスポンスを返す必要があります。

そのため、非同期で別のLambdaを起動させることにします。

import boto3

# Invoke lambda
client = boto3.client("lambda")
client.invoke(
    FunctionName="hoge",
    InvocationType="Event",
)

InvocationTypeEvent にすることで終了を待たずに実行させることができます。

一旦Slash Commandのレスポンスを返します

f:id:tadashi-nemoto0713:20180516100142p:plain

Step2 GitHub APIを呼び、Slackに通知する

非同期で起動させたLambda関数を実装していきます。

Slash Commandから取ったキーワードを元にGitHub APIを呼びます。

Search | GitHub Developer Guide

今回はPyGithubというライブラリを使い、特定のレポジトリ内でSQLファイルのみを検索させるようにします。

github.com

from github import Github

g = Github("GitHubのToken")

results = g.search_code(
    "検索キーワード",
    language="sql",
    repo="query-recipe"
)

そして、検索結果を元にMessageを作成します。

SlackのMessage Attachmentを使うことによって、リッチな表現をすることが可能です

api.slack.com

Slash Commandから送られたリクエストに含まれる response_url に今回作成したMessageを送ることによって、Slash Commandを実行した本人にしか表示させないことが可能です。


f:id:tadashi-nemoto0713:20180514163530p:plain

Step3 ボタンをクリックしたら、その分析クエリをチャンネルに投稿する

検索結果ごとにボタンをつけ、クリックされたら該当の分析クエリを投稿させるようにします。

SlackのInteractive Messageという機能を利用し、API GatewayとLambdaのセットを用意します。

api.slack.com

作ったAPI GatewayのURLはInteractive ComponentsのRequest URLに保存します。

f:id:tadashi-nemoto0713:20180515124036p:plain

これで、ボタンをクリックするとLambdaが起動するようになりました。

あとは、先ほどと同様のMessage Attachmentを該当のSlack Channelに投稿させます。

Apexを使い、簡単に複数のLambda関数を管理・デプロイ

これまでの実装において、3つのLambda関数を作りました。

Lambda関数のアップロードには、依存ライブラリのインストールやZipにまとめるなどの作業が必要になります。

そのため、Lambda関数が増えるとその手間も増えてしまいます。

現在私のチームでは、複数のLambda関数をApexというツールで管理しています。

apex.run

apex deployコマンドを使うと、上記の必要な作業が管理されているLambda関数に対して実行されます。

また、CircleCIを使ってmasterにmergeされた際に上記のコマンドを使って自動デプロイされるように設定しました。

以下の記事が参考になるかと思います。

kakakakakku.hatenablog.com

これによって修正→反映させるコストも下がり、改善するモチベーションも上がります。

まとめ

今回作った Slack Commandによって、分析クエリをよりシンプルに検索・共有できるようになりました。

Slackで質問・相談などのやりとりがある
↓
Slack Commandを使って分析クエリを検索する
↓
共有したい分析クエリは、ボタンをクリックして共有

このSlack Commandが活用されて、社内において分析する文化がより広まってもらえると嬉しいです。

また、今後は社内のどの人が、どのキーワードで検索しているかを集計・活用しても面白そうです。


メルカリでは、エンジニアの行動指針に Automation, Karakuri があります。

自動化・効率化が好きな方は是非遊びに来てください!

ソフトウェアエンジニア(Mobile Testing, Automation) / メルカリ