「GitHubでIssue作ったときに自動でコメントしてくれるBotあったらいいな〜」
そんな軽い気持ちで始めたGitHub Bot作り。最初は面倒そうだと思ってましたが、実際やってみたら意外とサクッとできました。
今回はGo言語でGitHub App(Bot)を個人開発した体験談として、実際にハマったポイントや「ここはこうした方がよかった」という話を共有します。
🎯 作ったもの
Issueが作成されると、こんな感じで自動コメントしてくれるBot:
🌸 @username さん、お疲れさまです!新しいIssueを作成していただき、ありがとうございます。一歩一歩、着実に進んでいきましょう ✨
シンプルですが、なんか温かみがあって気に入ってます。
🛠️ 使った技術スタック
- Go言語 - シンプルで書きやすい
- GitHub App - 公式の推奨方法
- ngrok - ローカル開発で外部公開
- go-github - GitHub API クライアント
📝 実際の開発手順
1. GitHub App作成(一番重要)
GitHub Settings から「New GitHub App」で作成。
設定で重要だったポイント:
GitHub App name: my-simple-bot
Webhook URL: 一旦 https://example.com/webhook (後で変更)
Webhook secret: mysecret123
Repository permissions:
- Issues: Read & write
Subscribe to events:
- Issues ✅
ここでハマった: 最初Webhook URLを空にしてActiveのチェックを外していたのですが、後でngrokのURL設定するとき手間でした。最初から仮のURLでも入れておくべきでした。
2. 必要な情報をメモ
- App ID: 作成後の画面に表示される
- Private key: 「Generate a private key」でダウンロード
- Webhook secret: 上で設定したやつ
この3つは後で環境変数で使います。
3. Go環境セットアップ
mkdir simple-github-bot
cd simple-github-bot
go mod init simple-github-bot
go get github.com/google/go-github/v29/github
go get github.com/bradleyfalzon/ghinstallation
4. コード実装
メインのコードはこんな感じです:
package main
import (
"context"
"fmt"
"log"
"net/http"
"os"
"strconv"
"time"
"github.com/bradleyfalzon/ghinstallation"
"github.com/google/go-github/v29/github"
)
func main() {
http.HandleFunc("/webhook", handleWebhook)
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "🤖 Bot is running!")
})
log.Println("🚀 Bot starting on port 8080...")
log.Fatal(http.ListenAndServe(":8080", nil))
}
func handleWebhook(w http.ResponseWriter, r *http.Request) {
secret := os.Getenv("WEBHOOK_SECRET")
payload, err := github.ValidatePayload(r, []byte(secret))
if err != nil {
log.Printf("❌ Invalid payload: %v", err)
http.Error(w, "Invalid payload", http.StatusBadRequest)
return
}
event, err := github.ParseWebHook(github.WebHookType(r), payload)
if err != nil {
log.Printf("❌ Parse error: %v", err)
http.Error(w, "Parse error", http.StatusBadRequest)
return
}
if issueEvent, ok := event.(*github.IssuesEvent); ok {
if issueEvent.GetAction() == "opened" {
handleIssueEvent(r.Context(), issueEvent)
}
}
w.WriteHeader(http.StatusOK)
}
func handleIssueEvent(ctx context.Context, event *github.IssuesEvent) {
log.Printf("📝 New issue: %s", event.GetIssue().GetTitle())
client, err := createGitHubClient(event.GetInstallation().GetID())
if err != nil {
log.Printf("❌ Failed to create client: %v", err)
return
}
user := event.GetIssue().GetUser().GetLogin()
comment := fmt.Sprintf(
"🌸 @%s さん、お疲れさまです!新しいIssueを作成していただき、ありがとうございます。一歩一歩、着実に進んでいきましょう ✨",
user,
)
issueComment := &github.IssueComment{Body: &comment}
_, _, err = client.Issues.CreateComment(
ctx,
event.GetRepo().GetOwner().GetLogin(),
event.GetRepo().GetName(),
event.GetIssue().GetNumber(),
issueComment,
)
if err != nil {
log.Printf("❌ Failed to post comment: %v", err)
return
}
log.Printf("✅ Comment posted successfully!")
}
func createGitHubClient(installationID int64) (*github.Client, error) {
appID, err := strconv.ParseInt(os.Getenv("GITHUB_APP_ID"), 10, 64)
if err != nil {
return nil, err
}
transport, err := ghinstallation.NewKeyFromFile(
http.DefaultTransport,
appID,
installationID,
"private-key.pem",
)
if err != nil {
return nil, err
}
return github.NewClient(&http.Client{
Transport: transport,
Timeout: 10 * time.Second,
}), nil
}
5. ローカルテスト
環境変数設定:
export GITHUB_APP_ID=123456
export WEBHOOK_SECRET=mysecret123
ngrokで外部公開:
# 別ターミナルで
ngrok http 8080
GitHub AppのWebhook URL更新:
ngrokで表示されたhttps URLを使って https://abc123.ngrok.io/webhook
に変更。
Botを起動:
go run main.go
6. 動作確認
GitHub AppをリポジトリにインストールしてIssueを作成。うまくいけばBotがコメントしてくれます!
😅 実際にハマったポイント
1. 秘密鍵のファイル名
ダウンロードした秘密鍵ファイルが app-name.2025-05-27.private-key.pem
みたいな長い名前だったので、private-key.pem
にリネームするのを忘れてました。
2. Installation IDの取得
最初はInstallation IDをハードコードしてましたが、Webhookのペイロードから取得する方が正しいです。複数のリポジトリにインストールする可能性もありますしね。
3. Webhook検証を後回しにした
最初は検証なしで作ってましたが、セキュリティ的によくないので早めに実装すべきでした。github.ValidatePayload
で簡単にできます。
💡 改善案・拡張アイデア
今回作ったのはシンプルなBotでしたが、以下のような拡張も面白そうです:
- AI連携: ChatGPT APIと連携してより賢いコメント
- ラベル自動付与: Issue内容を解析して適切なラベルを自動追加
- プルリクエスト対応: PRにも自動レビューコメント
- Slack通知: 重要なIssueをSlackにも通知
🎉 まとめ
Go言語でGitHub Bot作るのは思ったより簡単でした!特に:
- GitHub App: 公式の推奨方法で安全
- go-github: ライブラリが充実していて使いやすい
- ngrok: ローカル開発が楽になる
30分〜1時間もあれば基本的なBotは作れるので、何か自動化したいことがあったらぜひ試してみてください。
個人開発でも十分活用できますし、チーム開発なら更に威力を発揮しそうです。
参考リンク: