Skip to content

Commit

Permalink
feat: add --mastodon flag to ipsw watch to also annouce to Mastodon
Browse files Browse the repository at this point in the history
  • Loading branch information
blacktop committed Jan 12, 2025
1 parent f1128b5 commit 78b9cac
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 38 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/discord.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@ jobs:
sudo snap install ipsw
- name: Run ipsw watch WebKit/WebKit
run: |
/snap/bin/ipsw watch WebKit/WebKit --pattern '(?i)Lockdown Mode' --days 1 --cache watch-cache --api ${{ secrets.GITHUB_TOKEN }} --discord-id ${{ secrets.DISCORD_ID }} --discord-token ${{ secrets.DISCORD_TOKEN }} --discord-icon "https://raw.githubusercontent.com/blacktop/ipsw/master/www/static/img/webkit.png"
/snap/bin/ipsw watch apple-oss-distributions/distribution-macOS --tags --cache watch-cache --api ${{ secrets.GITHUB_TOKEN }} --discord-id ${{ secrets.DISCORD_ID }} --discord-token ${{ secrets.DISCORD_TOKEN }} --discord-icon "https://avatars.githubusercontent.com/u/91919287"
/snap/bin/ipsw watch WebKit/WebKit --pattern '(?i)Lockdown Mode' --days 1 --cache watch-cache --api ${{ secrets.GITHUB_TOKEN }} --discord --discord-id ${{ secrets.DISCORD_ID }} --discord-token ${{ secrets.DISCORD_TOKEN }} --discord-icon "https://raw.githubusercontent.com/blacktop/ipsw/master/www/static/img/webkit.png"
/snap/bin/ipsw watch apple-oss-distributions/distribution-macOS --tags --cache watch-cache --api ${{ secrets.GITHUB_TOKEN }} --discord --discord-id ${{ secrets.DISCORD_ID }} --discord-token ${{ secrets.DISCORD_TOKEN }} --discord-icon "https://avatars.githubusercontent.com/u/91919287"
109 changes: 78 additions & 31 deletions cmd/ipsw/cmd/watch.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"github.com/MakeNowJust/heredoc/v2"
"github.com/apex/log"
"github.com/blacktop/ipsw/internal/commands/watch"
"github.com/blacktop/ipsw/internal/commands/watch/announce"
"github.com/blacktop/ipsw/internal/download"
"github.com/fatih/color"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -71,9 +72,15 @@ func init() {
watchCmd.Flags().DurationP("timeout", "t", 0, "Timeout for watch attempts (default: 0s = no timeout/run once)")
watchCmd.Flags().StringP("command", "c", "", "Command to run on new commit")
watchCmd.Flags().Bool("post", false, "Create social media post for NEW tags")
watchCmd.Flags().Bool("discord", false, "Annouce to Discord")
watchCmd.Flags().String("discord-id", "", "Discord Webhook ID")
watchCmd.Flags().String("discord-token", "", "Discord Webhook Token")
watchCmd.Flags().String("discord-icon", "", "Discord Post Icon URL")
watchCmd.Flags().Bool("mastodon", false, "Annouce to Mastodon")
watchCmd.Flags().String("mastodon-server", "https://mastodon.social", "Mastodon Server URL")
watchCmd.Flags().String("mastodon-client-id", "", "Mastodon Client ID")
watchCmd.Flags().String("mastodon-client-secret", "", "Mastodon Client Secret")
watchCmd.Flags().String("mastodon-access-token", "", "Mastodon Access Token")
watchCmd.Flags().String("cache", "", "Cache file to store seen commits/tags")
viper.BindPFlag("watch.tags", watchCmd.Flags().Lookup("tags"))
viper.BindPFlag("watch.branch", watchCmd.Flags().Lookup("branch"))
Expand All @@ -85,9 +92,15 @@ func init() {
viper.BindPFlag("watch.timeout", watchCmd.Flags().Lookup("timeout"))
viper.BindPFlag("watch.command", watchCmd.Flags().Lookup("command"))
viper.BindPFlag("watch.post", watchCmd.Flags().Lookup("post"))
viper.BindPFlag("watch.discord", watchCmd.Flags().Lookup("discord"))
viper.BindPFlag("watch.discord-id", watchCmd.Flags().Lookup("discord-id"))
viper.BindPFlag("watch.discord-token", watchCmd.Flags().Lookup("discord-token"))
viper.BindPFlag("watch.discord-icon", watchCmd.Flags().Lookup("discord-icon"))
viper.BindPFlag("watch.mastodon", watchCmd.Flags().Lookup("mastodon"))
viper.BindPFlag("watch.mastodon-server", watchCmd.Flags().Lookup("mastodon-server"))
viper.BindPFlag("watch.mastodon-client-id", watchCmd.Flags().Lookup("mastodon-client-id"))
viper.BindPFlag("watch.mastodon-client-secret", watchCmd.Flags().Lookup("mastodon-client-secret"))
viper.BindPFlag("watch.mastodon-access-token", watchCmd.Flags().Lookup("mastodon-access-token"))
viper.BindPFlag("watch.cache", watchCmd.Flags().Lookup("cache"))
}

Expand Down Expand Up @@ -126,7 +139,8 @@ var watchCmd = &cobra.Command{
apiToken := viper.GetString("watch.api")
asJSON := viper.GetBool("watch.json")
postCommand := viper.GetString("watch.command")
annouce := false
discord := viper.GetBool("watch.discord")
mastodon := viper.GetBool("watch.mastodon")
// validate flags
if viper.GetBool("watch.tags") {
if viper.IsSet("watch.branch") {
Expand All @@ -152,9 +166,15 @@ var watchCmd = &cobra.Command{
return fmt.Errorf("commit watching is not supported with --post")
}
}

if viper.GetString("watch.discord-id") != "" && viper.GetString("watch.discord-token") != "" {
annouce = true
if discord {
if !viper.IsSet("watch.discord-id") || !viper.IsSet("watch.discord-token") {
return fmt.Errorf("--discord announce requires --discord-id and --discord-token")
}
}
if mastodon {
if !viper.IsSet("watch.mastodon-client-id") || !viper.IsSet("watch.mastodon-client-secret") || !viper.IsSet("watch.mastodon-access-token") {
return fmt.Errorf("--mastodon announce requires --mastodon-client-id, --mastodon-client-secret, and --mastodon-access-token")
}
}

if len(apiToken) == 0 {
Expand Down Expand Up @@ -208,22 +228,37 @@ var watchCmd = &cobra.Command{
}
}

if annouce {
iconURL := viper.GetString("watch.discord-icon")
if iconURL == "" {
iconURL = "https://github.githubassets.com/assets/GitHub-Mark-ea2971cee799.png"
}
if post == "" {
post = fmt.Sprintf("%s/%s\n\t - [%s](https://github.com/%s/%s/releases/tag/%s)", parts[0], parts[1], tags[0], parts[0], parts[1], tags[0])
if discord || mastodon {
if discord {
iconURL := viper.GetString("watch.discord-icon")
if iconURL == "" {
iconURL = "https://github.githubassets.com/assets/GitHub-Mark-ea2971cee799.png"
}
if post == "" {
post = fmt.Sprintf("%s/%s\n\t - [%s](https://github.com/%s/%s/releases/tag/%s)", parts[0], parts[1], tags[0], parts[0], parts[1], tags[0])
}
if err := announce.Discord(post, &announce.DiscordConfig{
DiscordWebhookID: viper.GetString("watch.discord-id"),
DiscordWebhookToken: viper.GetString("watch.discord-token"),
DiscordColor: "4535172",
DiscordAuthor: "🆕 TAG",
DiscordIconURL: iconURL,
}); err != nil {
return fmt.Errorf("discord announce failed: %v", err)
}
}
if err := watch.DiscordAnnounce(post, &watch.Config{
DiscordWebhookID: viper.GetString("watch.discord-id"),
DiscordWebhookToken: viper.GetString("watch.discord-token"),
DiscordColor: "4535172",
DiscordAuthor: "🆕 TAG",
DiscordIconURL: iconURL,
}); err != nil {
return fmt.Errorf("discord announce failed: %v", err)
if mastodon {
if post == "" {
post = fmt.Sprintf("%s/%s\n\t - [%s](https://github.com/%s/%s/releases/tag/%s)", parts[0], parts[1], tags[0], parts[0], parts[1], tags[0])
}
if err := announce.Mastodon(post, &announce.MastodonConfig{
Server: viper.GetString("watch.mastodon-server"),
ClientID: viper.GetString("watch.mastodon-client-id"),
ClientSecret: viper.GetString("watch.mastodon-client-secret"),
AccessToken: viper.GetString("watch.mastodon-access-token"),
}); err != nil {
return fmt.Errorf("mastodon announce failed: %v", err)
}
}
} else {
if post == "" {
Expand Down Expand Up @@ -252,19 +287,31 @@ var watchCmd = &cobra.Command{
if _, ok := cache.Get(string(commit.OID)); !ok {
cache.Add(string(commit.OID), commit)

if annouce && !viper.IsSet("watch.command") {
iconURL := viper.GetString("watch.discord-icon")
if iconURL == "" {
iconURL = "https://github.githubassets.com/assets/GitHub-Mark-ea2971cee799.png"
if discord || mastodon {
if discord && !viper.IsSet("watch.command") {
iconURL := viper.GetString("watch.discord-icon")
if iconURL == "" {
iconURL = "https://github.githubassets.com/assets/GitHub-Mark-ea2971cee799.png"
}
if err := announce.Discord(string(commit.Message), &announce.DiscordConfig{
DiscordWebhookID: viper.GetString("watch.discord-id"),
DiscordWebhookToken: viper.GetString("watch.discord-token"),
DiscordColor: "4535172",
DiscordAuthor: string(commit.Author.Name),
DiscordIconURL: iconURL,
}); err != nil {
return fmt.Errorf("discord announce failed: %v", err)
}
}
if err := watch.DiscordAnnounce(string(commit.Message), &watch.Config{
DiscordWebhookID: viper.GetString("watch.discord-id"),
DiscordWebhookToken: viper.GetString("watch.discord-token"),
DiscordColor: "4535172",
DiscordAuthor: string(commit.Author.Name),
DiscordIconURL: iconURL,
}); err != nil {
return fmt.Errorf("discord announce failed: %v", err)
if mastodon && !viper.IsSet("watch.command") {
if err := announce.Mastodon(string(commit.Message), &announce.MastodonConfig{
Server: viper.GetString("watch.mastodon-server"),
ClientID: viper.GetString("watch.mastodon-client-id"),
ClientSecret: viper.GetString("watch.mastodon-client-secret"),
AccessToken: viper.GetString("watch.mastodon-access-token"),
}); err != nil {
return fmt.Errorf("mastodon announce failed: %v", err)
}
}
} else if asJSON {
json.NewEncoder(os.Stdout).Encode(commit)
Expand Down
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ require (
github.com/hashicorp/go-version v1.7.0
github.com/hashicorp/golang-lru/v2 v2.0.7
github.com/invopop/jsonschema v0.13.0
github.com/mattn/go-mastodon v0.0.9
github.com/mitchellh/mapstructure v1.5.0
github.com/olekukonko/tablewriter v0.0.5
github.com/opencontainers/image-spec v1.1.0
Expand Down Expand Up @@ -122,6 +123,7 @@ require (
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/gorilla/websocket v1.5.1 // indirect
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
Expand Down Expand Up @@ -169,6 +171,7 @@ require (
github.com/subosito/gotenv v1.6.0 // indirect
github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af // indirect
github.com/temoto/robotstxt v1.1.2 // indirect
github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.12 // indirect
github.com/ulikunitz/lz v0.4.0 // indirect
Expand Down
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,8 @@ github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd/go.mod h1:kf6iHlnVGwg
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
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/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 h1:TmHmbvxPmaegwhDubVz0lICL0J5Ka2vwTzhoePEXsGE=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0/go.mod h1:qztMSjm835F2bXf+5HKAPIS5qsmQDqZna/PgVt4rWtI=
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU=
Expand Down Expand Up @@ -314,6 +316,8 @@ github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-mastodon v0.0.9 h1:zAlQF0LMumKPQLNR7dZL/YVCrvr4iP6ayyzxTR3vsSw=
github.com/mattn/go-mastodon v0.0.9/go.mod h1:8YkqetHoAVEktRkK15qeiv/aaIMfJ/Gc89etisPZtHU=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
Expand Down Expand Up @@ -436,6 +440,8 @@ github.com/tj/go-buffer v1.1.0/go.mod h1:iyiJpfFcR2B9sXu7KvjbT9fpM4mOelRSDTbntVj
github.com/tj/go-elastic v0.0.0-20171221160941-36157cbbebc2/go.mod h1:WjeM0Oo1eNAjXGDx2yma7uG2XoyRZTq1uv3M/o7imD0=
github.com/tj/go-kinesis v0.0.0-20171128231115-08b17f58cb1b/go.mod h1:/yhzCV0xPfx6jb1bBgRFjl5lytqVqZXEaeqWP8lTEao=
github.com/tj/go-spin v1.1.0/go.mod h1:Mg1mzmePZm4dva8Qz60H2lHwmJ2loum4VIrLgVnKwh4=
github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 h1:nrZ3ySNYwJbSpD6ce9duiP+QkD3JuLCcWkdaehUS/3Y=
github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80/go.mod h1:iFyPdL66DjUD96XmzVL3ZntbzcflLnznH0fr99w5VqE=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/twmb/murmur3 v1.1.8 h1:8Yt9taO/WN3l08xErzjeschgZU2QSrwm1kclYq+0aRg=
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package watch
package announce

import (
"bytes"
Expand All @@ -13,8 +13,8 @@ import (

const discordURL = "https://discord.com/api"

// Config for discord
type Config struct {
// DiscordConfig for discord
type DiscordConfig struct {
DiscordWebhookID string `json:"discord_webhook_id"`
DiscordWebhookToken string `json:"discord_webhook_token"`
DiscordColor string `json:"discord_color"`
Expand All @@ -37,8 +37,8 @@ type embedAuthor struct {
IconURL string `json:"icon_url,omitempty"`
}

// DiscordAnnounce posts a message to a discord webhook
func DiscordAnnounce(msg string, cfg *Config) error {
// Discord posts a message to a discord webhook
func Discord(msg string, cfg *DiscordConfig) error {
log.Infof("posting to discord:\n%s", msg)

color, err := strconv.Atoi(cfg.DiscordColor)
Expand Down
34 changes: 34 additions & 0 deletions internal/commands/watch/announce/mastodon.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package announce

import (
"context"
"fmt"

"github.com/apex/log"
"github.com/mattn/go-mastodon"
)

type MastodonConfig struct {
Server string `json:"server,omitempty"`
ClientID string `json:"client_id,omitempty"`
ClientSecret string `json:"client_secret,omitempty"`
AccessToken string `json:"access_token,omitempty"`
}

func Mastodon(msg string, cfg *MastodonConfig) error {
log.Infof("posting: '%s'", msg)

client := mastodon.NewClient(&mastodon.Config{
Server: cfg.Server,
ClientID: cfg.ClientID,
ClientSecret: cfg.ClientSecret,
AccessToken: cfg.AccessToken,
})

if _, err := client.PostStatus(context.Background(), &mastodon.Toot{
Status: msg,
}); err != nil {
return fmt.Errorf("failed to post to mastodon: %w", err)
}
return nil
}

0 comments on commit 78b9cac

Please sign in to comment.