Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions comment.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package main

import (
"bytes"
"crypto/rand"
"encoding/hex"
"encoding/json"
"fmt"
"net/http"
)

// GenerateIdempotencyKey 生成一个随机的幂等键,用于 POST 请求防止重复提交。
// 返回 16 字节的十六进制字符串。
func GenerateIdempotencyKey() (string, error) {
b := make([]byte, 16)
_, err := rand.Read(b)
if err != nil {
return "", fmt.Errorf("failed to generate idempotency key: %w", err)
}
return hex.EncodeToString(b), nil
}

// setIdempotencyHeader 向 HTTP 请求中添加幂等键头。
func setIdempotencyHeader(req *http.Request) error {
key, err := GenerateIdempotencyKey()
if err != nil {
return err
}
req.Header.Set("X-GitHub-Idempotency-Key", key)
return nil
}

// PostComment 向指定 URL 发送 POST 请求,自动生成并添加幂等键。
// body 将被序列化为 JSON。返回 HTTP 响应和可能的错误。
func PostComment(client *http.Client, url string, body interface{}) (*http.Response, error) {
jsonBody, err := json.Marshal(body)
if err != nil {
return nil, fmt.Errorf("failed to marshal body: %w", err)
}

req, err := http.NewRequest("POST", url, bytes.NewReader(jsonBody))
if err != nil {
return nil, fmt.Errorf("failed to create request: %w", err)
}
req.Header.Set("Content-Type", "application/json")

// 添加幂等键头
if err := setIdempotencyHeader(req); err != nil {
return nil, fmt.Errorf("failed to set idempotency key: %w", err)
}

return client.Do(req)
}
22 changes: 21 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,27 @@
package main

import "fmt"
import (
"fmt"
"log"
"net/http"
"time"
)

func main() {
fmt.Println("Hello, Bounty Hunter!")

// 演示使用幂等键发送评论 POST 请求
// 实际使用时,请替换为真实的 GitHub API 评论 URL 和 Token
client := &http.Client{Timeout: 10 * time.Second}
commentBody := map[string]string{"body": "This is a test comment with idempotency key."}
url := "https://api.github.com/repos/owner/repo/issues/1/comments"

resp, err := PostComment(client, url, commentBody)
if err != nil {
log.Printf("Failed to post comment: %v", err)
return
}
defer resp.Body.Close()

fmt.Printf("Comment posted, status: %s\n", resp.Status)
}