goのパッケージを作成する
APIを確認してslackにwebhook投げるものを作りたいで作成したslackに関する部分をパッケージとして切り出すのが目標。
package名
プログラミング言語Go という本によると
パッケージを作成する場合には、その名前は短くしてください。しかし、意味不明になるほど短くはしないでください
とのこと。webhookをキーワードとして入れたかったですが、今回はslackutilとして関数名にwebhook入れることに。
保存場所
保存場所は $GOPATH/github.com/hidekazoo/skackutil 。自身のgithubアカウント名フォルダの下に作成。もちろん、githubにもリポジトリ作成してgit管理。
Code
package slackutil
import (
"net/http"
"net/url"
)
type Slack struct {
WebhookURL string
}
func NewWebhook(url string) *Slack {
if url == "" {
return nil
}
s := Slack{WebhookURL: url}
return &s
}
func (s *Slack) SendWebhook(text string) error {
_, err := http.PostForm(s.WebhookURL, url.Values{"payload": {string(text)}})
if err != nil {
return err
}
return nil
}
調べた限りGoにはconstructor機能がなく、似たような機能としてfactory functionsを使う。その関数名にはNewを付けるのが慣習
Constructors and composite literals
前回のCodeを修正
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"github.com/hidekazoo/slackutil"
)
var domain = ""
var apiRoot = ""
var webhook = ""
var urls = [...]string{
"",
}
type params struct {
Text string `json:"text"`
}
func main() {
http.HandleFunc("/api/check", func(w http.ResponseWriter, r *http.Request) {
targetURL := domain + apiRoot + urls[0]
resp, err := http.Get(targetURL)
if err != nil {
fmt.Println(err)
}
defer resp.Body.Close()
s := slackutil.NewWebhook(webhook)
if resp.Status != "200 OK" {
p := params{
Text: "api url: " + targetURL + " status: " + resp.Status,
}
data, err := json.Marshal(p)
if err != nil {
fmt.Println("json error")
}
err = s.SendWebhook(string(data))
if err != nil {
fmt.Println("slack post error")
}
defer resp.Body.Close()
}
})
log.Fatal(http.ListenAndServe(":4020", nil))
}
少し良くなりました。slack関連で他の機能が使いたくなったらslackutil拡張することにします。
課題
・テストの追加 ・ログ
機能を分離するほどにログの出力方法は重要になるので工夫して実装したいものです。 テストも順次追加して完全な使い捨てにならないように注意します。