post Image
コードレビューをチームにリクエストするSlack BotをSwift実装したお話🚢

GithubでコードレビューをチームにリクエストするSlack BotをSwift実装したお話🚢

サーバーサイドSwiftで代表的なフレームワークVaporを使って、チーム開発をしているレポジトリーでPull Requestを出した時に同じチーム内の誰かにランダムでレビューをアサインするSlack Botを実装しました!

職人のように洗練されて行って欲しいのでGithubShokuninと名付けました👍

現状のGithubShokuninができること

現状のGithubShokuninができることは以下の一個だけです😇

  • Slackで以下のようにメンションすることでGithub上でメンバーにランダムでReviewをリクエストできる。
@Bot review #PR Number

こんな感じです!

Screen Shot 2016-12-24 at 15.25.05.png

GithubShokuninのセットアップ

Vaporのインストール方法はReadMeにまとめてあります!

  • Slack BotのTokenと名前をbot-config.jsonに書き込む
{
    "token": "xoxo-2h4j43n5g3i2mn24g",
    "bot_name": "GithubShokunin"
}
  • GithubのTokenやTeamIdをセットする

※レポジトリー上でReviewを行うチームを作成する必要があります!

{
    "owner_name": "yuzushioh",
    "repo_name": "GithubShokunin",
    "review_team_id": "12345",
    "github_token": "biub3h24vb53vjjv2v42v24g(sample)"
}

Vaporについて

Vapor

インストール ReadMe

以下のコードで、Hello World!を実装できます!

let drop = Droplet()

drop.get("/") { request in
    return "Hello World!"
}

drop.run()

GithubShokuninの実装

Hubotが使えないのでSlackのReal Time Messaging APIを使ってChatを監視しています。

VaporのWebSocket

以下のようにWebSocket Clientを作成できます。

import Engine
import WebSockets

try WebSocket.connect(to: url) { ws in
    print("Connected to \(url)")

    ws.onText = { ws, text in
        print("[event] - \(text)")
    }

    ws.onClose = { ws, _, _, _ in
        print("\n[CLOSED]\n")
    }
}

メンションされたユーザーがbot-config.jsonで指定したBotならば、そのチャットの内容に応じて処理を行うようになっています。

チャットの内容を元にContentを作成する

現状はチャットの内容をもとに以下の3つにわけている。
enum MessageContent {
    case requestReview(prNumber: String)
    case commandLine
    case unknown
}

Contentを元に必要なAPIを叩く

VaporのDropletを使ってGithubのAPIを叩く

let response = try drop.client.get("http://github.com", query: ["q": "test"])

ResponseのJSONをModelにマッピングする。

guard let json = response.json else {
    throw BotError.invalidResponse
}

let pullRequest = try PullRequest(node: json.node)

作成したModelを元にBotのレスポンスを作成する

  • SlackMessageというModelを用意している
struct SlackMessage {
    let id: UInt32
    let channel: String
    let text: String
    let type: String

    init(to channel: String, text: String) {
        self.id = UInt32.random()
        self.channel = channel
        self.text = text
        self.type = "message"
    }
}

このモデルはVaporのNodeConvertibleに準拠していて、モデルからNodeを作り出すことができます!

extension SlackMessage: NodeConvertible {
    func makeNode(context: Context) throws -> Node {
        return try Node(node: [
            "id": id,
            "channel": channel,
            "type": "message",
            "text": text]
        )
    }

    init(node: Node, in context: Context)  throws {
        id = UInt32.random()
        channel = try node.extract("channel")
        text = try node.extract("text")
        type = try node.extract("type")
    }
}

作成いたSlackMessageをメンションがあったSlack Channelに投げ返す!!

try WebSocket.connect(to: url) { ws in
    print("Connected to \(url)")

    ws.onText = { ws, text in
        ......
        let response = SlackMessage(to: message.channel, text: responseText)
        try socket.send(response)
    }

    ws.onClose = { ws, _, _, _ in
        print("\n[CLOSED]\n")
    }
}

 思ったこと

  • Hubotが使えないのでCoffee Scriptでかいた時より格段にコード量が増えてしまった。
  • Vaporは初めて2週間くらいだがなかなか使いやすいし書きやすい!

Vaporの参考にしたり、是非チーム開発で使ってみてください!


『 Swift 』Article List
Category List

Eye Catch Image
Read More

Androidに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

AWSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Bitcoinに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

CentOSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

dockerに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

GitHubに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Goに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Javaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

JavaScriptに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Laravelに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Pythonに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Rubyに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Scalaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Swiftに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Unityに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Vue.jsに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Wordpressに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

機械学習に関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。