diff --git a/src/spow-whatsapp-bridge/.gitignore b/src/spow-whatsapp-bridge/.gitignore index b62e1bb..29ed4b4 100644 --- a/src/spow-whatsapp-bridge/.gitignore +++ b/src/spow-whatsapp-bridge/.gitignore @@ -1,6 +1,7 @@ spow-whatsapp-bridge mdtest.db -dist +dist/ +test/ # nix .devbox diff --git a/src/spow-whatsapp-bridge/README.md b/src/spow-whatsapp-bridge/README.md new file mode 100644 index 0000000..b63c178 --- /dev/null +++ b/src/spow-whatsapp-bridge/README.md @@ -0,0 +1,5 @@ +# surplus on wheels: WhatsApp Bridge + +see +or [/docs/onwheels/whatsapp-bridge.md](../../docs/onwheels/whatsapp-bridge.md) +for more information and documentation diff --git a/src/spow-whatsapp-bridge/main.go b/src/spow-whatsapp-bridge/bridge.go similarity index 75% rename from src/spow-whatsapp-bridge/main.go rename to src/spow-whatsapp-bridge/bridge.go index 88df671..5272b32 100644 --- a/src/spow-whatsapp-bridge/main.go +++ b/src/spow-whatsapp-bridge/bridge.go @@ -1,10 +1,12 @@ // Copyright (c) 2021 Tulir Asokan -// Copyright (c) 2023 Mark Joshwel +// Copyright (c) 2024 Mark Joshwel // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. +// from https://github.com/tulir/whatsmeow/commit/792d96fbe610bfbf1039ec3b8d3f37f630025aea + package main import ( @@ -17,7 +19,6 @@ import ( "mime" "os" "os/signal" - "path" "strings" "sync/atomic" @@ -28,8 +29,6 @@ import ( "github.com/mdp/qrterminal/v3" "google.golang.org/protobuf/proto" - // "go.mau.fi/libsignal/groups" - // "go.mau.fi/libsignal/keys/message" "go.mau.fi/whatsmeow" "go.mau.fi/whatsmeow/appstate" waBinary "go.mau.fi/whatsmeow/binary" @@ -51,33 +50,37 @@ var dbAddress = flag.String("db-address", "file:mdtest.db?_foreign_keys=on", "Da var requestFullSync = flag.Bool("request-full-sync", false, "Request full (1 year) history sync when logging in?") var pairRejectChan = make(chan bool, 1) -var data_dir = path.Join(os.Getenv("HOME"), ".local", "share", "s+ow-whatsapp-bridge") -var sharetext_path = path.Join(os.Getenv("HOME"), ".cache", "s+ow", "message") +// s+ow-whatsapp-bridge: define important paths +var dataDir = path.Join(os.Getenv("HOME"), ".local", "share", "s+ow-whatsapp-bridge") +var sharetextPath = path.Join(os.Getenv("HOME"), ".cache", "s+ow", "message") func main() { - if *debugLogs { - logLevel = "DEBUG" - } - log = waLog.Stdout("Main", logLevel, true) - - // make and change dir - err := os.MkdirAll(data_dir, os.ModePerm) - if err != nil { - log.Errorf("s+ow-whatsapp-bridge: Failed to create directory: %v", err) - return - } - err = os.Chdir(data_dir) - if err != nil { - log.Errorf("s+ow-whatsapp-bridge: Failed to change directory: %v", err) - return - } - - // mdtest code waBinary.IndentXML = true flag.Parse() + if *debugLogs { + logLevel = "DEBUG" + } if *requestFullSync { store.DeviceProps.RequireFullSync = proto.Bool(true) + store.DeviceProps.HistorySyncConfig = &waProto.DeviceProps_HistorySyncConfig{ + FullSyncDaysLimit: proto.Uint32(3650), + FullSyncSizeMbLimit: proto.Uint32(102400), + StorageQuotaMb: proto.Uint32(102400), + } + } + log = waLog.Stdout("Main", logLevel, true) + + // s+ow-whatsapp-bridge: make and change dir + err := os.MkdirAll(dataDir, os.ModePerm) + if err != nil { + log.Errorf("s+ow-whatsapp-bridge: s+ow-whatsapp-bridge: Failed to create directory: %v", err) + return + } + err = os.Chdir(dataDir) + if err != nil { + log.Errorf("s+ow-whatsapp-bridge: s+ow-whatsapp-bridge: Failed to change directory: %v", err) + return } dbLog := waLog.Stdout("Database", logLevel, true) @@ -135,10 +138,9 @@ func main() { return } - c := make(chan os.Signal) + c := make(chan os.Signal, 1) input := make(chan string) - signalChan := make(chan os.Signal, 1) - signal.Notify(signalChan, os.Interrupt, syscall.SIGTERM) + signal.Notify(c, os.Interrupt, syscall.SIGTERM) go func() { defer close(input) scan := bufio.NewScanner(os.Stdin) @@ -150,7 +152,8 @@ func main() { } }() - // if 'login' in os.Args, we exit here + // s+ow-whatsapp-bridge + // - if 'login' in os.Args, we exit here for _, arg := range os.Args { if arg == "login" { for { @@ -170,21 +173,23 @@ func main() { } } - // if using as cli + // - if using as cli args := os.Args[1:] if len(args) > 0 { handleCmd(strings.ToLower(args[0]), args[1:]) return } - // read file ~/.cache/s+ow/message - sharetext, err := os.ReadFile(sharetext_path) + // - else, "normal" operation: + + // - - read file ~/.cache/s+ow/message + sharetext, err := os.ReadFile(sharetextPath) if err != nil { log.Errorf("s+ow-whatsapp-bridge: Failed to open file: %v", err) return } - // "normal" operation; read JID targets from stdin + // - - read JID targets from stdin targets := <-input split := strings.Split(targets, ",") for _, target := range split { @@ -198,6 +203,8 @@ func main() { if !ok { return } + + // reference the "send" case in handleCmd as a single source of truth msg := &waProto.Message{Conversation: proto.String(strings.TrimSpace(string(sharetext)))} resp, err := cli.SendMessage(context.Background(), recipient, msg) if err != nil { @@ -233,7 +240,26 @@ func parseJID(arg string) (types.JID, bool) { } func handleCmd(cmd string, args []string) { + // s+ow-whatsapp-bridge: we only need the bare minimum: + // - account-related: pair-phone, logout, reconnect + // - chat-related: list, send switch cmd { + case "pair-phone": + if len(args) < 1 { + log.Errorf("s+ow-whatsapp-bridge: Usage: pair-phone ") + return + } + linkingCode, err := cli.PairPhone(args[0], true, whatsmeow.PairClientChrome, "Chrome (Linux)") + if err != nil { + panic(err) + } + fmt.Println("Linking code:", linkingCode) + case "reconnect": + cli.Disconnect() + err := cli.Connect() + if err != nil { + log.Errorf("s+ow-whatsapp-bridge: Failed to connect: %v", err) + } case "logout": err := cli.Logout() if err != nil { @@ -245,10 +271,10 @@ func handleCmd(cmd string, args []string) { groups, err := cli.GetJoinedGroups() if err != nil { log.Errorf("s+ow-whatsapp-bridge: Failed to get group list: %v", err) - return - } - for _, group := range groups { - fmt.Printf("%s\t\t%s\n", group.JID, group.Name) + } else { + for _, group := range groups { + fmt.Printf("%s\t\t%s\n", group.JID, group.Name) + } } case "send": if len(args) < 2 { @@ -278,7 +304,7 @@ func handler(rawEvt interface{}) { if len(cli.Store.PushName) > 0 && evt.Name == appstate.WAPatchCriticalBlock { err := cli.SendPresence(types.PresenceAvailable) if err != nil { - log.Warnf("s+ow-whatsapp-bridge: Failed to send available presence: %v", err) + log.Warnf("Failed to send available presence: %v", err) } else { log.Infof("s+ow-whatsapp-bridge: Marked self as available") } @@ -291,7 +317,7 @@ func handler(rawEvt interface{}) { // This makes sure that outgoing messages always have the right pushname. err := cli.SendPresence(types.PresenceAvailable) if err != nil { - log.Warnf("s+ow-whatsapp-bridge: Failed to send available presence: %v", err) + log.Warnf("Failed to send available presence: %v", err) } else { log.Infof("s+ow-whatsapp-bridge: Marked self as available") } @@ -350,13 +376,29 @@ func handler(rawEvt interface{}) { return } exts, _ := mime.ExtensionsByType(img.GetMimetype()) - path := fmt.Sprintf("%s%s", evt.Info.ID, exts[0]) - err = os.WriteFile(path, data, 0600) + savePath := fmt.Sprintf("%s%s", evt.Info.ID, exts[0]) + err = os.WriteFile(savePath, data, 0600) if err != nil { log.Errorf("s+ow-whatsapp-bridge: Failed to save image: %v", err) return } - log.Infof("s+ow-whatsapp-bridge: Saved image in message to %s", path) + log.Infof("s+ow-whatsapp-bridge: Saved image in message to %s", savePath) + } + case *events.Receipt: + if evt.Type == types.ReceiptTypeRead || evt.Type == types.ReceiptTypeReadSelf { + log.Infof("s+ow-whatsapp-bridge: %v was read by %s at %s", evt.MessageIDs, evt.SourceString(), evt.Timestamp) + } else if evt.Type == types.ReceiptTypeDelivered { + log.Infof("s+ow-whatsapp-bridge: %s was delivered to %s at %s", evt.MessageIDs[0], evt.SourceString(), evt.Timestamp) + } + case *events.Presence: + if evt.Unavailable { + if evt.LastSeen.IsZero() { + log.Infof("s+ow-whatsapp-bridge: %s is now offline", evt.From) + } else { + log.Infof("s+ow-whatsapp-bridge: %s is now offline (last seen: %s)", evt.From, evt.LastSeen) + } + } else { + log.Infof("s+ow-whatsapp-bridge: %s is now online", evt.From) } case *events.HistorySync: id := atomic.AddInt32(&historySyncID, 1) @@ -376,10 +418,12 @@ func handler(rawEvt interface{}) { log.Infof("s+ow-whatsapp-bridge: Wrote history sync to %s", fileName) _ = file.Close() case *events.AppState: - log.Debugf("App state event: %+v / %+v", evt.Index, evt.SyncActionValue) + log.Debugf("s+ow-whatsapp-bridge: App state event: %+v / %+v", evt.Index, evt.SyncActionValue) case *events.KeepAliveTimeout: - log.Debugf("Keepalive timeout event: %+v", evt) + log.Debugf("s+ow-whatsapp-bridge: Keepalive timeout event: %+v", evt) case *events.KeepAliveRestored: - log.Debugf("Keepalive restored") + log.Debugf("s+ow-whatsapp-bridge: Keepalive restored") + case *events.Blocklist: + log.Infof("s+ow-whatsapp-bridge: Blocklist event: %+v", evt) } } diff --git a/src/spow-whatsapp-bridge/build-termux.sh b/src/spow-whatsapp-bridge/build-termux.sh index 51d1d09..b4459e5 100644 --- a/src/spow-whatsapp-bridge/build-termux.sh +++ b/src/spow-whatsapp-bridge/build-termux.sh @@ -1,4 +1,4 @@ +mkdir -p "$HOME/.local/bin" pkg install golang go build -mkdir -p $HOME/.local/bin -mv spow-whatsapp-bridge $HOME/.local/bin/s+ow-whatsapp-bridge +mv spow_whatsapp_bridge "$HOME/.local/bin/s+ow-whatsapp-bridge" diff --git a/src/spow-whatsapp-bridge/go.mod b/src/spow-whatsapp-bridge/go.mod index fd891ef..58b5ad1 100644 --- a/src/spow-whatsapp-bridge/go.mod +++ b/src/spow-whatsapp-bridge/go.mod @@ -1,22 +1,26 @@ -module spow-whatsapp-bridge +module forge.joshwel.co/mark/surplus/src/spow-whatsapp-bridge -go 1.21.3 +go 1.22.3 require ( - github.com/mattn/go-sqlite3 v1.14.18 + github.com/mattn/go-sqlite3 v1.14.22 github.com/mdp/qrterminal/v3 v3.2.0 - go.mau.fi/whatsmeow v0.0.0-20231104103606-23bd57d939ca - google.golang.org/protobuf v1.31.0 + go.mau.fi/whatsmeow v0.0.0-20240603101645-64bc969fbe78 + google.golang.org/protobuf v1.34.2 ) require ( - filippo.io/edwards25519 v1.0.0 // indirect - github.com/gorilla/websocket v1.5.1 // indirect + filippo.io/edwards25519 v1.1.0 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/gorilla/websocket v1.5.3 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/rs/zerolog v1.33.0 // indirect go.mau.fi/libsignal v0.1.0 // indirect - go.mau.fi/util v0.2.0 // indirect - golang.org/x/crypto v0.14.0 // indirect - golang.org/x/net v0.17.0 // indirect - golang.org/x/sys v0.14.0 // indirect - golang.org/x/term v0.13.0 // indirect + go.mau.fi/util v0.4.2 // indirect + golang.org/x/crypto v0.24.0 // indirect + golang.org/x/net v0.26.0 // indirect + golang.org/x/sys v0.21.0 // indirect + golang.org/x/term v0.21.0 // indirect rsc.io/qr v0.2.0 // indirect ) diff --git a/src/spow-whatsapp-bridge/go.sum b/src/spow-whatsapp-bridge/go.sum index 40a9ab8..cd755e6 100644 --- a/src/spow-whatsapp-bridge/go.sum +++ b/src/spow-whatsapp-bridge/go.sum @@ -1,42 +1,55 @@ -filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek= -filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= -github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM= -github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= -github.com/mattn/go-sqlite3 v1.14.18 h1:JL0eqdCOq6DJVNPSvArO/bIV9/P7fbGrV00LZHc+5aI= -github.com/mattn/go-sqlite3 v1.14.18/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= -github.com/mdp/qrterminal v1.0.1/go.mod h1:Z33WhxQe9B6CdW37HaVqcRKzP+kByF3q/qLxOGe12xQ= -github.com/mdp/qrterminal/v3 v3.0.0 h1:ywQqLRBXWTktytQNDKFjhAvoGkLVN3J2tAFZ0kMd9xQ= -github.com/mdp/qrterminal/v3 v3.0.0/go.mod h1:NJpfAs7OAm77Dy8EkWrtE4aq+cE6McoLXlBqXQEwvE0= +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.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +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-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= +github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/mdp/qrterminal/v3 v3.2.0 h1:qteQMXO3oyTK4IHwj2mWsKYYRBOp1Pj2WRYFYYNTCdk= github.com/mdp/qrterminal/v3 v3.2.0/go.mod h1:XGGuua4Lefrl7TLEsSONiD+UEjQXJZ4mPzF+gWYIJkk= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= +github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= go.mau.fi/libsignal v0.1.0 h1:vAKI/nJ5tMhdzke4cTK1fb0idJzz1JuEIpmjprueC+c= go.mau.fi/libsignal v0.1.0/go.mod h1:R8ovrTezxtUNzCQE5PH30StOQWWeBskBsWE55vMfY9I= -go.mau.fi/util v0.2.0 h1:AMGBEdg9Ya/smb/09dljo9wBwKr432EpfjDWF7aFQg0= -go.mau.fi/util v0.2.0/go.mod h1:AxuJUMCxpzgJ5eV9JbPWKRH8aAJJidxetNdUj7qcb84= -go.mau.fi/whatsmeow v0.0.0-20230805111647-405414b9b5c0 h1:6kAOyrp8E9p99X1I3uj7BtEFspdcVjnYzUZpqcHo/mE= -go.mau.fi/whatsmeow v0.0.0-20230805111647-405414b9b5c0/go.mod h1:+ObGpFE6cbbY4hKc1FmQH9MVfqaemmlXGXSnwDvCOyE= -go.mau.fi/whatsmeow v0.0.0-20231104103606-23bd57d939ca h1:r1/XGlSlYUFR4WTDKURPf8bTuPncrADZfOGPNrfr1oI= -go.mau.fi/whatsmeow v0.0.0-20231104103606-23bd57d939ca/go.mod h1:u557d2vph8xcLrk3CKTBknUHoB6icUpqazA4w+binRU= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= -golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +go.mau.fi/util v0.4.2 h1:RR3TOcRHmCF9Bx/3YG4S65MYfa+nV6/rn8qBWW4Mi30= +go.mau.fi/util v0.4.2/go.mod h1:PlAVfUUcPyHPrwnvjkJM9UFcPE7qGPDJqk+Oufa1Gtw= +go.mau.fi/whatsmeow v0.0.0-20240603101645-64bc969fbe78 h1:zST/E2cOjQEjXuis0miwSd20Uf+ffdJna6QefQyxEcc= +go.mau.fi/whatsmeow v0.0.0-20240603101645-64bc969fbe78/go.mod h1:0+65CYaE6r4dWzr0dN8i+UZKy0gIfJ79VuSqIl0nKRM= +golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= +golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= rsc.io/qr v0.2.0 h1:6vBLea5/NRMVTz8V66gipeLycZMl/+UlFmk8DvqQ6WY= rsc.io/qr v0.2.0/go.mod h1:IF+uZjkb9fqyeF/4tlBoynqmQxUoPfWEKh921coOuXs= diff --git a/src/spow-whatsapp-bridge/install.sh b/src/spow-whatsapp-bridge/install.sh new file mode 100644 index 0000000..bbd0507 --- /dev/null +++ b/src/spow-whatsapp-bridge/install.sh @@ -0,0 +1,5 @@ +#!/bin/sh +# surplus on wheels: WhatsApp Bridge: installation and updater script +set -e + +echo TODO