mirror of
https://github.com/taigrr/github-to-signal.git
synced 2026-04-02 03:09:09 -07:00
feat: initial github-to-signal webhook server
HTTP server that receives GitHub webhook events and sends formatted notifications to Signal via signal-cli's JSON-RPC API. Supported events: push, issues, issue comments, pull requests, PR reviews, PR review comments, releases, stars, forks, workflow runs, branch/tag creation, branch/tag deletion. Uses cbrgm/githubevents for webhook handling and taigrr/signalcli for Signal delivery. Config via TOML file or GH2SIG_ env vars (powered by taigrr/jety).
This commit is contained in:
9
.gitignore
vendored
Normal file
9
.gitignore
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
# Binaries
|
||||
github-to-signal
|
||||
*.exe
|
||||
|
||||
# Config with secrets
|
||||
config.toml
|
||||
config.yaml
|
||||
config.json
|
||||
*.env
|
||||
12
LICENSE
Normal file
12
LICENSE
Normal file
@@ -0,0 +1,12 @@
|
||||
Copyright (C) 2026 Tai Groot
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
THIS SOFTWARE.
|
||||
19
README.md
Normal file
19
README.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# github-to-signal
|
||||
|
||||
HTTP server that receives GitHub webhook events and forwards them as Signal messages via [signal-cli](https://github.com/AsamK/signal-cli).
|
||||
|
||||
## Events
|
||||
|
||||
Push, issues, issue comments, pull requests, PR reviews, PR review comments, releases, stars, forks, workflow runs, branch/tag creation and deletion.
|
||||
|
||||
## Setup
|
||||
|
||||
1. Copy `config.example.toml` to `config.toml` and fill in values
|
||||
2. Run the server: `go run .`
|
||||
3. Add a webhook in your GitHub repo pointing to `https://your-host:9900/webhook`
|
||||
|
||||
All config values can also be set via environment variables with `GH2SIG_` prefix (e.g. `GH2SIG_SIGNAL_ACCOUNT`).
|
||||
|
||||
## Requirements
|
||||
|
||||
- [signal-cli](https://github.com/AsamK/signal-cli) running in daemon mode with JSON-RPC enabled
|
||||
14
config.example.toml
Normal file
14
config.example.toml
Normal file
@@ -0,0 +1,14 @@
|
||||
# GitHub webhook secret (set in your GitHub webhook settings)
|
||||
webhook_secret = ""
|
||||
|
||||
# Address to listen on
|
||||
listen_addr = ":9900"
|
||||
|
||||
# signal-cli JSON-RPC endpoint
|
||||
signal_url = "http://127.0.0.1:8080"
|
||||
|
||||
# signal-cli account (phone number registered with signal-cli)
|
||||
signal_account = "+1234567890"
|
||||
|
||||
# Signal recipient UUID or phone number to send notifications to
|
||||
signal_recipient = ""
|
||||
35
config.go
Normal file
35
config.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package main
|
||||
|
||||
import "github.com/taigrr/jety"
|
||||
|
||||
// Config holds the application configuration.
|
||||
type Config struct {
|
||||
// ListenAddr is the address to bind the webhook server to.
|
||||
ListenAddr string
|
||||
// WebhookSecret is the GitHub webhook secret for signature validation.
|
||||
WebhookSecret string
|
||||
// SignalURL is the signal-cli JSON-RPC base URL.
|
||||
SignalURL string
|
||||
// SignalAccount is the signal-cli account (phone number or UUID).
|
||||
SignalAccount string
|
||||
// SignalRecipient is the default Signal recipient for notifications.
|
||||
SignalRecipient string
|
||||
}
|
||||
|
||||
func loadConfig() Config {
|
||||
jety.SetDefault("listen_addr", ":9900")
|
||||
jety.SetDefault("signal_url", "http://127.0.0.1:8080")
|
||||
|
||||
jety.SetEnvPrefix("GH2SIG")
|
||||
jety.SetConfigFile("config.toml")
|
||||
jety.SetConfigType("toml")
|
||||
_ = jety.ReadInConfig()
|
||||
|
||||
return Config{
|
||||
ListenAddr: jety.GetString("listen_addr"),
|
||||
WebhookSecret: jety.GetString("webhook_secret"),
|
||||
SignalURL: jety.GetString("signal_url"),
|
||||
SignalAccount: jety.GetString("signal_account"),
|
||||
SignalRecipient: jety.GetString("signal_recipient"),
|
||||
}
|
||||
}
|
||||
206
format.go
Normal file
206
format.go
Normal file
@@ -0,0 +1,206 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/google/go-github/v70/github"
|
||||
)
|
||||
|
||||
// formatPush formats a push event into a Signal message.
|
||||
func formatPush(event *github.PushEvent) string {
|
||||
repo := event.GetRepo().GetFullName()
|
||||
ref := strings.TrimPrefix(event.GetRef(), "refs/heads/")
|
||||
pusher := event.GetPusher().GetName()
|
||||
count := len(event.Commits)
|
||||
|
||||
var sb strings.Builder
|
||||
sb.WriteString(fmt.Sprintf("[%s] %s pushed %d commit", repo, pusher, count))
|
||||
if count != 1 {
|
||||
sb.WriteString("s")
|
||||
}
|
||||
sb.WriteString(fmt.Sprintf(" to %s\n", ref))
|
||||
|
||||
for _, commit := range event.Commits {
|
||||
short := commit.GetID()
|
||||
if len(short) > 7 {
|
||||
short = short[:7]
|
||||
}
|
||||
msg := firstLine(commit.GetMessage())
|
||||
sb.WriteString(fmt.Sprintf(" %s %s\n", short, msg))
|
||||
}
|
||||
|
||||
return strings.TrimSpace(sb.String())
|
||||
}
|
||||
|
||||
// formatIssue formats an issue event into a Signal message.
|
||||
func formatIssue(event *github.IssuesEvent) string {
|
||||
repo := event.GetRepo().GetFullName()
|
||||
action := event.GetAction()
|
||||
issue := event.GetIssue()
|
||||
sender := event.GetSender().GetLogin()
|
||||
|
||||
msg := fmt.Sprintf("[%s] %s %s issue #%d: %s\n%s",
|
||||
repo, sender, action, issue.GetNumber(), issue.GetTitle(), issue.GetHTMLURL())
|
||||
|
||||
if action == "opened" && issue.GetBody() != "" {
|
||||
body := truncate(issue.GetBody(), 200)
|
||||
msg += "\n\n" + body
|
||||
}
|
||||
|
||||
return msg
|
||||
}
|
||||
|
||||
// formatIssueComment formats an issue comment event into a Signal message.
|
||||
func formatIssueComment(event *github.IssueCommentEvent) string {
|
||||
repo := event.GetRepo().GetFullName()
|
||||
sender := event.GetSender().GetLogin()
|
||||
issue := event.GetIssue()
|
||||
comment := event.GetComment()
|
||||
|
||||
body := truncate(comment.GetBody(), 300)
|
||||
|
||||
return fmt.Sprintf("[%s] %s commented on #%d (%s):\n%s\n%s",
|
||||
repo, sender, issue.GetNumber(), issue.GetTitle(), body, comment.GetHTMLURL())
|
||||
}
|
||||
|
||||
// formatPR formats a pull request event into a Signal message.
|
||||
func formatPR(event *github.PullRequestEvent) string {
|
||||
repo := event.GetRepo().GetFullName()
|
||||
action := event.GetAction()
|
||||
pr := event.GetPullRequest()
|
||||
sender := event.GetSender().GetLogin()
|
||||
|
||||
msg := fmt.Sprintf("[%s] %s %s PR #%d: %s\n%s",
|
||||
repo, sender, action, pr.GetNumber(), pr.GetTitle(), pr.GetHTMLURL())
|
||||
|
||||
if action == "opened" && pr.GetBody() != "" {
|
||||
body := truncate(pr.GetBody(), 200)
|
||||
msg += "\n\n" + body
|
||||
}
|
||||
|
||||
return msg
|
||||
}
|
||||
|
||||
// formatPRReview formats a pull request review event into a Signal message.
|
||||
func formatPRReview(event *github.PullRequestReviewEvent) string {
|
||||
repo := event.GetRepo().GetFullName()
|
||||
sender := event.GetSender().GetLogin()
|
||||
pr := event.GetPullRequest()
|
||||
review := event.GetReview()
|
||||
|
||||
state := review.GetState()
|
||||
body := truncate(review.GetBody(), 200)
|
||||
|
||||
msg := fmt.Sprintf("[%s] %s %s PR #%d: %s\n%s",
|
||||
repo, sender, state, pr.GetNumber(), pr.GetTitle(), review.GetHTMLURL())
|
||||
|
||||
if body != "" {
|
||||
msg += "\n\n" + body
|
||||
}
|
||||
|
||||
return msg
|
||||
}
|
||||
|
||||
// formatPRReviewComment formats a pull request review comment event.
|
||||
func formatPRReviewComment(event *github.PullRequestReviewCommentEvent) string {
|
||||
repo := event.GetRepo().GetFullName()
|
||||
sender := event.GetSender().GetLogin()
|
||||
pr := event.GetPullRequest()
|
||||
comment := event.GetComment()
|
||||
|
||||
body := truncate(comment.GetBody(), 300)
|
||||
|
||||
return fmt.Sprintf("[%s] %s commented on PR #%d (%s):\n%s\n%s",
|
||||
repo, sender, pr.GetNumber(), pr.GetTitle(), body, comment.GetHTMLURL())
|
||||
}
|
||||
|
||||
// formatRelease formats a release event into a Signal message.
|
||||
func formatRelease(event *github.ReleaseEvent) string {
|
||||
repo := event.GetRepo().GetFullName()
|
||||
release := event.GetRelease()
|
||||
sender := event.GetSender().GetLogin()
|
||||
|
||||
return fmt.Sprintf("[%s] %s %s release %s\n%s",
|
||||
repo, sender, event.GetAction(), release.GetTagName(), release.GetHTMLURL())
|
||||
}
|
||||
|
||||
// formatStar formats a star event into a Signal message.
|
||||
func formatStar(event *github.StarEvent) string {
|
||||
repo := event.GetRepo().GetFullName()
|
||||
sender := event.GetSender().GetLogin()
|
||||
action := event.GetAction()
|
||||
count := event.GetRepo().GetStargazersCount()
|
||||
|
||||
if action == "deleted" {
|
||||
return fmt.Sprintf("[%s] %s unstarred (now %d)", repo, sender, count)
|
||||
}
|
||||
return fmt.Sprintf("[%s] %s starred (now %d)", repo, sender, count)
|
||||
}
|
||||
|
||||
// formatFork formats a fork event into a Signal message.
|
||||
func formatFork(event *github.ForkEvent) string {
|
||||
repo := event.GetRepo().GetFullName()
|
||||
forkee := event.GetForkee().GetFullName()
|
||||
sender := event.GetSender().GetLogin()
|
||||
|
||||
return fmt.Sprintf("[%s] %s forked to %s", repo, sender, forkee)
|
||||
}
|
||||
|
||||
// formatWorkflowRun formats a workflow run event into a Signal message.
|
||||
func formatWorkflowRun(event *github.WorkflowRunEvent) string {
|
||||
repo := event.GetRepo().GetFullName()
|
||||
run := event.GetWorkflowRun()
|
||||
conclusion := run.GetConclusion()
|
||||
name := run.GetName()
|
||||
branch := run.GetHeadBranch()
|
||||
|
||||
// Only notify on completion
|
||||
if event.GetAction() != "completed" {
|
||||
return ""
|
||||
}
|
||||
|
||||
emoji := "✅"
|
||||
if conclusion == "failure" {
|
||||
emoji = "❌"
|
||||
} else if conclusion == "cancelled" {
|
||||
emoji = "⚠️"
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s [%s] workflow %q %s on %s\n%s",
|
||||
emoji, repo, name, conclusion, branch, run.GetHTMLURL())
|
||||
}
|
||||
|
||||
// formatCreate formats a create event (branch/tag) into a Signal message.
|
||||
func formatCreate(event *github.CreateEvent) string {
|
||||
repo := event.GetRepo().GetFullName()
|
||||
sender := event.GetSender().GetLogin()
|
||||
refType := event.GetRefType()
|
||||
ref := event.GetRef()
|
||||
|
||||
return fmt.Sprintf("[%s] %s created %s %s", repo, sender, refType, ref)
|
||||
}
|
||||
|
||||
// formatDelete formats a delete event (branch/tag) into a Signal message.
|
||||
func formatDelete(event *github.DeleteEvent) string {
|
||||
repo := event.GetRepo().GetFullName()
|
||||
sender := event.GetSender().GetLogin()
|
||||
refType := event.GetRefType()
|
||||
ref := event.GetRef()
|
||||
|
||||
return fmt.Sprintf("[%s] %s deleted %s %s", repo, sender, refType, ref)
|
||||
}
|
||||
|
||||
func firstLine(s string) string {
|
||||
if idx := strings.IndexByte(s, '\n'); idx >= 0 {
|
||||
return s[:idx]
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func truncate(s string, maxLen int) string {
|
||||
if len(s) <= maxLen {
|
||||
return s
|
||||
}
|
||||
return s[:maxLen] + "..."
|
||||
}
|
||||
18
go.mod
Normal file
18
go.mod
Normal file
@@ -0,0 +1,18 @@
|
||||
module github.com/taigrr/github-to-signal
|
||||
|
||||
go 1.26.0
|
||||
|
||||
require (
|
||||
github.com/cbrgm/githubevents/v2 v2.2.0
|
||||
github.com/google/go-github/v70 v70.0.0
|
||||
github.com/taigrr/jety v0.2.0
|
||||
github.com/taigrr/signalcli v0.0.0-20260301154901-6aed09f3f2af
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.6.0 // indirect
|
||||
github.com/google/go-querystring v1.2.0 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
golang.org/x/sync v0.12.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
23
go.sum
Normal file
23
go.sum
Normal file
@@ -0,0 +1,23 @@
|
||||
github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk=
|
||||
github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||
github.com/cbrgm/githubevents/v2 v2.2.0 h1:nttKcls+vGtq+osxirM1qpY287hkXyJmTjHWHjQT1/A=
|
||||
github.com/cbrgm/githubevents/v2 v2.2.0/go.mod h1:3J4oJkVO5NlZNEtEyUb8B7sW7+q8OZgHdTBvw9dPsMs=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/go-github/v70 v70.0.0 h1:/tqCp5KPrcvqCc7vIvYyFYTiCGrYvaWoYMGHSQbo55o=
|
||||
github.com/google/go-github/v70 v70.0.0/go.mod h1:xBUZgo8MI3lUL/hwxl3hlceJW1U8MVnXP3zUyI+rhQY=
|
||||
github.com/google/go-querystring v1.2.0 h1:yhqkPbu2/OH+V9BfpCVPZkNmUXhb2gBxJArfhIxNtP0=
|
||||
github.com/google/go-querystring v1.2.0/go.mod h1:8IFJqpSRITyJ8QhQ13bmbeMBDfmeEJZD5A0egEOmkqU=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/taigrr/jety v0.2.0 h1:oGv6i1yBxdV5YnRD4f7V9Nv74PxY0kVIXCTJsRkqgmo=
|
||||
github.com/taigrr/jety v0.2.0/go.mod h1:PtJDxNFDqR6739at6QrjlE4MGf/zcs21Y86KVQMKPEk=
|
||||
github.com/taigrr/signalcli v0.0.0-20260301154901-6aed09f3f2af h1:qavmWkSyV3NeiZ+HHVj1I/6c8VQosUKFV1SfN1X/4DM=
|
||||
github.com/taigrr/signalcli v0.0.0-20260301154901-6aed09f3f2af/go.mod h1:Jgly+nAwowk5O5ZUXSAAxCOVK9nlsAvPIfdNg5kXWSM=
|
||||
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
|
||||
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
149
main.go
Normal file
149
main.go
Normal file
@@ -0,0 +1,149 @@
|
||||
// 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 == "" {
|
||||
log.Fatal("signal_recipient is required (set GH2SIG_SIGNAL_RECIPIENT or config.toml)")
|
||||
}
|
||||
|
||||
signal := signalcli.NewClient(cfg.SignalURL, cfg.SignalAccount)
|
||||
handle := githubevents.New(cfg.WebhookSecret)
|
||||
|
||||
notifier := ¬ifier{
|
||||
signal: signal,
|
||||
recipient: cfg.SignalRecipient,
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
func (n *notifier) send(ctx context.Context, msg string) {
|
||||
if msg == "" {
|
||||
return
|
||||
}
|
||||
_, err := n.signal.Send(ctx, signalcli.SendParams{
|
||||
Recipient: n.recipient,
|
||||
Message: msg,
|
||||
})
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user