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を付けるのが慣習

Go language Pattern

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拡張することにします。

課題

・テストの追加 ・ログ

機能を分離するほどにログの出力方法は重要になるので工夫して実装したいものです。 テストも順次追加して完全な使い捨てにならないように注意します。