最近流行りのojichatをslackbotにした


最近流行りのojichatをslackbotにした話

最近シェル芸botの猛威によってTLがおじさんだらけになってしまった。
うちのslackにもおじさんで賑やかにしたいな~と思ったので作ってみた。

greymd/ojichat
https://github.com/greymd/ojichat

処理の流れ

  1. OutGoing WebHooks使って特定の投稿をとる。
  2. Slack側から特定のサーバにリクエスト送る。
  3. サーバで受け取って名前取り出す!
  4. 取り出した名前をIncomingWebHooksで指定されたURLにJSON形式でリクエスト送る!
  5. おじさんしゃべる!

Outgoing WebHooks

指定した文字の投稿があった際に、Slackから外部のサーバにPOST送るやつ。
それぞれの設定項目があるので入れていく。
Channel     #general
TriggerWord(s)  ojisan
URL(s)      http://X.X.X.X:8080

今回はこれくらいしか設定入れてません。
URL(s)にはリクエストを受け取りたいサーバのipアドレス指定してください。

これでojisanキーワードが投稿されたら上記URLにPOSTされます。

Incoming WebHooks

外部からSlackにメッセージを送信するやつ。これでおじさんメッセージ送ります
Outgoing WebHooksと同様設定項目を入れていきます
Post to Channel #general
Customize Name おじさん

他にもアイコンなども変えることができます。
項目のWebhook URLにあるURLに対してJSON形式でリクエストを送ることで
Slackの指定したチャンネルにメッセージを送ることができます。

受信サーバ

最近Goしか書いていないので、Go製Webアプリケーションフレームワークのgin/gonic使いました。
https://github.com/gin-gonic/gin

もうここまで来たらほぼ完成じゃんと思って、
ウキウキで受け取ったデータがこれ...

token=vFlRfdwGp9Nk5koVtSrbMxxx&
team_id=T63EC9xxx&
team_domain=xxx-network-club&
service_id=652176051511&
channel_id=CJSJ7TXXX&
channel_name=general&
timestamp=1559196598.002400&
user_id=U643K5XXX&
user_name=minatoo&
text=ojisan&
trigger_word=ojisan"

なんの形式やねんこれ....
調べたら
application/x-www-form-urlencoded: キーと値は、その間に '=' がある形でキーと値の組になり、 '&' で区切られてエンコードされます。
https://developer.mozilla.org/ja/docs/Web/HTTP/Methods/POST

てことでJSON形式にコンバートする処理をガキみたいなコードで実装した。
https://github.com/mntky/convA2J/blob/master/pkg/conv.go

これで自由にデータを扱える...!!

受信サーバのコード

package main

import (
    "fmt"
    "os/exec"
    "encoding/json"

    "github.com/gin-gonic/gin"
    "github.com/mntky/convA2J/pkg"
)


type ConvData struct {
    Token           string
    Team_id         string
    Team_domain     string
    Service_id      string
    Channel_id      string
    Channel_name    string
    Timestamp       string
    User_id         string
    User_name       string
}

func main() {
    g := gin.Default()
    g.POST("/", func(c *gin.Context) {
            buf := make([]byte, 2048)
            n, _ := c.Request.Body.Read(buf)
            b := string(buf[0:n])

            decode(b)
    })
    g.Run(":8080")
}

func decode(data string) {
    var convdata *ConvData = &ConvData{}
    resp := conv.Convert(data)
    err := json.Unmarshal([]byte(resp), convdata)
    if err != nil {
            fmt.Println(err)
    }

    fmt.Println(convdata.User_name)
    out, err := exec.Command("sh", "./send.sh", convdata.User_name).Output()
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println(string(out))
}

取り出した名前はexecで send.shに引数渡して実行させてます。

curl incomingwebhookの指定URL -X POST -H "Content-Type: application/json" -d '{"username":"おぢさん", "text":"'$(ojichat $1)'"}'

まとめ

これで完成です。
最後に動かした例を...

相変わらずのキモさで疲れが飛びました。
なお自分以外誰もojisan打ってくれないので二度と出番がなさそうです。

ぜひみなさんのチャンネルにもいかがでしょうか?