21
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ディップAdvent Calendar 2022

Day 18

lambda + Goで定期バッチを作成する

Posted at

この記事はディップ株式会社Advent Calendar 2022 の18日目です

概要

私が所属しているチームでは週1回定例があり、DocBaseという情報提供ツールに議事録を残しています。
議事録は毎週定例実施前にテンプレートを手動で準備していましたが、以下問題点がありました。

新規issueの記入が面倒

議事録には、定例までの期間に新しく作成されたissueを記入をする必要がありますが、所属チームではリポジトリを複数管理しています。
そのため、リポジトリごとにissueを検索 -> md形式に変換 という工程を複数回を行う必要があり、issueの記入に時間がかかりました。

手作業によるミス

人の手で作業を行うため、日付のミス・issue起票のミス・議事録作成忘れなどが稀に発生していました。

これらを解決し業務を効率化させるために、定例議事録の作成をバッチ化させました。

詳細

定例バッチの作成には lambda + EventBrigeを使用し、最終的には以下のような構成にしました。

アーキテクチャ図 (1).jpg

一部実装を簡単に説明していきます

lambdaハンドラーの実装

github.com/aws/aws-lambda-go/lambdaを使用してハンドラーを作成します。
eventにはEventBridgeで設定できる定数パラメーターが入ってくるので、こちらを使用することでどの処理を実行するかを判断させています。

main.go
type myEvent struct {
	Name string `json:"name"`
	Days []int  `json:"days,omitempty"`
}

func HandleRequest(ctx context.Context, event myEvent) (string, error) {
	fmt.Println("start HandleRequest")
	var err error

	switch event.Name {
	// 定例テンプレート作成
	case constant.MEETING_TEMPLATE_CREATING: // meeting_template_creating
		err = meeting.Handler(event.Days)
    // issue記入
	case constant.MEETING_ISSUE_EXPORT: // meeting_issue_export
		err = issue.Handler()
	default:
		err = fmt.Errorf("unexpected batch name")
	}

	return fmt.Sprintf("Finish %s!", event.Name), err
}

func main() {
	lambda.Start(HandleRequest)
}

議事録の作成

DocBaseへ議事録のテンプレート投稿する処理を行なっています。
議事録のテンプレートをTPL_BODYに格納しておき、定例ごとに変動する箇所のみを置き換え後、DocBaseが提供しているメモ投稿APIを使用し投稿を行なっています。

create.go
const TPL_BODY = `
議事録のテンプレート
`

const URL = "https://api.docbase.io/teams/{チーム名}/posts"

func create(day int) error {
	date := time.Now().AddDate(0, 0, day).Format("2006/01/02")
	GROUP_ID, err := strconv.Atoi(os.Getenv("DOCBASE_GROUP_ID"))
	if err != nil {
		return err
	}

	// 置き換え用文字列を置換
	r := strings.NewReplacer("{日付記入欄}", date, "{参加者}", os.Getenv("MEMBERS"))
	rBody := r.Replace(TPL_BODY)

	params := &param{
		Title:  "タイトル " + date,
		Body:   rBody,
		Tags:   []string{"議事録", "チームのタグ"},
		Scope:  "group",
		Groups: []int{GROUP_ID},
	}
	jsonParam, err := json.Marshal(params)
	if err != nil {
		return err
	}

	// メモの新規作成
	req, err := http.NewRequest(http.MethodPost, URL, bytes.NewBuffer(jsonParam))
	if err != nil {
		return err
	}

	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("X-DocBaseToken", os.Getenv("DOCBASE_TOKEN"))

	client := new(http.Client)
	res, err := client.Do(req)
	if err != nil {
		return err
	}
	res.Body.Close()
}

issueの記入

こちらは以下の処理の流れで実装を行いました。

1.メモの検索APIを使用し更新する議事録を取得
2. github APIを使用してリポジトリごとにissueを取得し、 [issueのタイトル](リンク)のmdに変換
3. 作成したissueパートの文章を本文に記入・更新を行う

issue.go
func Handler() error {
	searchRes, err := search() // 該当議事録の検索
	if err != nil {
		return err
	}
	txt := issue() // issueの収集
	body := strings.Replace(searchRes.Body, "{issue起票置き換え}", txt, 1)
	err = updateBody(body, searchRes.ID) // 議事録の更新
	if err != nil {
		return err
	}
	return nil
}

コンパイル ~ EventBridgeの設定

作成したlambda関数のコードはコンパイルしてzip化し lambdaにアップロードする必要はあるのでコンパイル〜zip化をしていきます

公式ドキュメントには記述がありませんが、実行環境がM1Macの場合、
fork/exec /var/task/main: exec format errorというエラーが発生します。
こちらのエラーはGOARCH=amd64を追加することで回避することができます。

	GOARCH=amd64 GOOS=linux go build main.go
	zip function.zip main

lambda関数を作成しzip化したコードをコンパイル後、EventBridgeにlambdaを紐付けて作成します。この時定数パラメーターを設定することで、先ほど述べた通り実行したいバッチ処理を指定することができます。

mosaic_20221217233902.png

終わり

今回は定例議事録の作成を定期バッチ化させました。
自分が普段使っているサービスのAPIを調べてみると、意外な発見があり効率化に結びつくことがあるので皆さんも是非確認して見てください!

21
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?