golang实现GitHub和Bitbucket的Webhook接收功能插件库webhooks的使用
Golang实现GitHub和Bitbucket的Webhook接收功能插件库webhooks的使用
简介
webhooks库可以方便地接收和解析GitHub、Bitbucket、GitLab、Docker Hub、Gogs和Azure DevOps的Webhook事件。
主要特性:
- 解析整个payload,而不仅仅是几个字段
- 字段和结构直接对应webhook发布的json
注意事项:
- 目前仅接受json payload
安装
使用go get安装:
go get -u github.com/go-playground/webhooks/v6
然后在代码中导入包:
import "github.com/go-playground/webhooks/v6"
使用示例
GitHub Webhook示例
package main
import (
"fmt"
"net/http"
"github.com/go-playground/webhooks/v6/github"
)
const (
path = "/webhooks"
)
func main() {
// 创建GitHub webhook实例,设置secret
hook, _ := github.New(github.Options.Secret("MyGitHubSuperSecretSecret...?"))
// 设置HTTP处理函数
http.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
// 解析请求,只处理ReleaseEvent和PullRequestEvent
payload, err := hook.Parse(r, github.ReleaseEvent, github.PullRequestEvent)
if err != nil {
if err == github.ErrEventNotFound {
// 事件不是我们要处理的类型
}
}
// 根据事件类型处理
switch payload.(type) {
case github.ReleasePayload:
release := payload.(github.ReleasePayload)
// 处理release事件...
fmt.Printf("%+v", release)
case github.PullRequestPayload:
pullRequest := payload.(github.PullRequestPayload)
// 处理pull request事件...
fmt.Printf("%+v", pullRequest)
}
})
// 启动HTTP服务器
http.ListenAndServe(":3000", nil)
}
Bitbucket Webhook示例
package main
import (
"fmt"
"net/http"
"github.com/go-playground/webhooks/v6/bitbucket"
)
const (
path = "/webhooks"
)
func main() {
// 创建Bitbucket webhook实例
hook, _ := bitbucket.New(bitbucket.Options.Secret("MyBitbucketSecret"))
http.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
// 解析请求,处理Push和PullRequest事件
payload, err := hook.Parse(r, bitbucket.RepoPushEvent, bitbucket.PullRequestCreatedEvent)
if err != nil {
if err == bitbucket.ErrEventNotFound {
// 事件不是我们要处理的类型
}
}
switch payload.(type) {
case bitbucket.RepoPushPayload:
push := payload.(bitbucket.RepoPushPayload)
// 处理push事件...
fmt.Printf("Received push: %+v", push)
case bitbucket.PullRequestCreatedPayload:
pr := payload.(bitbucket.PullRequestCreatedPayload)
// 处理pull request创建事件...
fmt.Printf("New PR created: %+v", pr)
}
})
http.ListenAndServe(":3000", nil)
}
注意事项
- 确保在GitHub/Bitbucket的webhook设置中使用相同的secret
- 服务器需要能够从公网访问,才能接收webhook通知
- 根据实际需求处理不同的事件类型
- 生产环境中建议添加更多的错误处理和日志记录
贡献
欢迎提交其他服务的pull request!如果是破坏性变更,请先创建issue讨论。
许可证
基于MIT许可证分发,更多细节请查看代码中的许可证文件。
更多关于golang实现GitHub和Bitbucket的Webhook接收功能插件库webhooks的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang实现GitHub和Bitbucket的Webhook接收功能插件库webhooks的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用webhooks库实现GitHub和Bitbucket的Webhook接收
下面我将介绍如何使用golang的webhooks库来接收GitHub和Bitbucket的Webhook通知,并提供完整的示例代码。
安装webhooks库
首先安装webhooks库:
go get github.com/go-playground/webhooks/v6
GitHub Webhook接收实现
package main
import (
"fmt"
"net/http"
"os"
"github.com/go-playground/webhooks/v6/github"
)
const (
path = "/webhooks"
)
func main() {
// 从环境变量获取GitHub的webhook secret
secret := os.Getenv("GITHUB_WEBHOOK_SECRET")
if secret == "" {
panic("GITHUB_WEBHOOK_SECRET environment variable not set")
}
// 创建GitHub webhook实例
hook, err := github.New(github.Options.Secret(secret))
if err != nil {
panic(err)
}
// 注册HTTP处理函数
http.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
// 解析GitHub事件
payload, err := hook.Parse(r,
github.PushEvent,
github.PullRequestEvent,
github.IssuesEvent,
)
if err != nil {
if err == github.ErrEventNotFound {
// 事件类型未注册
fmt.Printf("Unregistered event: %v\n", err)
w.WriteHeader(http.StatusOK)
return
}
fmt.Printf("Error parsing webhook: %v\n", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
// 根据事件类型处理payload
switch payload := payload.(type) {
case github.PushPayload:
// 处理push事件
fmt.Printf("Received push event on %s\n", payload.Repository.FullName)
fmt.Printf("Commit by %s: %s\n", payload.Pusher.Name, payload.HeadCommit.Message)
case github.PullRequestPayload:
// 处理pull request事件
fmt.Printf("Received PR event: %s %s\n", payload.Action, payload.PullRequest.Title)
case github.IssuesPayload:
// 处理issues事件
fmt.Printf("Received issue event: %s %s\n", payload.Action, payload.Issue.Title)
}
w.WriteHeader(http.StatusOK)
})
// 启动HTTP服务器
fmt.Println("Server listening on :8080")
http.ListenAndServe(":8080", nil)
}
Bitbucket Webhook接收实现
package main
import (
"fmt"
"net/http"
"os"
"github.com/go-playground/webhooks/v6/bitbucket"
)
const (
path = "/webhooks"
)
func main() {
// 从环境变量获取Bitbucket的webhook secret
secret := os.Getenv("BITBUCKET_WEBHOOK_SECRET")
if secret == "" {
panic("BITBUCKET_WEBHOOK_SECRET environment variable not set")
}
// 创建Bitbucket webhook实例
hook, err := bitbucket.New(bitbucket.Options.Secret(secret))
if err != nil {
panic(err)
}
// 注册HTTP处理函数
http.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
// 解析Bitbucket事件
payload, err := hook.Parse(r,
bitbucket.RepoPushEvent,
bitbucket.PullRequestCreatedEvent,
bitbucket.PullRequestUpdatedEvent,
)
if err != nil {
if err == bitbucket.ErrEventNotFound {
// 事件类型未注册
fmt.Printf("Unregistered event: %v\n", err)
w.WriteHeader(http.StatusOK)
return
}
fmt.Printf("Error parsing webhook: %v\n", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
// 根据事件类型处理payload
switch payload := payload.(type) {
case bitbucket.RepoPushPayload:
// 处理push事件
fmt.Printf("Received push event on %s\n", payload.Repository.FullName)
for _, change := range payload.Push.Changes {
fmt.Printf("Change: %s -> %s\n", change.Old.Name, change.New.Name)
}
case bitbucket.PullRequestPayload:
// 处理pull request事件
fmt.Printf("Received PR event: %s %s\n", payload.PullRequest.Title, payload.Actor.DisplayName)
}
w.WriteHeader(http.StatusOK)
})
// 启动HTTP服务器
fmt.Println("Server listening on :8080")
http.ListenAndServe(":8080", nil)
}
配置说明
-
Webhook Secret:
- 从环境变量获取secret,确保安全性
- 需要在GitHub/Bitbucket的webhook设置中配置相同的secret
-
事件类型:
- 代码中只注册了部分事件类型,可以根据需要添加更多
- 完整的事件类型列表参考webhooks库文档
-
部署:
- 需要将服务部署到公网可访问的地址
- 在GitHub/Bitbucket的仓库设置中配置webhook URL
高级功能
- 同时支持多个平台:
func main() {
// 初始化GitHub和Bitbucket的hook
githubHook, _ := github.New(github.Options.Secret(os.Getenv("GITHUB_SECRET")))
bitbucketHook, _ := bitbucket.New(bitbucket.Options.Secret(os.Getenv("BITBUCKET_SECRET")))
http.HandleFunc("/webhooks", func(w http.ResponseWriter, r *http.Request) {
// 根据请求头判断来源
switch r.Header.Get("X-GitHub-Event") {
case "push", "pull_request":
handleGitHub(githubHook, w, r)
case "repo:push", "pullrequest:created":
handleBitbucket(bitbucketHook, w, r)
default:
w.WriteHeader(http.StatusBadRequest)
}
})
http.ListenAndServe(":8080", nil)
}
- 添加中间件:
func authMiddleware(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
// 验证IP白名单或其他认证逻辑
if !isAllowed(r.RemoteAddr) {
w.WriteHeader(http.StatusForbidden)
return
}
next(w, r)
}
}
func main() {
http.HandleFunc("/webhooks", authMiddleware(handleWebhook))
}
总结
使用webhooks库可以方便地接收和处理GitHub和Bitbucket的webhook通知。主要步骤包括:
- 初始化对应平台的hook实例
- 注册需要处理的事件类型
- 实现HTTP处理函数解析payload
- 根据不同类型的事件进行相应处理
这个库简化了webhook的验证和解析过程,让开发者可以专注于业务逻辑的实现。