masarasiの日記

私は Mackerel CRE テクニカルサポート担当です。

Go言語でAPIを実行するプログラムを作る①

勉強のために Go 言語で API を実行するプログラムを作り始めている。

はてなでは勤怠管理に AKASHI というシステムを使っていて、出勤時と退勤時にボタンを押すというもの。そしてこれをよく忘れる。。。

画面を開く > ログインする > 打刻(出勤/退勤ボタンを押す)

たったこれだけの操作だけど忘れてしまうんだよな。なので、この操作をとことん簡略化することで押し忘れを防ごうという計画。

まぁ、その目的のためなら他に方法はたくさんありそうだけど(社内には StreamDeck でやっている人がいる)、主目的は Go の勉強なので一石二鳥を狙ったかたちだ。

ゴール

1 クリックで出勤/退勤が出来る UI を作る

進捗

いきなり POST するプログラムを作るのは怖いので、AKASHI から打刻情報を GET で取得するプログラムを作った。

作成にあたってはこちらを参考にさせてもらった。

golangstart.com

AKASHIから打刻情報を取得するプログラム

※不要なコードが含まれている可能性は多分にある

package main

import (
    "fmt"
    "io"
    "log"
    "net/http"
    "net/url"
)

func main() {
    // 空のurl.URL構造体のポインタ
    u := &url.URL{}

    // 構造体のフィールドに値をセット
    u.Scheme = "https"
    u.Host = "atnd.ak4.jp"
    u.Path = "/api/cooperation/<企業ID>/stamps"

    // Queryメソッドでクエリパラメータのマップを取得
    q := u.Query()

    // クエリマップに値をセット
    q.Set("end_date", "20220131000000")
    q.Set("start_date", "20220101000000")
    q.Set("token", "<アクセストークン>")

    // クエリパラメータをエンコード
    u.RawQuery = q.Encode()

    // String 型に変換
    uStr := u.String()

    // リクエストを作成
    req, _ := http.NewRequest("GET", uStr, nil)

    //requestにheaderをつける
    req.Header.Add("Cotent-Type", `application/json"`)

    //クライアントを作成
    var client *http.Client = &http.Client{}

    //結果を変数に代入
    resp, err := client.Do(req)
    if err != nil {
        log.Fatalln(err)
    }

    // deferでクローズ処理
    defer resp.Body.Close()

    //読み込み
    body, _ := io.ReadAll(resp.Body)

    //出力
    fmt.Println(string(body))
}

難しかったポイント

NewRequest の URL 指定

構文

func NewRequest(method, url string, body io.Reader) (*Request, error)

実際のコード

req, _ := http.NewRequest("GET", uStr, nil)

送信先の URL は u := &url.URL{} の通り u に格納されている。NewRequest の引数 url に初め u をそのまま書いてエラーになった。url は string 型でなければいけないが、url.URL{} は構造体のためそのままでは使えないので、uStr := u.String() で string 型に変換する必要があった。

残る作業

  • 企業 ID やアクセストークンは変数で渡したい(そもそも出来るかはわからない)
  • POST メソッドで打刻するプログラムに変更する
  • UI を作る