日頃の行い

個人的な日頃の行いをつらつら書いてます\\\\ ٩( 'ω' )و ////

Slack内でActiveなユーザ数をMackerelのサービスメトリックで表示してみた

コミュニティでSlackを使ってるんですが、どれくらいの人が普段見てるんだろうと思って可視化してみました。
計測したい数は今User Presenceがactiveなユーザ数です。

api.slack.com

Mackerelのサービスメトリックがカジュアルに使えてとても便利なので今回はそれを利用しました。

mackerel.io

作ったコードはこんな感じです。
とても素朴なコードです。
これをcronで毎分動かすことで、毎分activeなユーザ数をMackerelのサービスメトリックに投げています。
Slackのライブラリを使おうとしたのですが、Presenceがなぜか取れなかったりしたのでとりあえず自前で書きました。

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "os"
    "time"

    "github.com/joho/godotenv"
    mkr "github.com/mackerelio/mackerel-client-go"
)

type response struct {
    OK      bool   `json:"ok"`
    Members []user `json:"members"`
}

type user struct {
    ID                string      `json:"id"`
    Name              string      `json:"name"`
    Deleted           bool        `json:"deleted"`
    Color             string      `json:"color"`
    RealName          string      `json:"real_name"`
    TZ                string      `json:"tz,omitempty"`
    TZLabel           string      `json:"tz_label"`
    TZOffset          int         `json:"tz_offset"`
    Profile           interface{} `json:"profile"`
    IsBot             bool        `json:"is_bot"`
    IsAdmin           bool        `json:"is_admin"`
    IsOwner           bool        `json:"is_owner"`
    IsPrimaryOwner    bool        `json:"is_primary_owner"`
    IsRestricted      bool        `json:"is_restricted"`
    IsUltraRestricted bool        `json:"is_ultra_restricted"`
    Has2FA            bool        `json:"has_2fa"`
    HasFiles          bool        `json:"has_files"`
    Presence          string      `json:"presence"`
}

func main() {
    err := godotenv.Load()
    if err != nil {
        log.Fatal(err.Error())
    }
    client := mkr.NewClient(os.Getenv("MACKEREL_TOKEN"))
    token := os.Getenv("SLACK_TOKEN")
    resp, err := http.Get(
        fmt.Sprintf("https://slack.com/api/users.list?token=%s&presence=1", token),
    )
    if err != nil {
        log.Fatal(err.Error())
    }
    body, _ := ioutil.ReadAll(resp.Body)
    defer resp.Body.Close()
    r := response{}
    json.Unmarshal(body, &r)
    c := 0
    for _, u := range r.Members {
        if u.Presence == "active" {
            c++
        }
    }
    err = client.PostServiceMetricValues("Dark", []*mkr.MetricValue{
        &mkr.MetricValue{
            Name:  "dark.slack.active_rate",
            Time:  time.Now().Unix(),
            Value: c,
        },
    })
    if err != nil {
        log.Fatal(err.Error())
    }
}

github.com

実際の画面がこんな感じでした。
深夜帯に少しいるのはbotも数えてしまっているからかもしれないので、
botを除く処理を挟もうとこの記事を書いてる際に思いました。
ブログ書くのは整理にもなって良いですね。

f:id:arata3da4:20170324185031p:plain

まとめ