mirror of
https://github.com/taigrr/github-to-signal.git
synced 2026-04-02 11:19:15 -07:00
Set signal_group_id in config to send to a group instead of a DM. Group ID takes priority over signal_recipient when both are set.
155 lines
4.4 KiB
Go
155 lines
4.4 KiB
Go
// github-to-signal is an HTTP server that receives GitHub webhook events
|
|
// and forwards formatted notifications to Signal via signal-cli's JSON-RPC API.
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
|
|
"github.com/cbrgm/githubevents/v2/githubevents"
|
|
"github.com/google/go-github/v70/github"
|
|
"github.com/taigrr/signalcli"
|
|
)
|
|
|
|
func main() {
|
|
cfg := loadConfig()
|
|
|
|
if cfg.SignalAccount == "" {
|
|
log.Fatal("signal_account is required (set GH2SIG_SIGNAL_ACCOUNT or config.toml)")
|
|
}
|
|
if cfg.SignalRecipient == "" && cfg.SignalGroupID == "" {
|
|
log.Fatal("signal_recipient or signal_group_id is required")
|
|
}
|
|
|
|
signal := signalcli.NewClient(cfg.SignalURL, cfg.SignalAccount)
|
|
handle := githubevents.New(cfg.WebhookSecret)
|
|
|
|
notifier := ¬ifier{
|
|
signal: signal,
|
|
recipient: cfg.SignalRecipient,
|
|
groupID: cfg.SignalGroupID,
|
|
}
|
|
|
|
// Register event handlers.
|
|
handle.OnPushEventAny(notifier.onPush)
|
|
handle.OnIssuesEventAny(notifier.onIssue)
|
|
handle.OnIssueCommentEventAny(notifier.onIssueComment)
|
|
handle.OnPullRequestEventAny(notifier.onPR)
|
|
handle.OnPullRequestReviewEventAny(notifier.onPRReview)
|
|
handle.OnPullRequestReviewCommentEventAny(notifier.onPRReviewComment)
|
|
handle.OnReleaseEventAny(notifier.onRelease)
|
|
handle.OnStarEventAny(notifier.onStar)
|
|
handle.OnForkEventAny(notifier.onFork)
|
|
handle.OnWorkflowRunEventAny(notifier.onWorkflowRun)
|
|
handle.OnCreateEventAny(notifier.onCreate)
|
|
handle.OnDeleteEventAny(notifier.onDelete)
|
|
|
|
handle.OnError(func(_ context.Context, _ string, _ string, _ interface{}, err error) error {
|
|
log.Printf("webhook error: %v", err)
|
|
return nil
|
|
})
|
|
|
|
mux := http.NewServeMux()
|
|
mux.HandleFunc("POST /webhook", func(w http.ResponseWriter, r *http.Request) {
|
|
if err := handle.HandleEventRequest(r); err != nil {
|
|
log.Printf("handle event: %v", err)
|
|
http.Error(w, "webhook processing failed", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
w.WriteHeader(http.StatusOK)
|
|
})
|
|
mux.HandleFunc("GET /health", func(w http.ResponseWriter, _ *http.Request) {
|
|
w.WriteHeader(http.StatusOK)
|
|
fmt.Fprintln(w, "ok")
|
|
})
|
|
|
|
log.Printf("listening on %s", cfg.ListenAddr)
|
|
if err := http.ListenAndServe(cfg.ListenAddr, mux); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
|
|
type notifier struct {
|
|
signal *signalcli.Client
|
|
recipient string
|
|
groupID string
|
|
}
|
|
|
|
func (n *notifier) send(ctx context.Context, msg string) {
|
|
if msg == "" {
|
|
return
|
|
}
|
|
params := signalcli.SendParams{Message: msg}
|
|
if n.groupID != "" {
|
|
params.GroupID = n.groupID
|
|
} else {
|
|
params.Recipient = n.recipient
|
|
}
|
|
_, err := n.signal.Send(ctx, params)
|
|
if err != nil {
|
|
log.Printf("signal send error: %v", err)
|
|
}
|
|
}
|
|
|
|
func (n *notifier) onPush(ctx context.Context, _ string, _ string, event *github.PushEvent) error {
|
|
n.send(ctx, formatPush(event))
|
|
return nil
|
|
}
|
|
|
|
func (n *notifier) onIssue(ctx context.Context, _ string, _ string, event *github.IssuesEvent) error {
|
|
n.send(ctx, formatIssue(event))
|
|
return nil
|
|
}
|
|
|
|
func (n *notifier) onIssueComment(ctx context.Context, _ string, _ string, event *github.IssueCommentEvent) error {
|
|
n.send(ctx, formatIssueComment(event))
|
|
return nil
|
|
}
|
|
|
|
func (n *notifier) onPR(ctx context.Context, _ string, _ string, event *github.PullRequestEvent) error {
|
|
n.send(ctx, formatPR(event))
|
|
return nil
|
|
}
|
|
|
|
func (n *notifier) onPRReview(ctx context.Context, _ string, _ string, event *github.PullRequestReviewEvent) error {
|
|
n.send(ctx, formatPRReview(event))
|
|
return nil
|
|
}
|
|
|
|
func (n *notifier) onPRReviewComment(ctx context.Context, _ string, _ string, event *github.PullRequestReviewCommentEvent) error {
|
|
n.send(ctx, formatPRReviewComment(event))
|
|
return nil
|
|
}
|
|
|
|
func (n *notifier) onRelease(ctx context.Context, _ string, _ string, event *github.ReleaseEvent) error {
|
|
n.send(ctx, formatRelease(event))
|
|
return nil
|
|
}
|
|
|
|
func (n *notifier) onStar(ctx context.Context, _ string, _ string, event *github.StarEvent) error {
|
|
n.send(ctx, formatStar(event))
|
|
return nil
|
|
}
|
|
|
|
func (n *notifier) onFork(ctx context.Context, _ string, _ string, event *github.ForkEvent) error {
|
|
n.send(ctx, formatFork(event))
|
|
return nil
|
|
}
|
|
|
|
func (n *notifier) onWorkflowRun(ctx context.Context, _ string, _ string, event *github.WorkflowRunEvent) error {
|
|
n.send(ctx, formatWorkflowRun(event))
|
|
return nil
|
|
}
|
|
|
|
func (n *notifier) onCreate(ctx context.Context, _ string, _ string, event *github.CreateEvent) error {
|
|
n.send(ctx, formatCreate(event))
|
|
return nil
|
|
}
|
|
|
|
func (n *notifier) onDelete(ctx context.Context, _ string, _ string, event *github.DeleteEvent) error {
|
|
n.send(ctx, formatDelete(event))
|
|
return nil
|
|
}
|