AlfredからSlackに簡単に分報を投稿する

"車輪の再発明は楽しい"
2020.08.31

はじめに

大阪オフィスの岡田です。
皆さんはSlackで分報やってますか? 私は悩みを呟ける場所が欲しくなって最近始めました。 やり始めると、

  • Slackアプリに毎回移動するのがめんどくさいなぁ
  • Slackの雑談部屋が気になるなぁ
  • 分報を投稿するために作業の手がとまってしまう...

という気持ちが出てきます。本当はもっと楽に、作業中の思考を止めずに気楽にポイポイポストしたいです。

車輪の再発明

MacだとAlfredから分報がポストできたら上記の悩みが解決できそう! 少し調べるとAlfredからSlackに投稿するやり方はいくつかヒットするのですが、この程度の車輪なら再発明(再開発)してみたいですよね。というわけで作ることにしました。

Alfredのワークフローでは複数の開発言語をサポートしていますが、今回はGo言語でSlackへ投稿するスクリプトを書き、それをzshスクリプトから呼び出すという方式にしています。 わざわざGoで書く理由ですが、普段業務ではScalaを書く事が多いので

Goで書いてみたい

という理由です。それ以外にはありません。

まずは成果物

Alfredを起動してスクリプトを呼び出す

t [テキスト] で、テキストを投稿します。

posted-from-alfred

投稿するためにSlackアプリに移動しなくていいので楽です!

前提

  • Slackのアプリを新規作成し、トークンを取得しておく
    • Bolt入門ガイド がわかりやすいです
    • トークンとアプリのインストール まででOK
    • 権限は char:write に設定します
  • AlfredのPowerpackを購入する
    • 無償版ではワークフローが使えなかったので、今回課金しました

コード

まずSlackに投稿するスクリプトです。

package main

import (
  "flag"
  "fmt"
  "log"
  "net/http"
  "net/url"
  "strings"
  "time"
)

type Config struct {
  Token string `json:"token"`
  Channel string `json:"channel"`
}

func main() {

  postUrl := "https://slack.com/api/chat.postMessage"
  // コマンドライン引数からメッセージを取得
  token := flag.String("t", "", "oAuth token of slack app")
  channel := flag.String("c", "", "slack channel name")
  text := flag.String("m", "", "chatting text message")
  flag.Parse()

  if len(*token) > 0 && len(*text) > 0 && len(*channel) > 0 {

    values := url.Values{}
    values.Add("token", *token)
    values.Add("channel", *channel)
    values.Add("text", *text)

    client := http.Client{Timeout: time.Duration(10) * time.Second}
    req, err := http.NewRequest("POST", postUrl, strings.NewReader(values.Encode()))
    if err != nil {
      log.Fatal(err)
        panic(err)
    }
    req.Header.Add("Content-Type", "application/x-www-form-urlencoded")

      res, err := client.Do(req)
      if err != nil {
        log.Fatal(err)
          panic(err)
      }
      defer res.Body.Close()

  } else {
    err := fmt.Sprintf("not set param. (t=%s, c=%s, m=%s)", *token, *channel, *text)
    log.Fatal(err)
    panic(err)
  }
}

スクリプトがコピーできたらgoのコマンドビルドし、実行ファイルを作成します。 ビルドした実行ファイルは post-to-slack とします。

次にAlfredのワークフローです。

alfred-workflow

エラー時にMacの通知にメッセージを表示するために、フローの最後にサイドバーの通知を入れています。

最後にワークフローの真ん中になるbashスクリプトです。

#!/bin/zsh
PATH=$PATH:~/work/go/times-okaryu/bin #実行ファイルのパスを追加

token="[Slackのトークン]"
channel="#[チャンネル名]"
text="{query}"

post-to-slack -t $token -c $channel -m "$text"

上記をAlfredのワークフローにコピペします。 token はSlackアプリで取得したトークン。 channel はポストしたいチャンネル名です。 {query} にAlfredで入力したテキストが入ります。 post-to-slack に必要なコマンドラインパラメータを渡して実行してやると、前述のGo製のスクリプトが実行され、SlackのAPIを叩きます。

まとめ

Alfredから投稿できるようになったので、プログラミング途中だろうが、ブログを書いていようが、Zoomで会議中だろうがサクッと投稿できてしまいます。ScalaもGoも楽しい。