diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 64c7942..163aacb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,7 +3,7 @@ name: Release Prebuilt Binaries on: push: paths: - - state/state.go + - state/version.txt branches: - main workflow_dispatch: @@ -34,7 +34,7 @@ jobs: - name: Get Project Version id: get_version run: | - echo "version=$(grep -oP 'WATGBRIDGE_VERSION = \"\K[0-9]+\.[0-9]+\.[0-9]+' state/state.go)" >> $GITHUB_OUTPUT + echo "version=$(cat state/version.txt | tr -d '\n')" >> $GITHUB_OUTPUT - name: Create Release for amd64 if: always() @@ -70,7 +70,7 @@ jobs: - name: Get Project Version id: get_version run: | - echo "version=$(grep -oP 'WATGBRIDGE_VERSION = \"\K[0-9]+\.[0-9]+\.[0-9]+' state/state.go)" >> $GITHUB_OUTPUT + echo "version=$(cat state/version.txt | tr -d '\n')" >> $GITHUB_OUTPUT - name: Create Release for arm64 if: always() diff --git a/.github/workflows/cache_nix.yml b/.github/workflows/cache_nix.yml index ab68a77..6507358 100644 --- a/.github/workflows/cache_nix.yml +++ b/.github/workflows/cache_nix.yml @@ -4,6 +4,14 @@ on: push: branches: - main + paths: + - '**.go' + - state/version.txt + - go.mod + - go.sum + - gomod2nix.toml + - flake.nix + - nix/packages/*.nix workflow_dispatch: jobs: diff --git a/.gitignore b/.gitignore index 9c6653d..8f484c9 100644 --- a/.gitignore +++ b/.gitignore @@ -17,7 +17,7 @@ *.yaml !sample_config.yaml -watgbridge +/watgbridge *.db *.db-journal watgbridge-build/ diff --git a/README.md b/README.md index d7ed061..2de3703 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ This project is in no way affiliated with WhatsApp or Telegram. Using this can a ## Bugs and TODO -- Document naming is messed up and not consistent on Telegram, have to find a way to always send sane names +- Document naming is messed up and not consistent on Telegram, have to find a way to always send same names PRs are welcome :) diff --git a/flake.lock b/flake.lock index 75324e8..845e7ad 100644 --- a/flake.lock +++ b/flake.lock @@ -5,11 +5,11 @@ "systems": "systems" }, "locked": { - "lastModified": 1710146030, - "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", "owner": "numtide", "repo": "flake-utils", - "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", "type": "github" }, "original": { @@ -44,11 +44,11 @@ ] }, "locked": { - "lastModified": 1717050755, - "narHash": "sha256-C9IEHABulv2zEDFA+Bf0E1nmfN4y6MIUe5eM2RCrDC0=", + "lastModified": 1732540042, + "narHash": "sha256-i3FpT1w4x1hNZSKj20Rt2qHQvp1xp3Dz9rCPeSIQp0s=", "owner": "nix-community", "repo": "gomod2nix", - "rev": "31b6d2e40b36456e792cd6cf50d5a8ddd2fa59a1", + "rev": "f11423d1a082d83710275913f05b2a0b606f5aed", "type": "github" }, "original": { @@ -59,11 +59,11 @@ }, "nix-filter": { "locked": { - "lastModified": 1710156097, - "narHash": "sha256-1Wvk8UP7PXdf8bCCaEoMnOT1qe5/Duqgj+rL8sRQsSM=", + "lastModified": 1731533336, + "narHash": "sha256-oRam5PS1vcrr5UPgALW0eo1m/5/pls27Z/pabHNy2Ms=", "owner": "numtide", "repo": "nix-filter", - "rev": "3342559a24e85fc164b295c3444e8a139924675b", + "rev": "f7653272fd234696ae94229839a99b73c9ab7de0", "type": "github" }, "original": { @@ -74,11 +74,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1718530797, - "narHash": "sha256-pup6cYwtgvzDpvpSCFh1TEUjw2zkNpk8iolbKnyFmmU=", + "lastModified": 1733392399, + "narHash": "sha256-kEsTJTUQfQFIJOcLYFt/RvNxIK653ZkTBIs4DG+cBns=", "owner": "nixos", "repo": "nixpkgs", - "rev": "b60ebf54c15553b393d144357375ea956f89e9a9", + "rev": "d0797a04b81caeae77bcff10a9dde78bc17f5661", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index f866d97..03a0003 100644 --- a/flake.nix +++ b/flake.nix @@ -6,29 +6,46 @@ flake-utils.url = "github:numtide/flake-utils"; nix-filter.url = "github:numtide/nix-filter"; gomod2nix = { - url = "github:nix-community/gomod2nix"; - inputs.nixpkgs.follows = "nixpkgs"; + url = "github:nix-community/gomod2nix"; + inputs.nixpkgs.follows = "nixpkgs"; }; }; - outputs = { self, nixpkgs, flake-utils, gomod2nix, nix-filter }: - flake-utils.lib.eachDefaultSystem (system: + outputs = + { + self, + nixpkgs, + flake-utils, + gomod2nix, + nix-filter, + }: + flake-utils.lib.eachDefaultSystem ( + system: let pkgs = import nixpkgs { - inherit system; - overlays = [ gomod2nix.overlays.default ]; + inherit system; + overlays = [ gomod2nix.overlays.default ]; }; in - with pkgs; { + with pkgs; + rec { devShells.default = mkShell { name = "watgbridge-dev"; nativeBuildInputs = [ go gopls + delve libwebp gomod2nix.packages."${system}".default + sqlite ]; + hardeningDisable = [ "fortify" ]; + }; + + apps.default = { + type = "app"; + program = "${packages.default}/bin/watgbridge"; }; packages = rec { @@ -36,11 +53,17 @@ default = watgbridge; }; + overlay = final: prev: { + watgbridge = (pkgs.callPackage ./nix/pkgs/watgbridge-dev.nix { inherit nix-filter; }); + }; + } ); nixConfig = { extra-substituters = [ "https://watgbridge.cachix.org" ]; - extra-trusted-public-keys = [ "watgbridge.cachix.org-1:KSfgmbSBvXQTpUnoCj21vST7zgwpy3SbNfk0/nesR1Y=" ]; + extra-trusted-public-keys = [ + "watgbridge.cachix.org-1:KSfgmbSBvXQTpUnoCj21vST7zgwpy3SbNfk0/nesR1Y=" + ]; }; } diff --git a/go.mod b/go.mod index 9c59da4..40cca2f 100644 --- a/go.mod +++ b/go.mod @@ -3,25 +3,26 @@ module watgbridge go 1.22.3 require ( - github.com/PaulSonOfLars/gotgbot/v2 v2.0.0-rc.28 - github.com/emersion/go-vcard v0.0.0-20230815062825-8fda7d206ec9 + github.com/PaulSonOfLars/gotgbot/v2 v2.0.0-rc.30 + github.com/emersion/go-vcard v0.0.0-20241024213814-c9703dde27ff github.com/forPelevin/gomoji v1.2.0 github.com/go-co-op/gocron v1.37.0 - github.com/jackc/pgx/v5 v5.6.0 + github.com/jackc/pgx/v5 v5.7.2 github.com/lithammer/fuzzysearch v1.1.8 - github.com/mattn/go-sqlite3 v1.14.22 + github.com/mattn/go-sqlite3 v1.14.24 github.com/mdp/qrterminal/v3 v3.2.0 + github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e github.com/watgbridge/tgsconverter v0.0.0-20240710075117-d1c05581b842 github.com/watgbridge/webp v0.0.0-20240709143015-99fb5316f772 - go.mau.fi/whatsmeow v0.0.0-20240710112833-d732338c041f + go.mau.fi/whatsmeow v0.0.0-20250104105216-918c879fcd19 go.uber.org/zap v1.27.0 - golang.org/x/exp v0.0.0-20240707233637-46b078467d37 - google.golang.org/protobuf v1.34.2 + golang.org/x/exp v0.0.0-20250103183323-7d7fa50e5329 + google.golang.org/protobuf v1.36.1 gopkg.in/yaml.v3 v3.0.1 gorm.io/driver/mysql v1.5.7 - gorm.io/driver/postgres v1.5.9 - gorm.io/driver/sqlite v1.5.6 - gorm.io/gorm v1.25.11 + gorm.io/driver/postgres v1.5.11 + gorm.io/driver/sqlite v1.5.7 + gorm.io/gorm v1.25.12 ) require ( @@ -33,7 +34,7 @@ require ( github.com/gorilla/websocket v1.5.3 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect - github.com/jackc/puddle/v2 v2.2.1 // indirect + github.com/jackc/puddle/v2 v2.2.2 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect github.com/kettek/apng v0.0.0-20220823221153-ff692776a607 // indirect @@ -42,15 +43,15 @@ require ( github.com/rivo/uniseg v0.4.7 // indirect github.com/robfig/cron/v3 v3.0.1 // indirect github.com/rs/zerolog v1.33.0 // indirect - go.mau.fi/libsignal v0.1.1-0.20240705162345-47e713a595ab // indirect - go.mau.fi/util v0.5.0 // indirect + go.mau.fi/libsignal v0.1.1 // indirect + go.mau.fi/util v0.8.3 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.25.0 // indirect - golang.org/x/net v0.27.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/term v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/crypto v0.31.0 // indirect + golang.org/x/net v0.33.0 // indirect + golang.org/x/sync v0.10.0 // indirect + golang.org/x/sys v0.29.0 // indirect + golang.org/x/term v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect rsc.io/qr v0.2.0 // indirect ) diff --git a/go.sum b/go.sum index 3aa743a..6c02aba 100644 --- a/go.sum +++ b/go.sum @@ -2,10 +2,10 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/Benau/go_rlottie v0.0.0-20210807002906-98c1b2421989 h1:+wrfJITuBoQOE6ST4k3c4EortNVQXVhfAbwt0M/j0+Y= github.com/Benau/go_rlottie v0.0.0-20210807002906-98c1b2421989/go.mod h1:aDWSWjsayFyGTvHZH3v4ijGXEBe51xcEkAK+NUWeOeo= -github.com/PaulSonOfLars/gotgbot/v2 v2.0.0-rc.27 h1:rOlGzmYC3jPVPLVLWKMiiYuePQ6MV8Cyw5qJYBoMnkY= -github.com/PaulSonOfLars/gotgbot/v2 v2.0.0-rc.27/go.mod h1:kL1v4iIjlalwm3gCYGvF4NLa3hs+aKEfRkNJvj4aoDU= -github.com/PaulSonOfLars/gotgbot/v2 v2.0.0-rc.28 h1:3EidAXUUuDBwaRX5881fmpGGv2WPnW9oHwRMlvdQiwU= -github.com/PaulSonOfLars/gotgbot/v2 v2.0.0-rc.28/go.mod h1:kL1v4iIjlalwm3gCYGvF4NLa3hs+aKEfRkNJvj4aoDU= +github.com/PaulSonOfLars/gotgbot/v2 v2.0.0-rc.29 h1:5/K8zgmoKnsegt6h9XvFIJAGxbHVWOEwSpjdjaySf6A= +github.com/PaulSonOfLars/gotgbot/v2 v2.0.0-rc.29/go.mod h1:kL1v4iIjlalwm3gCYGvF4NLa3hs+aKEfRkNJvj4aoDU= +github.com/PaulSonOfLars/gotgbot/v2 v2.0.0-rc.30 h1:kPFkEzqg3+5gu077Zrg+24d0rO0Iwdx/ZUUHFFprfsc= +github.com/PaulSonOfLars/gotgbot/v2 v2.0.0-rc.30/go.mod h1:kL1v4iIjlalwm3gCYGvF4NLa3hs+aKEfRkNJvj4aoDU= github.com/av-elier/go-decimal-to-rational v0.0.0-20191127152832-89e6aad02ecf h1:csfEAyvOG4/498Q4SyF48ysFqQC9ESj3o8ppRtg+Rog= github.com/av-elier/go-decimal-to-rational v0.0.0-20191127152832-89e6aad02ecf/go.mod h1:POPnOeaYF7U9o3PjLTb9icRfEOxjBNLRXh9BLximJGM= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= @@ -15,6 +15,8 @@ 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/emersion/go-vcard v0.0.0-20230815062825-8fda7d206ec9 h1:ATgqloALX6cHCranzkLb8/zjivwQ9DWWDCQRnxTPfaA= github.com/emersion/go-vcard v0.0.0-20230815062825-8fda7d206ec9/go.mod h1:HMJKR5wlh/ziNp+sHEDV2ltblO4JD2+IdDOWtGcQBTM= +github.com/emersion/go-vcard v0.0.0-20241024213814-c9703dde27ff h1:4N8wnS3f1hNHSmFD5zgFkWCyA4L1kCDkImPAtK7D6tg= +github.com/emersion/go-vcard v0.0.0-20241024213814-c9703dde27ff/go.mod h1:HMJKR5wlh/ziNp+sHEDV2ltblO4JD2+IdDOWtGcQBTM= github.com/forPelevin/gomoji v1.2.0 h1:9k4WVSSkE1ARO/BWywxgEUBvR/jMnao6EZzrql5nxJ8= github.com/forPelevin/gomoji v1.2.0/go.mod h1:8+Z3KNGkdslmeGZBC3tCrwMrcPy5GRzAD+gL9NAwMXg= github.com/go-co-op/gocron v1.37.0 h1:ZYDJGtQ4OMhTLKOKMIch+/CY70Brbb1dGdooLEhh7b0= @@ -28,22 +30,22 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/uuid v1.4.0/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/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= -github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 h1:L0QtFUgDarD7Fpv9jeVMgy/+Ec0mtnmYuImjTz6dtDA= -github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= -github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw= -github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A= github.com/jackc/pgx/v5 v5.6.0 h1:SWJzexBzPL5jb0GEsrPMLIsi/3jOo7RHlzTjcAeDrPY= github.com/jackc/pgx/v5 v5.6.0/go.mod h1:DNZ/vlrUnhWCoFGxHAG8U2ljioxukquj7utPDgtQdTw= +github.com/jackc/pgx/v5 v5.7.1 h1:x7SYsPBYDkHDksogeSmZZ5xzThcTgRz++I5E+ePFUcs= +github.com/jackc/pgx/v5 v5.7.1/go.mod h1:e7O26IywZZ+naJtWWos6i6fvWK+29etgITqrqHLfoZA= +github.com/jackc/pgx/v5 v5.7.2 h1:mLoDLV6sonKlvjIEsV56SkWNCnuNv531l94GaIzO+XI= +github.com/jackc/pgx/v5 v5.7.2/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ= github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk= github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= +github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= +github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= @@ -68,6 +70,10 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE 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/mattn/go-sqlite3 v1.14.23 h1:gbShiuAP1W5j9UOksQ06aiiqPMxYecovVGwmTxWtuw0= +github.com/mattn/go-sqlite3 v1.14.23/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM= +github.com/mattn/go-sqlite3 v1.14.24/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/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= @@ -82,10 +88,10 @@ github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg= github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= -github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= 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/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0= +github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -96,27 +102,38 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= 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= -github.com/watgbridge/tgsconverter v0.0.0-20240630070853-83de423ff0ec h1:PQM9zile98WsYZRxjmob42zBdcURPlWq0y47+4urjdQ= -github.com/watgbridge/tgsconverter v0.0.0-20240630070853-83de423ff0ec/go.mod h1:TiKtQQnS7kqOXMl372GzDy+8ABveJy9w9JD88NQaR14= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/watgbridge/tgsconverter v0.0.0-20240710075117-d1c05581b842 h1:wnf7BjgRzAn1Nrt8s/JSAIBY4piCqjT2b68w2tKixrU= github.com/watgbridge/tgsconverter v0.0.0-20240710075117-d1c05581b842/go.mod h1:TiKtQQnS7kqOXMl372GzDy+8ABveJy9w9JD88NQaR14= -github.com/watgbridge/webp v0.0.0-20240630070243-84d3a70502bb h1:ScNT6ubA5fVjA4IKR9JhOrVjzUAb/3eHNqyFP55Nruk= -github.com/watgbridge/webp v0.0.0-20240630070243-84d3a70502bb/go.mod h1:TqnmhmYJVPcl/RYFCJ6xf6KJfJQTqVwXpGTvzPVhqF0= github.com/watgbridge/webp v0.0.0-20240709143015-99fb5316f772 h1:pXnh8U4/14QVM4LB/DJVOGHoWpkrBke+gE+qcOaLxMQ= github.com/watgbridge/webp v0.0.0-20240709143015-99fb5316f772/go.mod h1:TqnmhmYJVPcl/RYFCJ6xf6KJfJQTqVwXpGTvzPVhqF0= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -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/libsignal v0.1.1-0.20240705162345-47e713a595ab h1:/tnRxsaaG/xBGjXTb6tzTr+XY4T5fQlrGHE1p9ir/wM= -go.mau.fi/libsignal v0.1.1-0.20240705162345-47e713a595ab/go.mod h1:R8ovrTezxtUNzCQE5PH30StOQWWeBskBsWE55vMfY9I= -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/util v0.5.0 h1:8yELAl+1CDRrwGe9NUmREgVclSs26Z68pTWePHVxuDo= -go.mau.fi/util v0.5.0/go.mod h1:DsJzUrJAG53lCZnnYvq9/mOyLuPScWwYhvETiTrpdP4= -go.mau.fi/whatsmeow v0.0.0-20240520180327-81f8f07f1dfb h1:FW5W0ewNOmunylB3Pmru8PvxYkhI6ZphCJtimM2aB6o= -go.mau.fi/whatsmeow v0.0.0-20240520180327-81f8f07f1dfb/go.mod h1:0+65CYaE6r4dWzr0dN8i+UZKy0gIfJ79VuSqIl0nKRM= -go.mau.fi/whatsmeow v0.0.0-20240710112833-d732338c041f h1:ni8K5zVngwOWrrZ1HzwEmvAovj0+p0cq464l9g0/dt0= -go.mau.fi/whatsmeow v0.0.0-20240710112833-d732338c041f/go.mod h1:lMW+LxRTakgyNasZwYNB+2uqjKox75GcEfeUXSJhe8I= +go.mau.fi/libsignal v0.1.1 h1:m/0PGBh4QKP/I1MQ44ti4C0fMbLMuHb95cmDw01FIpI= +go.mau.fi/libsignal v0.1.1/go.mod h1:QLs89F/OA3ThdSL2Wz2p+o+fi8uuQUz0e1BRa6ExdBw= +go.mau.fi/util v0.7.0 h1:l31z+ivrSQw+cv/9eFebEqtQW2zhxivGypn+JT0h/ws= +go.mau.fi/util v0.7.0/go.mod h1:bWYreIoTULL/UiRbZdfddPh7uWDFW5yX4YCv5FB0eE0= +go.mau.fi/util v0.8.0 h1:MiSny8jgQq4XtCLAT64gDJhZVhqiDeMVIEBDFVw+M0g= +go.mau.fi/util v0.8.0/go.mod h1:1Ixb8HWoVbl3rT6nAX6nV4iMkzn7KU/KXwE0Rn5RmsQ= +go.mau.fi/util v0.8.1 h1:Ga43cz6esQBYqcjZ/onRoVnYWoUwjWbsxVeJg2jOTSo= +go.mau.fi/util v0.8.1/go.mod h1:T1u/rD2rzidVrBLyaUdPpZiJdP/rsyi+aTzn0D+Q6wc= +go.mau.fi/util v0.8.2 h1:zWbVHwdRKwI6U9AusmZ8bwgcLosikwbb4GGqLrNr1YE= +go.mau.fi/util v0.8.2/go.mod h1:BHHC9R2WLMJd1bwTZfTcFxUgRFmUgUmiWcT4RbzUgiA= +go.mau.fi/util v0.8.3 h1:sulhXtfquMrQjsOP67x9CzWVBYUwhYeoo8hNQIpCWZ4= +go.mau.fi/util v0.8.3/go.mod h1:c00Db8xog70JeIsEvhdHooylTkTkakgnAOsZ04hplQY= +go.mau.fi/whatsmeow v0.0.0-20240816195430-66c6524b93ad h1:SVmmN5/6fKQimC53m62nTX44mpod5MmA6mJ0omh7WgI= +go.mau.fi/whatsmeow v0.0.0-20240816195430-66c6524b93ad/go.mod h1:BhHKalSq0qNtSCuGIUIvoJyU5KbT4a7k8DQ5yw1Ssk4= +go.mau.fi/whatsmeow v0.0.0-20240917093958-061c065cc1ee h1:wP8wJwD9lRqEeWQsWg9z6dnW5FKMi6rU7hJO+BEfaa0= +go.mau.fi/whatsmeow v0.0.0-20240917093958-061c065cc1ee/go.mod h1:BhHKalSq0qNtSCuGIUIvoJyU5KbT4a7k8DQ5yw1Ssk4= +go.mau.fi/whatsmeow v0.0.0-20241009112614-70d73b690a8d h1:0OV2Ula2IGaoHVfvv7ns+Gn3xGT0SHn5yDecJBB8FQY= +go.mau.fi/whatsmeow v0.0.0-20241009112614-70d73b690a8d/go.mod h1:UvaXcdb8y5Mryj2LSXAMw7u4/exnWJIXn8Gvpmf6ndI= +go.mau.fi/whatsmeow v0.0.0-20241015144315-3fa42c3d6a28 h1:Kb0UAafF46p2gJfrxP27jxLUtn1oEWD41g+IddxjQ3U= +go.mau.fi/whatsmeow v0.0.0-20241015144315-3fa42c3d6a28/go.mod h1:UvaXcdb8y5Mryj2LSXAMw7u4/exnWJIXn8Gvpmf6ndI= +go.mau.fi/whatsmeow v0.0.0-20241030164414-f98aea1881f6 h1:ibChSQNQa6WTO+jUuJQz9x7qwCQoeIl/zlNCa/dAtvg= +go.mau.fi/whatsmeow v0.0.0-20241030164414-f98aea1881f6/go.mod h1:UvaXcdb8y5Mryj2LSXAMw7u4/exnWJIXn8Gvpmf6ndI= +go.mau.fi/whatsmeow v0.0.0-20241202173457-b2dd543e5721 h1:NveCzJ+3fTWBNnHg5+0iVqjdPdFmCTw9MDY1yELUDx4= +go.mau.fi/whatsmeow v0.0.0-20241202173457-b2dd543e5721/go.mod h1:iB+F/NVNOnyumU2p/TKTSSdBhH05GHFG36diYuFp9VQ= +go.mau.fi/whatsmeow v0.0.0-20250104105216-918c879fcd19 h1:uVS+Zct5fF8rSXV9lfs87zoXdge0JXTzVGNkjmZ61UU= +go.mau.fi/whatsmeow v0.0.0-20250104105216-918c879fcd19/go.mod h1:TLzm2XkwgufONEmiVAsFny+9uBqyEZnUoPrQAfMyuSU= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= @@ -128,29 +145,51 @@ go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= -golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= -golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= -golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= -golang.org/x/exp v0.0.0-20240707233637-46b078467d37 h1:uLDX+AfeFCct3a2C7uIWBKMJIR3CJMhcgfrUAqjRK6w= -golang.org/x/exp v0.0.0-20240707233637-46b078467d37/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= +golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= +golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= +golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= +golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= +golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= +golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= +golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= +golang.org/x/exp v0.0.0-20241004190924-225e2abe05e6 h1:1wqE9dj9NpSm04INVsJhhEUzhuDVjbcyKH91sVyPATw= +golang.org/x/exp v0.0.0-20241004190924-225e2abe05e6/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8= +golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY= +golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8= +golang.org/x/exp v0.0.0-20241204233417-43b7b7cde48d h1:0olWaB5pg3+oychR51GUVCEsGkeCU/2JxjBgIo4f3M0= +golang.org/x/exp v0.0.0-20241204233417-43b7b7cde48d/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c= +golang.org/x/exp v0.0.0-20250103183323-7d7fa50e5329 h1:9kj3STMvgqy3YA4VQXBrN7925ICMxD5wzMRcgA30588= +golang.org/x/exp v0.0.0-20250103183323-7d7fa50e5329/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= +golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= +golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= +golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= +golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -160,35 +199,55 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.5.0/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.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= -golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= +golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= +golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= +golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= +golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= +golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= +golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= -google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= +google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= +google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk= +google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= @@ -197,22 +256,20 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gorm.io/driver/mysql v1.5.6 h1:Ld4mkIickM+EliaQZQx3uOJDJHtrd70MxAUqWqlx3Y8= -gorm.io/driver/mysql v1.5.6/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM= gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo= gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM= -gorm.io/driver/postgres v1.5.7 h1:8ptbNJTDbEmhdr62uReG5BGkdQyeasu/FZHxI0IMGnM= -gorm.io/driver/postgres v1.5.7/go.mod h1:3e019WlBaYI5o5LIdNV+LyxCMNtLOQETBXL2h4chKpA= gorm.io/driver/postgres v1.5.9 h1:DkegyItji119OlcaLjqN11kHoUgZ/j13E0jkJZgD6A8= gorm.io/driver/postgres v1.5.9/go.mod h1:DX3GReXH+3FPWGrrgffdvCk3DQ1dwDPdmbenSkweRGI= -gorm.io/driver/sqlite v1.5.5 h1:7MDMtUZhV065SilG62E0MquljeArQZNfJnjd9i9gx3E= -gorm.io/driver/sqlite v1.5.5/go.mod h1:6NgQ7sQWAIFsPrJJl1lSNSu2TABh0ZZ/zm5fosATavE= +gorm.io/driver/postgres v1.5.11 h1:ubBVAfbKEUld/twyKZ0IYn9rSQh448EdelLYk9Mv314= +gorm.io/driver/postgres v1.5.11/go.mod h1:DX3GReXH+3FPWGrrgffdvCk3DQ1dwDPdmbenSkweRGI= gorm.io/driver/sqlite v1.5.6 h1:fO/X46qn5NUEEOZtnjJRWRzZMe8nqJiQ9E+0hi+hKQE= gorm.io/driver/sqlite v1.5.6/go.mod h1:U+J8craQU6Fzkcvu8oLeAQmi50TkwPEhHDEjQZXDah4= +gorm.io/driver/sqlite v1.5.7 h1:8NvsrhP0ifM7LX9G4zPB97NwovUakUxc+2V2uuf3Z1I= +gorm.io/driver/sqlite v1.5.7/go.mod h1:U+J8craQU6Fzkcvu8oLeAQmi50TkwPEhHDEjQZXDah4= gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= -gorm.io/gorm v1.25.10 h1:dQpO+33KalOA+aFYGlK+EfxcI5MbO7EP2yYygwh9h+s= -gorm.io/gorm v1.25.10/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= gorm.io/gorm v1.25.11 h1:/Wfyg1B/je1hnDx3sMkX+gAlxrlZpn6X0BXRlwXlvHg= gorm.io/gorm v1.25.11/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ= +gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8= +gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ= 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/gomod2nix.toml b/gomod2nix.toml index 3c06b63..c076c37 100644 --- a/gomod2nix.toml +++ b/gomod2nix.toml @@ -8,14 +8,14 @@ schema = 3 version = "v0.0.0-20210807002906-98c1b2421989" hash = "sha256-oIe5oARFioEFTv/tR8V0PJGvsW1qB0/ZFo7E/UPhJX4=" [mod."github.com/PaulSonOfLars/gotgbot/v2"] - version = "v2.0.0-rc.28" - hash = "sha256-hoa3YYckHcBAXs3VJUoSsjxF1mx3D2B6JybeB+gCZ7Q=" + version = "v2.0.0-rc.30" + hash = "sha256-FatUrphnwfhNzFtfRxayIp2yrOsIYQSYqX6qSsD72m8=" [mod."github.com/av-elier/go-decimal-to-rational"] version = "v0.0.0-20191127152832-89e6aad02ecf" hash = "sha256-134e6CsH7ukNl3ew3CW/8+DvBtsiaIXn5YlP1+fWUpQ=" [mod."github.com/emersion/go-vcard"] - version = "v0.0.0-20230815062825-8fda7d206ec9" - hash = "sha256-tMdvTJm3jC1zwYS3CsLgSwy5+19yYygTde33Im2UxYo=" + version = "v0.0.0-20241024213814-c9703dde27ff" + hash = "sha256-FY3jy4rGASVbssqoAsaV9XqUWBaWWKRwNEJVIkx120g=" [mod."github.com/forPelevin/gomoji"] version = "v1.2.0" hash = "sha256-OY45JcTHo1ekvmRrX5nhZ5F97/mLvD8QzvrmBfDdZCI=" @@ -38,11 +38,11 @@ schema = 3 version = "v0.0.0-20240606120523-5a60cdf6a761" hash = "sha256-ETpGsLAA2wcm5xJBayr/mZrCE1YsWbnkbSSX3ptrFn0=" [mod."github.com/jackc/pgx/v5"] - version = "v5.6.0" - hash = "sha256-6Tx7UF6gWc4e572x6wBDLghoe0Inhef0cH2Fq5I8fX4=" + version = "v5.7.2" + hash = "sha256-FEh0GwrkTlFPZiqT6m3jYg5OV62/LHs/otMQuJfcMNw=" [mod."github.com/jackc/puddle/v2"] - version = "v2.2.1" - hash = "sha256-Edf8SLT/8l+xfHm9IjUGxs1MHtic2VgRyfqb6OzGA9k=" + version = "v2.2.2" + hash = "sha256-IUxdu4JYfsCh/qlz2SiUWu7EVPHhyooiVA4oaS2Z6yk=" [mod."github.com/jinzhu/inflection"] version = "v1.0.0" hash = "sha256-3h3pHib5MaCXKyKLIMyQnSptDJ16kPjCOQPoEBoQsZg=" @@ -62,8 +62,8 @@ schema = 3 version = "v0.0.20" hash = "sha256-qhw9hWtU5wnyFyuMbKx+7RB8ckQaFQ8D+8GKPkN3HHQ=" [mod."github.com/mattn/go-sqlite3"] - version = "v1.14.22" - hash = "sha256-CWF2Hjg43658NhaePWbGzS19gHJXjuTroG5c0W3hgYQ=" + version = "v1.14.24" + hash = "sha256-taGKFZFQlR5++5b2oZ1dYS3RERKv6yh1gniNWhb4egg=" [mod."github.com/mdp/qrterminal/v3"] version = "v3.2.0" hash = "sha256-2ZcpLFu6P+a3qHH32uiFKUwzgza1NF0Bmayl41GQCEI=" @@ -76,6 +76,9 @@ schema = 3 [mod."github.com/rs/zerolog"] version = "v1.33.0" hash = "sha256-jT/Y/izhZiCdrDbC/ty83FGs8UQavTU+OW03O4vKFkY=" + [mod."github.com/skip2/go-qrcode"] + version = "v0.0.0-20200617195104-da1b6568686e" + hash = "sha256-ST9t4/b7WFXUb8wra4ZYVDNZJGrEykw8dkWhLrxp8F0=" [mod."github.com/watgbridge/tgsconverter"] version = "v0.0.0-20240710075117-d1c05581b842" hash = "sha256-0S477WzYnjZNofoxiuYMR0Wc/elXu74WDUi7N8QoK0Q=" @@ -83,14 +86,14 @@ schema = 3 version = "v0.0.0-20240709143015-99fb5316f772" hash = "sha256-CL7WYufOA7rxy8Tn/B8iVYa/Cf7JdIGEko2XGYoF2Fo=" [mod."go.mau.fi/libsignal"] - version = "v0.1.1-0.20240705162345-47e713a595ab" - hash = "sha256-Dv9uBYPpSMOPacao1VqJ1DFhpvsU+HDiIAKL0BY8BEc=" + version = "v0.1.1" + hash = "sha256-KegSskYAq2MFiOvB28WG0j0VPzfbXqivapLHwsIEYNc=" [mod."go.mau.fi/util"] - version = "v0.5.0" - hash = "sha256-Gpg/orzKd3emcQecqc++y3xDp43oC8owDljiiBNIxpQ=" + version = "v0.8.3" + hash = "sha256-RAvVZ5LqwpKfECdScp8jKnBCSMh0p3n2H4pAmJDKpxo=" [mod."go.mau.fi/whatsmeow"] - version = "v0.0.0-20240710112833-d732338c041f" - hash = "sha256-2+WrcaKNis4/Vi2vo6hxlJ7tO/02jXTbgjLKmw9ICiA=" + version = "v0.0.0-20250104105216-918c879fcd19" + hash = "sha256-X+w0jxBU0jTmk9wumkLo8XomZjRn3Sawfc8E8Nuqwx4=" [mod."go.uber.org/atomic"] version = "v1.11.0" hash = "sha256-TyYws/cSPVqYNffFX0gbDml1bD4bBGcysrUWU7mHPIY=" @@ -101,29 +104,29 @@ schema = 3 version = "v1.27.0" hash = "sha256-8655KDrulc4Das3VRduO9MjCn8ZYD5WkULjCvruaYsU=" [mod."golang.org/x/crypto"] - version = "v0.25.0" - hash = "sha256-traLAylqoBwGIh0Z1fuEhNjbGgQBItgVjtZYdYr0zzQ=" + version = "v0.31.0" + hash = "sha256-ZBjoG7ZOuTEmjaXPP9txAvjAjC46DeaLs0zrNzi8EQw=" [mod."golang.org/x/exp"] - version = "v0.0.0-20240707233637-46b078467d37" - hash = "sha256-jTwnJtpErpBIGT38VAJI8+UAnGfa8V3M1y1yN4dHTvE=" + version = "v0.0.0-20250103183323-7d7fa50e5329" + hash = "sha256-LY28ecvACsMYVHp+tfb+YQN+9rAUBfVbTbstgm9JArc=" [mod."golang.org/x/net"] - version = "v0.27.0" - hash = "sha256-GrlN5isYeEVrPZVAHK0MDQatttbnyfSPoWJHj0xqhjk=" + version = "v0.33.0" + hash = "sha256-9swkU9vp6IflUUqAzK+y8PytSmrKLuryidP3RmRfe0w=" [mod."golang.org/x/sync"] - version = "v0.7.0" - hash = "sha256-2ETllEu2GDWoOd/yMkOkLC2hWBpKzbVZ8LhjLu0d2A8=" + version = "v0.10.0" + hash = "sha256-HWruKClrdoBKVdxKCyoazxeQV4dIYLdkHekQvx275/o=" [mod."golang.org/x/sys"] - version = "v0.22.0" - hash = "sha256-RbG0XaXGGlErCsl2agvUxMnrkRwdbJLmriYT1H24FwA=" + version = "v0.29.0" + hash = "sha256-qfsodJQ1H1CBI8yQWOvsXJgY5qHmiuw566HrrIseYHI=" [mod."golang.org/x/term"] - version = "v0.22.0" - hash = "sha256-tRx/y4ZIZzGAlDJ/8JW3AycC9bRXlNuRqO4V48sAEEc=" + version = "v0.28.0" + hash = "sha256-1/iWqndBRFgDL+/tVokkaGHpO/jdyjZ0dN2YWuBdiXQ=" [mod."golang.org/x/text"] - version = "v0.16.0" - hash = "sha256-hMTO45upjEuA4sJzGplJT+La2n3oAfHccfYWZuHcH+8=" + version = "v0.21.0" + hash = "sha256-QaMwddBRnoS2mv9Y86eVC2x2wx/GZ7kr2zAJvwDeCPc=" [mod."google.golang.org/protobuf"] - version = "v1.34.2" - hash = "sha256-nMTlrDEE2dbpWz50eQMPBQXCyQh4IdjrTIccaU0F3m0=" + version = "v1.36.1" + hash = "sha256-qGWEeb6fd16uATHuJ5mDdZKUKnHwKOeneJ6mXEv3prQ=" [mod."gopkg.in/yaml.v3"] version = "v3.0.1" hash = "sha256-FqL9TKYJ0XkNwJFnq9j0VvJ5ZUU1RvH/52h/f5bkYAU=" @@ -131,14 +134,14 @@ schema = 3 version = "v1.5.7" hash = "sha256-r7Ov6434mt+fbFMXwRl8wNI/ZlVimsEsEWqa+p1iKOA=" [mod."gorm.io/driver/postgres"] - version = "v1.5.9" - hash = "sha256-C/ieKeHEsR0sS8kG4YZaMCkWCBRfcRC4RH5nIyWQGX4=" + version = "v1.5.11" + hash = "sha256-yayo9uKVOlZ3XR4iOPA5SOhIZek8C5fkXXYu9fOTqZY=" [mod."gorm.io/driver/sqlite"] - version = "v1.5.6" - hash = "sha256-ruKKw0WUlpVkkGGO0lsaXfhy5RmbgpSJ0qEA5ICPqlA=" + version = "v1.5.7" + hash = "sha256-BuliZdxfRe8qwMHxOOEn6PZSfec6x6Gv3SOTil4aOso=" [mod."gorm.io/gorm"] - version = "v1.25.11" - hash = "sha256-cR0jsCCR0CpqSA0Ci5Uq0/1YDONj3dl6lRuRYcu4HpQ=" + version = "v1.25.12" + hash = "sha256-GDUgUp7FmmuNTVb+EcnhVqmPExp2VjS5vHU3m4HqGyM=" [mod."rsc.io/qr"] version = "v0.2.0" hash = "sha256-I3fAJwwZhIrgBbCjWvIElAE9JqG2y59KRBc78EYi3RM=" diff --git a/main.go b/main.go index bcc9bc6..82e240a 100644 --- a/main.go +++ b/main.go @@ -34,6 +34,14 @@ func main() { panic(fmt.Errorf("failed to load config file: %s", err)) } + deprecatedOptions := state.GetDeprecatedConfigOptions(cfg) + if deprecatedOptions != nil { + fmt.Println("The following options have been deprecated/removed:") + for num, opt := range deprecatedOptions { + fmt.Printf("%d. %s: %s\n", num+1, opt.Name, opt.Description) + } + } + if cfg.Telegram.APIURL == "" { cfg.Telegram.APIURL = gotgbot.DefaultAPIURL } @@ -241,7 +249,7 @@ func main() { } SKIP_RESTART: - if !startMessageSuccessful { + if !startMessageSuccessful && !cfg.Telegram.SkipStartupMessage { state.State.TelegramBot.SendMessage(cfg.Telegram.OwnerID, "Successfully started WaTgBridge", &gotgbot.SendMessageOpts{}) } diff --git a/nix/pkgs/watgbridge-dev.nix b/nix/pkgs/watgbridge-dev.nix index 6831ce3..7e18434 100644 --- a/nix/pkgs/watgbridge-dev.nix +++ b/nix/pkgs/watgbridge-dev.nix @@ -1,10 +1,7 @@ -{ lib -, buildGoApplication -, enableFfmpeg ? true -, enableLibWebPTools ? true -, ffmpeg -, libwebp -, nix-filter +{ + lib, + buildGoApplication, + nix-filter, }: let @@ -28,26 +25,23 @@ let ]; }; -in buildGoApplication rec { +in +buildGoApplication rec { pname = "watgbridge"; - version = "1.9.0"; + version = (lib.trim (builtins.readFile ../../state/version.txt)); pwd = localSrc; src = localSrc; - buildInputs = [ - ] ++ lib.optionals enableFfmpeg [ - ffmpeg - ] ++ lib.optionals enableLibWebPTools [ - libwebp + ldflags = [ + "-s" + "-w" ]; - ldflags = [ "-s" "-w" ]; - meta = with lib; rec { description = "A bridge between WhatsApp and Telegram written in Golang"; homepage = "https://github.com/watgbridge/watgbridge"; - changelog = "${homepage}/compare/watgbridge-v${version}...main"; + changelog = "${homepage}/compare/v${version}...main"; license = licenses.mit; mainProgram = "watgbridge"; }; diff --git a/sample_config.yaml b/sample_config.yaml index 6ddb873..d631bc3 100644 --- a/sample_config.yaml +++ b/sample_config.yaml @@ -24,7 +24,13 @@ telegram: send_my_read_receipts: false # Setting this to true will mark all unread messages in a chat as read when you send a new message using Telegram silent_confirmation: true # Send a silent "Successfully sent" message - emoji_confirmation: true # Reacts to the message with a "👍" emoji instead of replying + confirmation_type: "emoji" # Can have three values: "text", "emoji" or "none" + + skip_startup_message: false # If set to true, then a message will NOT be sent to your Telegram DM when the bot starts + + spoiler_as_viewonce: true # If set to true, then all the spoiler files will be sent as view-once messages + + reactions: true # If set to true, will send you new text messages whenever a user reacts to your message or revokes their reaction. whatsapp: session_name: watgbridge # This will appear in your Linked Devices in mobile app diff --git a/state/config.go b/state/config.go index 548f713..e8b473c 100644 --- a/state/config.go +++ b/state/config.go @@ -32,7 +32,11 @@ type Config struct { SendMyPresence bool `yaml:"send_my_presence"` SendMyReadReceipts bool `yaml:"send_my_read_receipts"` SilentConfirmation bool `yaml:"silent_confirmation"` - EmojiConfirmation bool `yaml:"emoji_confirmation"` + ConfirmationType string `yaml:"confirmation_type"` + EmojiConfirmation *bool `yaml:"emoji_confirmation"` + SkipStartupMessage bool `yaml:"skip_startup_message"` + SpoilerViewOnce bool `yaml:"spoiler_as_viewonce"` + Reactions bool `yaml:"reactions"` } `yaml:"telegram"` WhatsApp struct { @@ -120,9 +124,12 @@ func (cfg *Config) SaveConfig() error { func (cfg *Config) SetDefaults() { cfg.TimeZone = "UTC" + cfg.WhatsApp.SessionName = "watgbridge" cfg.WhatsApp.LoginDatabase.Type = "sqlite3" cfg.WhatsApp.LoginDatabase.URL = "file:wawebstore.db?foreign_keys=on" cfg.WhatsApp.StickerMetadata.PackName = "WaTgBridge" cfg.WhatsApp.StickerMetadata.AuthorName = "WaTgBridge" + + cfg.Telegram.ConfirmationType = "emoji" } diff --git a/state/state.go b/state/state.go index 041d278..40a97cf 100644 --- a/state/state.go +++ b/state/state.go @@ -1,6 +1,8 @@ package state import ( + _ "embed" + "strings" "time" "github.com/PaulSonOfLars/gotgbot/v2" @@ -10,7 +12,8 @@ import ( "gorm.io/gorm" ) -const WATGBRIDGE_VERSION = "1.9.2" +//go:embed version.txt +var WATGBRIDGE_VERSION string type state struct { Config *Config @@ -33,5 +36,6 @@ type state struct { var State state func init() { + WATGBRIDGE_VERSION = strings.TrimSpace(WATGBRIDGE_VERSION) State.Config = &Config{Path: "config.yaml"} } diff --git a/state/utils.go b/state/utils.go new file mode 100644 index 0000000..be1ea87 --- /dev/null +++ b/state/utils.go @@ -0,0 +1,33 @@ +package state + +type DeprecatedOption struct { + Name string + Description string +} + +func GetDeprecatedConfigOptions(cfg *Config) []DeprecatedOption { + + returnValue := []DeprecatedOption{} + + if cfg.Telegram.EmojiConfirmation != nil { + returnValue = append(returnValue, DeprecatedOption{ + Name: "[telegram.emoji_confirmation]", + Description: "It has been replaced with [telegram.confirmation_type]", + }) + + if *cfg.Telegram.EmojiConfirmation { + cfg.Telegram.ConfirmationType = "emoji" + } else { + cfg.Telegram.ConfirmationType = "text" + } + cfg.Telegram.EmojiConfirmation = nil + + cfg.SaveConfig() + } + + if len(returnValue) > 0 { + return returnValue + } else { + return nil + } +} diff --git a/state/version.txt b/state/version.txt new file mode 100644 index 0000000..0eed1a2 --- /dev/null +++ b/state/version.txt @@ -0,0 +1 @@ +1.12.0 diff --git a/utils/telegram.go b/utils/telegram.go index 2a67ecd..42f1cdd 100644 --- a/utils/telegram.go +++ b/utils/telegram.go @@ -1,6 +1,7 @@ package utils import ( + "bytes" "context" "fmt" "html" @@ -16,6 +17,7 @@ import ( "github.com/PaulSonOfLars/gotgbot/v2" "github.com/PaulSonOfLars/gotgbot/v2/ext" + goVCard "github.com/emersion/go-vcard" "github.com/forPelevin/gomoji" "go.mau.fi/whatsmeow" "go.mau.fi/whatsmeow/proto/waCommon" @@ -304,7 +306,7 @@ func TgSendToWhatsApp(b *gotgbot.Bot, c *ext.Context, FileEncSHA256: uploadedImage.FileEncSHA256, FileSHA256: uploadedImage.FileSHA256, FileLength: proto.Uint64(uint64(len(imageBytes))), - ViewOnce: proto.Bool(msgToForward.HasProtectedContent), + ViewOnce: proto.Bool(msgToForward.HasProtectedContent || (msgToForward.HasMediaSpoiler && cfg.Telegram.SpoilerViewOnce)), Height: proto.Uint32(uint32(bestPhoto.Height)), Width: proto.Uint32(uint32(bestPhoto.Width)), ContextInfo: &waE2E.ContextInfo{}, @@ -327,21 +329,7 @@ func TgSendToWhatsApp(b *gotgbot.Bot, c *ext.Context, return TgReplyWithErrorByContext(b, c, "Failed to send image to WhatsApp", err) } revokeKeyboard := TgMakeRevokeKeyboard(sentMsg.ID, waChatJID.String(), false) - if cfg.Telegram.EmojiConfirmation { - b.SetMessageReaction( - msgToForward.Chat.Id, - msgToForward.MessageId, - &gotgbot.SetMessageReactionOpts{Reaction: []gotgbot.ReactionType{gotgbot.ReactionTypeEmoji{Emoji: "👍"}}}, - ) - } else { - msg, err := TgReplyTextByContext(b, c, "Successfully sent", revokeKeyboard, cfg.Telegram.SilentConfirmation) - if err == nil { - go func(_b *gotgbot.Bot, _m *gotgbot.Message) { - time.Sleep(15 * time.Second) - _b.DeleteMessage(_m.Chat.Id, _m.MessageId, &gotgbot.DeleteMessageOpts{}) - }(b, msg) - } - } + SendMessageConfirmation(b, c, cfg, msgToForward, revokeKeyboard) err = database.MsgIdAddNewPair(sentMsg.ID, waClient.Store.ID.String(), waChatJID.String(), cfg.Telegram.TargetChatID, msgToForward.MessageId, msgToForward.MessageThreadId) @@ -385,7 +373,7 @@ func TgSendToWhatsApp(b *gotgbot.Bot, c *ext.Context, FileEncSHA256: uploadedVideo.FileEncSHA256, FileSHA256: uploadedVideo.FileSHA256, FileLength: proto.Uint64(uint64(len(videoBytes))), - ViewOnce: proto.Bool(msgToForward.HasProtectedContent), + ViewOnce: proto.Bool(msgToForward.HasProtectedContent || (msgToForward.HasMediaSpoiler && cfg.Telegram.SpoilerViewOnce)), Seconds: proto.Uint32(uint32(msgToForward.Video.Duration)), GifPlayback: proto.Bool(false), Height: proto.Uint32(uint32(msgToForward.Video.Height)), @@ -410,21 +398,7 @@ func TgSendToWhatsApp(b *gotgbot.Bot, c *ext.Context, return TgReplyWithErrorByContext(b, c, "Failed to send video to WhatsApp", err) } revokeKeyboard := TgMakeRevokeKeyboard(sentMsg.ID, waChatJID.String(), false) - if cfg.Telegram.EmojiConfirmation { - b.SetMessageReaction( - msgToForward.Chat.Id, - msgToForward.MessageId, - &gotgbot.SetMessageReactionOpts{Reaction: []gotgbot.ReactionType{gotgbot.ReactionTypeEmoji{Emoji: "👍"}}}, - ) - } else { - msg, err := TgReplyTextByContext(b, c, "Successfully sent", revokeKeyboard, cfg.Telegram.SilentConfirmation) - if err == nil { - go func(_b *gotgbot.Bot, _m *gotgbot.Message) { - time.Sleep(15 * time.Second) - _b.DeleteMessage(_m.Chat.Id, _m.MessageId, &gotgbot.DeleteMessageOpts{}) - }(b, msg) - } - } + SendMessageConfirmation(b, c, cfg, msgToForward, revokeKeyboard) err = database.MsgIdAddNewPair(sentMsg.ID, waClient.Store.ID.String(), waChatJID.String(), cfg.Telegram.TargetChatID, msgToForward.MessageId, msgToForward.MessageThreadId) @@ -458,7 +432,7 @@ func TgSendToWhatsApp(b *gotgbot.Bot, c *ext.Context, } msgToSend := &waE2E.Message{ - VideoMessage: &waE2E.VideoMessage{ + PtvMessage: &waE2E.VideoMessage{ Caption: proto.String(msgToForward.Caption), URL: proto.String(uploadedVideo.URL), DirectPath: proto.String(uploadedVideo.DirectPath), @@ -467,22 +441,22 @@ func TgSendToWhatsApp(b *gotgbot.Bot, c *ext.Context, FileEncSHA256: uploadedVideo.FileEncSHA256, FileSHA256: uploadedVideo.FileSHA256, FileLength: proto.Uint64(uint64(len(videoBytes))), - ViewOnce: proto.Bool(msgToForward.HasProtectedContent), + ViewOnce: proto.Bool(msgToForward.HasProtectedContent || (msgToForward.HasMediaSpoiler && cfg.Telegram.SpoilerViewOnce)), Seconds: proto.Uint32(uint32(msgToForward.VideoNote.Duration)), GifPlayback: proto.Bool(false), ContextInfo: &waE2E.ContextInfo{}, }, } if isReply { - msgToSend.VideoMessage.ContextInfo.StanzaID = proto.String(stanzaId) - msgToSend.VideoMessage.ContextInfo.Participant = proto.String(participant) - msgToSend.VideoMessage.ContextInfo.QuotedMessage = &waE2E.Message{Conversation: proto.String("")} + msgToSend.PtvMessage.ContextInfo.StanzaID = proto.String(stanzaId) + msgToSend.PtvMessage.ContextInfo.Participant = proto.String(participant) + msgToSend.PtvMessage.ContextInfo.QuotedMessage = &waE2E.Message{Conversation: proto.String("")} } if len(mentions) > 0 { - msgToSend.VideoMessage.ContextInfo.MentionedJID = mentions + msgToSend.PtvMessage.ContextInfo.MentionedJID = mentions } if isEphemeral { - msgToSend.VideoMessage.ContextInfo.Expiration = &ephemeralTimer + msgToSend.PtvMessage.ContextInfo.Expiration = &ephemeralTimer } sentMsg, err := waClient.SendMessage(context.Background(), waChatJID, msgToSend) @@ -490,21 +464,7 @@ func TgSendToWhatsApp(b *gotgbot.Bot, c *ext.Context, return TgReplyWithErrorByContext(b, c, "Failed to send video note to WhatsApp", err) } revokeKeyboard := TgMakeRevokeKeyboard(sentMsg.ID, waChatJID.String(), false) - if cfg.Telegram.EmojiConfirmation { - b.SetMessageReaction( - msgToForward.Chat.Id, - msgToForward.MessageId, - &gotgbot.SetMessageReactionOpts{Reaction: []gotgbot.ReactionType{gotgbot.ReactionTypeEmoji{Emoji: "👍"}}}, - ) - } else { - msg, err := TgReplyTextByContext(b, c, "Successfully sent", revokeKeyboard, cfg.Telegram.SilentConfirmation) - if err == nil { - go func(_b *gotgbot.Bot, _m *gotgbot.Message) { - time.Sleep(15 * time.Second) - _b.DeleteMessage(_m.Chat.Id, _m.MessageId, &gotgbot.DeleteMessageOpts{}) - }(b, msg) - } - } + SendMessageConfirmation(b, c, cfg, msgToForward, revokeKeyboard) err = database.MsgIdAddNewPair(sentMsg.ID, waClient.Store.ID.String(), waChatJID.String(), cfg.Telegram.TargetChatID, msgToForward.MessageId, msgToForward.MessageThreadId) @@ -548,7 +508,7 @@ func TgSendToWhatsApp(b *gotgbot.Bot, c *ext.Context, FileEncSHA256: uploadedAnimation.FileEncSHA256, FileSHA256: uploadedAnimation.FileSHA256, FileLength: proto.Uint64(uint64(len(animationBytes))), - ViewOnce: proto.Bool(msgToForward.HasProtectedContent), + ViewOnce: proto.Bool(msgToForward.HasProtectedContent || (msgToForward.HasMediaSpoiler && cfg.Telegram.SpoilerViewOnce)), Height: proto.Uint32(uint32(msgToForward.Animation.Height)), Width: proto.Uint32(uint32(msgToForward.Animation.Width)), Seconds: proto.Uint32(uint32(msgToForward.Animation.Duration)), @@ -573,21 +533,7 @@ func TgSendToWhatsApp(b *gotgbot.Bot, c *ext.Context, return TgReplyWithErrorByContext(b, c, "Failed to send animation to WhatsApp", err) } revokeKeyboard := TgMakeRevokeKeyboard(sentMsg.ID, waChatJID.String(), false) - if cfg.Telegram.EmojiConfirmation { - b.SetMessageReaction( - msgToForward.Chat.Id, - msgToForward.MessageId, - &gotgbot.SetMessageReactionOpts{Reaction: []gotgbot.ReactionType{gotgbot.ReactionTypeEmoji{Emoji: "👍"}}}, - ) - } else { - msg, err := TgReplyTextByContext(b, c, "Successfully sent", revokeKeyboard, cfg.Telegram.SilentConfirmation) - if err == nil { - go func(_b *gotgbot.Bot, _m *gotgbot.Message) { - time.Sleep(15 * time.Second) - _b.DeleteMessage(_m.Chat.Id, _m.MessageId, &gotgbot.DeleteMessageOpts{}) - }(b, msg) - } - } + SendMessageConfirmation(b, c, cfg, msgToForward, revokeKeyboard) err = database.MsgIdAddNewPair(sentMsg.ID, waClient.Store.ID.String(), waChatJID.String(), cfg.Telegram.TargetChatID, msgToForward.MessageId, msgToForward.MessageThreadId) @@ -651,21 +597,7 @@ func TgSendToWhatsApp(b *gotgbot.Bot, c *ext.Context, return TgReplyWithErrorByContext(b, c, "Failed to send audio to WhatsApp", err) } revokeKeyboard := TgMakeRevokeKeyboard(sentMsg.ID, waChatJID.String(), false) - if cfg.Telegram.EmojiConfirmation { - b.SetMessageReaction( - msgToForward.Chat.Id, - msgToForward.MessageId, - &gotgbot.SetMessageReactionOpts{Reaction: []gotgbot.ReactionType{gotgbot.ReactionTypeEmoji{Emoji: "👍"}}}, - ) - } else { - msg, err := TgReplyTextByContext(b, c, "Successfully sent", revokeKeyboard, cfg.Telegram.SilentConfirmation) - if err == nil { - go func(_b *gotgbot.Bot, _m *gotgbot.Message) { - time.Sleep(15 * time.Second) - _b.DeleteMessage(_m.Chat.Id, _m.MessageId, &gotgbot.DeleteMessageOpts{}) - }(b, msg) - } - } + SendMessageConfirmation(b, c, cfg, msgToForward, revokeKeyboard) err = database.MsgIdAddNewPair(sentMsg.ID, waClient.Store.ID.String(), waChatJID.String(), cfg.Telegram.TargetChatID, msgToForward.MessageId, msgToForward.MessageThreadId) @@ -729,21 +661,7 @@ func TgSendToWhatsApp(b *gotgbot.Bot, c *ext.Context, return TgReplyWithErrorByContext(b, c, "Failed to send voice to WhatsApp", err) } revokeKeyboard := TgMakeRevokeKeyboard(sentMsg.ID, waChatJID.String(), false) - if cfg.Telegram.EmojiConfirmation { - b.SetMessageReaction( - msgToForward.Chat.Id, - msgToForward.MessageId, - &gotgbot.SetMessageReactionOpts{Reaction: []gotgbot.ReactionType{gotgbot.ReactionTypeEmoji{Emoji: "👍"}}}, - ) - } else { - msg, err := TgReplyTextByContext(b, c, "Successfully sent", revokeKeyboard, cfg.Telegram.SilentConfirmation) - if err == nil { - go func(_b *gotgbot.Bot, _m *gotgbot.Message) { - time.Sleep(15 * time.Second) - _b.DeleteMessage(_m.Chat.Id, _m.MessageId, &gotgbot.DeleteMessageOpts{}) - }(b, msg) - } - } + SendMessageConfirmation(b, c, cfg, msgToForward, revokeKeyboard) err = database.MsgIdAddNewPair(sentMsg.ID, waClient.Store.ID.String(), waChatJID.String(), cfg.Telegram.TargetChatID, msgToForward.MessageId, msgToForward.MessageThreadId) @@ -776,13 +694,11 @@ func TgSendToWhatsApp(b *gotgbot.Bot, c *ext.Context, return TgReplyWithErrorByContext(b, c, "Failed to upload document to WhatsApp", err) } - splitName := strings.Split(msgToForward.Document.FileName, ".") - documentFileName := strings.Join(splitName[:len(splitName)-1], ".") - msgToSend := &waE2E.Message{ DocumentMessage: &waE2E.DocumentMessage{ Caption: proto.String(msgToForward.Caption), - Title: proto.String(documentFileName), + Title: proto.String(msgToForward.Document.FileName), + FileName: proto.String(msgToForward.Document.FileName), URL: proto.String(uploadedDocument.URL), DirectPath: proto.String(uploadedDocument.DirectPath), MediaKey: uploadedDocument.MediaKey, @@ -810,21 +726,7 @@ func TgSendToWhatsApp(b *gotgbot.Bot, c *ext.Context, return TgReplyWithErrorByContext(b, c, "Failed to send document to WhatsApp", err) } revokeKeyboard := TgMakeRevokeKeyboard(sentMsg.ID, waChatJID.String(), false) - if cfg.Telegram.EmojiConfirmation { - b.SetMessageReaction( - msgToForward.Chat.Id, - msgToForward.MessageId, - &gotgbot.SetMessageReactionOpts{Reaction: []gotgbot.ReactionType{gotgbot.ReactionTypeEmoji{Emoji: "👍"}}}, - ) - } else { - msg, err := TgReplyTextByContext(b, c, "Successfully sent", revokeKeyboard, cfg.Telegram.SilentConfirmation) - if err == nil { - go func(_b *gotgbot.Bot, _m *gotgbot.Message) { - time.Sleep(15 * time.Second) - _b.DeleteMessage(_m.Chat.Id, _m.MessageId, &gotgbot.DeleteMessageOpts{}) - }(b, msg) - } - } + SendMessageConfirmation(b, c, cfg, msgToForward, revokeKeyboard) err = database.MsgIdAddNewPair(sentMsg.ID, waClient.Store.ID.String(), waChatJID.String(), cfg.Telegram.TargetChatID, msgToForward.MessageId, msgToForward.MessageThreadId) @@ -929,27 +831,131 @@ func TgSendToWhatsApp(b *gotgbot.Bot, c *ext.Context, return TgReplyWithErrorByContext(b, c, "Failed to send sticker to WhatsApp", err) } revokeKeyboard := TgMakeRevokeKeyboard(sentMsg.ID, waChatJID.String(), false) - if cfg.Telegram.EmojiConfirmation { - b.SetMessageReaction( - msgToForward.Chat.Id, - msgToForward.MessageId, - &gotgbot.SetMessageReactionOpts{Reaction: []gotgbot.ReactionType{gotgbot.ReactionTypeEmoji{Emoji: "👍"}}}, - ) + SendMessageConfirmation(b, c, cfg, msgToForward, revokeKeyboard) + + err = database.MsgIdAddNewPair(sentMsg.ID, waClient.Store.ID.String(), waChatJID.String(), + cfg.Telegram.TargetChatID, msgToForward.MessageId, msgToForward.MessageThreadId) + if err != nil { + return TgReplyWithErrorByContext(b, c, "Failed to add to database", err) + } + } else if msgToForward.Contact != nil { + + contact := msgToForward.Contact + + var displayName string + if contact.FirstName != "" { + displayName = contact.FirstName + if contact.LastName != "" { + displayName += (" " + contact.LastName) + } + } else { + displayName = contact.PhoneNumber + } + + var vcard string + if contact.Vcard == "" { + + card := goVCard.Card{} + card.SetName(&goVCard.Name{ + FamilyName: contact.LastName, + GivenName: contact.FirstName, + }) + card.SetValue(goVCard.FieldTelephone, contact.PhoneNumber) + card.SetValue(goVCard.FieldFormattedName, displayName) + card.SetValue(goVCard.FieldVersion, "3.0") + + vcardBytes := bytes.NewBuffer([]byte{}) + encoder := goVCard.NewEncoder(vcardBytes) + encoder.Encode(card) + + vcard = vcardBytes.String() } else { - msg, err := TgReplyTextByContext(b, c, "Successfully sent", revokeKeyboard, cfg.Telegram.SilentConfirmation) - if err == nil { - go func(_b *gotgbot.Bot, _m *gotgbot.Message) { - time.Sleep(15 * time.Second) - _b.DeleteMessage(_m.Chat.Id, _m.MessageId, &gotgbot.DeleteMessageOpts{}) - }(b, msg) + vcard = contact.Vcard + } + + msgToSend := &waE2E.Message{ + ContactMessage: &waE2E.ContactMessage{ + DisplayName: &displayName, + Vcard: &vcard, + ContextInfo: &waE2E.ContextInfo{}, + }, + } + if isReply { + msgToSend.ContactMessage.ContextInfo.StanzaID = proto.String(stanzaId) + msgToSend.ContactMessage.ContextInfo.Participant = proto.String(participant) + msgToSend.ContactMessage.ContextInfo.QuotedMessage = &waE2E.Message{Conversation: proto.String("")} + } + if isEphemeral { + msgToSend.ContactMessage.ContextInfo.Expiration = &ephemeralTimer + } + + sentMsg, err := waClient.SendMessage(context.Background(), waChatJID, msgToSend) + if err != nil { + return TgReplyWithErrorByContext(b, c, "Failed to send sticker to WhatsApp", err) + } + revokeKeyboard := TgMakeRevokeKeyboard(sentMsg.ID, waChatJID.String(), false) + SendMessageConfirmation(b, c, cfg, msgToForward, revokeKeyboard) + + err = database.MsgIdAddNewPair(sentMsg.ID, waClient.Store.ID.String(), waChatJID.String(), + cfg.Telegram.TargetChatID, msgToForward.MessageId, msgToForward.MessageThreadId) + if err != nil { + return TgReplyWithErrorByContext(b, c, "Failed to add to database", err) + } + + } else if msgToForward.Location != nil { + + location := msgToForward.Location + isLive := (location.LivePeriod > 0) + + msgToSend := &waE2E.Message{} + if isLive { + // TODO: make this live + msgToSend.LiveLocationMessage = &waE2E.LiveLocationMessage{ + DegreesLatitude: &location.Latitude, + DegreesLongitude: &location.Longitude, + AccuracyInMeters: proto.Uint32(uint32(location.HorizontalAccuracy)), + DegreesClockwiseFromMagneticNorth: proto.Uint32(uint32(location.Heading)), + ContextInfo: &waE2E.ContextInfo{}, + } + if isReply { + msgToSend.LiveLocationMessage.ContextInfo.StanzaID = proto.String(stanzaId) + msgToSend.LiveLocationMessage.ContextInfo.Participant = proto.String(participant) + msgToSend.LiveLocationMessage.ContextInfo.QuotedMessage = &waE2E.Message{Conversation: proto.String("")} + } + if isEphemeral { + msgToSend.LiveLocationMessage.ContextInfo.Expiration = &ephemeralTimer + } + } else { + msgToSend.LocationMessage = &waE2E.LocationMessage{ + DegreesLatitude: &location.Latitude, + DegreesLongitude: &location.Longitude, + DegreesClockwiseFromMagneticNorth: proto.Uint32(uint32(location.Heading)), + AccuracyInMeters: proto.Uint32(uint32(location.HorizontalAccuracy)), + ContextInfo: &waE2E.ContextInfo{}, + } + if isReply { + msgToSend.LocationMessage.ContextInfo.StanzaID = proto.String(stanzaId) + msgToSend.LocationMessage.ContextInfo.Participant = proto.String(participant) + msgToSend.LocationMessage.ContextInfo.QuotedMessage = &waE2E.Message{Conversation: proto.String("")} + } + if isEphemeral { + msgToSend.LocationMessage.ContextInfo.Expiration = &ephemeralTimer } } + sentMsg, err := waClient.SendMessage(context.Background(), waChatJID, msgToSend) + if err != nil { + return TgReplyWithErrorByContext(b, c, "Failed to send sticker to WhatsApp", err) + } + revokeKeyboard := TgMakeRevokeKeyboard(sentMsg.ID, waChatJID.String(), false) + SendMessageConfirmation(b, c, cfg, msgToForward, revokeKeyboard) + err = database.MsgIdAddNewPair(sentMsg.ID, waClient.Store.ID.String(), waChatJID.String(), cfg.Telegram.TargetChatID, msgToForward.MessageId, msgToForward.MessageThreadId) if err != nil { return TgReplyWithErrorByContext(b, c, "Failed to add to database", err) } + } else if msgToForward.Text != "" { if emojis := gomoji.CollectAll(msgToForward.Text); isReply && len(emojis) == 1 && gomoji.RemoveEmojis(msgToForward.Text) == "" { @@ -967,12 +973,16 @@ func TgSendToWhatsApp(b *gotgbot.Bot, c *ext.Context, if err != nil { return TgReplyWithErrorByContext(b, c, "Failed to send reaction to WhatsApp", err) } - msg, err := TgReplyTextByContext(b, c, "Successfully reacted", nil, cfg.Telegram.SilentConfirmation) - if err == nil { - go func(_b *gotgbot.Bot, _m *gotgbot.Message) { - time.Sleep(15 * time.Second) - _b.DeleteMessage(_m.Chat.Id, _m.MessageId, &gotgbot.DeleteMessageOpts{}) - }(b, msg) + if cfg.Telegram.ConfirmationType != "none" { + msg, err := TgReplyTextByContext(b, c, "Successfully reacted", nil, cfg.Telegram.SilentConfirmation) + + if err == nil { + go func(_b *gotgbot.Bot, _m *gotgbot.Message) { + time.Sleep(15 * time.Second) + _b.DeleteMessage(_m.Chat.Id, _m.MessageId, &gotgbot.DeleteMessageOpts{}) + }(b, msg) + } + return err } return err } @@ -1002,21 +1012,7 @@ func TgSendToWhatsApp(b *gotgbot.Bot, c *ext.Context, return TgReplyWithErrorByContext(b, c, "Failed to send message to WhatsApp", err) } revokeKeyboard := TgMakeRevokeKeyboard(sentMsg.ID, waChatJID.String(), false) - if cfg.Telegram.EmojiConfirmation { - b.SetMessageReaction( - msgToForward.Chat.Id, - msgToForward.MessageId, - &gotgbot.SetMessageReactionOpts{Reaction: []gotgbot.ReactionType{gotgbot.ReactionTypeEmoji{Emoji: "👍"}}}, - ) - } else { - msg, err := TgReplyTextByContext(b, c, "Successfully sent", revokeKeyboard, cfg.Telegram.SilentConfirmation) - if err == nil { - go func(_b *gotgbot.Bot, _m *gotgbot.Message) { - time.Sleep(15 * time.Second) - _b.DeleteMessage(_m.Chat.Id, _m.MessageId, &gotgbot.DeleteMessageOpts{}) - }(b, msg) - } - } + SendMessageConfirmation(b, c, cfg, msgToForward, revokeKeyboard) err = database.MsgIdAddNewPair(sentMsg.ID, waClient.Store.ID.String(), waChatJID.String(), cfg.Telegram.TargetChatID, msgToForward.MessageId, msgToForward.MessageThreadId) @@ -1095,3 +1091,28 @@ func TgBuildUrlButton(text, url string) gotgbot.InlineKeyboardMarkup { }}}, } } + +func SendMessageConfirmation( + b *gotgbot.Bot, + c *ext.Context, + cfg *state.Config, + msgToForward *gotgbot.Message, + revokeKeyboard *gotgbot.InlineKeyboardMarkup, +) { + switch cfg.Telegram.ConfirmationType { + case "emoji": + b.SetMessageReaction( + msgToForward.Chat.Id, + msgToForward.MessageId, + &gotgbot.SetMessageReactionOpts{Reaction: []gotgbot.ReactionType{gotgbot.ReactionTypeEmoji{Emoji: "👍"}}}, + ) + case "text": + msg, err := TgReplyTextByContext(b, c, "Successfully sent", revokeKeyboard, cfg.Telegram.SilentConfirmation) + if err == nil { + go func(_b *gotgbot.Bot, _m *gotgbot.Message) { + time.Sleep(15 * time.Second) + _b.DeleteMessage(_m.Chat.Id, _m.MessageId, &gotgbot.DeleteMessageOpts{}) + }(b, msg) + } + } +} diff --git a/whatsapp/client.go b/whatsapp/client.go index 62da981..5821a14 100644 --- a/whatsapp/client.go +++ b/whatsapp/client.go @@ -1,8 +1,10 @@ package whatsapp import ( + "bytes" "context" "fmt" + "html" "os" "watgbridge/state" @@ -11,6 +13,7 @@ import ( _ "github.com/jackc/pgx/v5" _ "github.com/mattn/go-sqlite3" "github.com/mdp/qrterminal/v3" + "github.com/skip2/go-qrcode" "go.mau.fi/whatsmeow" "go.mau.fi/whatsmeow/proto/waCompanionReg" "go.mau.fi/whatsmeow/store" @@ -107,12 +110,32 @@ func NewWhatsAppClient() error { } for evt := range qrChan { if evt.Event == "code" { + // var png []byte + // png, _err := qrcode.Encode("aklsdfjasdfaklsdfjlasdfjaskldfjasldfjaklsdfjals", qrcode.Highest, 256) + // if _err != nil { + // panic(_err) + // } + if state.State.TelegramBot != nil { - state.State.TelegramBot.SendMessage( - state.State.Config.Telegram.OwnerID, - "Please check your terminal and scan the QR code to login to WhatsApp.", - &gotgbot.SendMessageOpts{}, - ) + qrCodePNG, err := qrcode.Encode(evt.Code, qrcode.Highest, 512) + if err != nil { + state.State.TelegramBot.SendMessage( + state.State.Config.Telegram.OwnerID, + fmt.Sprintf( + "Please check your terminal and scan the QR code to login to WhatsApp. Failed to encode to PNG and send here:\n%s", + html.EscapeString(err.Error()), + ), + &gotgbot.SendMessageOpts{}, + ) + } else { + state.State.TelegramBot.SendPhoto( + state.State.Config.Telegram.OwnerID, + gotgbot.InputFileByReader("qrcode.png", bytes.NewReader(qrCodePNG)), + &gotgbot.SendPhotoOpts{ + Caption: "Scan the above QR code to login to WhatsApp.", + }, + ) + } } qrterminal.GenerateHalfBlock(evt.Code, qrterminal.L, os.Stdout) } else { diff --git a/whatsapp/handlers.go b/whatsapp/handlers.go index 932adcf..d962b47 100644 --- a/whatsapp/handlers.go +++ b/whatsapp/handlers.go @@ -48,6 +48,9 @@ func WhatsAppEventHandler(evt interface{}) { case *events.PushName: PushNameEventHandler(v) + case *events.UserAbout: + UserAboutEventHandler(v) + case *events.CallOffer: CallOfferEventHandler(v) @@ -286,6 +289,11 @@ func MessageFromOthersEventHandler(text string, v *events.Message, isEdited bool zap.String("event_id", v.Info.ID), ) contextInfo = v.Message.GetVideoMessage().GetContextInfo() + } else if v.Message.GetPtvMessage() != nil { + logger.Debug("taking context info from PtvMessage", + zap.String("event_id", v.Info.ID), + ) + contextInfo = v.Message.GetPtvMessage().GetContextInfo() } else if v.Message.GetAudioMessage() != nil { logger.Debug("taking context info from AudioMessage", zap.String("event_id", v.Info.ID), @@ -496,6 +504,7 @@ func MessageFromOthersEventHandler(text string, v *events.Message, isEdited bool ReplyParameters: &gotgbot.ReplyParameters{ MessageId: replyToMsgId, }, + HasSpoiler: imageMsg.GetViewOnce(), MessageThreadId: threadId, }) if sentMsg.MessageId != 0 { @@ -582,9 +591,17 @@ func MessageFromOthersEventHandler(text string, v *events.Message, isEdited bool return } - } else if v.Message.GetVideoMessage() != nil { + } else if v.Message.GetVideoMessage() != nil || v.Message.GetPtvMessage() != nil { + + var videoMsg *waE2E.VideoMessage = nil + isPtvMsg := false + if v.Message.GetVideoMessage() != nil { + videoMsg = v.Message.GetVideoMessage() + } else { + videoMsg = v.Message.GetPtvMessage() + isPtvMsg = true + } - videoMsg := v.Message.GetVideoMessage() if videoMsg.GetURL() == "" { return } @@ -645,13 +662,25 @@ func MessageFromOthersEventHandler(text string, v *events.Message, isEdited bool Data: bytes.NewReader(videoBytes), } - sentMsg, _ := tgBot.SendVideo(cfg.Telegram.TargetChatID, &fileToSend, &gotgbot.SendVideoOpts{ - Caption: bridgedText, - ReplyParameters: &gotgbot.ReplyParameters{ - MessageId: replyToMsgId, - }, - MessageThreadId: threadId, - }) + var sentMsg *gotgbot.Message = nil + if isPtvMsg { + sentMsg, _ = tgBot.SendVideoNote(cfg.Telegram.TargetChatID, &fileToSend, &gotgbot.SendVideoNoteOpts{ + ReplyMarkup: replyMarkup, + ReplyParameters: &gotgbot.ReplyParameters{ + MessageId: replyToMsgId, + }, + MessageThreadId: threadId, + }) + } else { + sentMsg, _ = tgBot.SendVideo(cfg.Telegram.TargetChatID, &fileToSend, &gotgbot.SendVideoOpts{ + Caption: bridgedText, + ReplyParameters: &gotgbot.ReplyParameters{ + MessageId: replyToMsgId, + }, + HasSpoiler: videoMsg.GetViewOnce(), + MessageThreadId: threadId, + }) + } if sentMsg.MessageId != 0 { database.MsgIdAddNewPair(msgId, v.Info.MessageSource.Sender.String(), v.Info.Chat.String(), cfg.Telegram.TargetChatID, sentMsg.MessageId, sentMsg.MessageThreadId) @@ -1163,6 +1192,45 @@ func MessageFromOthersEventHandler(text string, v *events.Message, isEdited bool } else { if text == "" { + if reactionMsg := v.Message.GetReactionMessage(); cfg.Telegram.Reactions && reactionMsg != nil { + tgChatId, _, tgMsgId, err := database.MsgIdGetTgFromWa(reactionMsg.Key.GetID(), v.Info.Chat.String()) + if err != nil { + logger.Error( + "failed to get message ID mapping from database", + zap.Error(err), + zap.String("stanza_id", reactionMsg.Key.GetID()), + zap.String("chat_id", v.Info.Chat.String()), + ) + } else if tgChatId == cfg.Telegram.TargetChatID { + + if *reactionMsg.Text != "" { + text = fmt.Sprintf( + "Reacted to this message with %s", + html.EscapeString(*reactionMsg.Text), + ) + } else { + text = "Revoked their reaction to this message" + } + + bridgedText += text + + sentMsg, err := tgBot.SendMessage(cfg.Telegram.TargetChatID, bridgedText, &gotgbot.SendMessageOpts{ + ReplyParameters: &gotgbot.ReplyParameters{ + MessageId: tgMsgId, + }, + MessageThreadId: threadId, + }) + if err != nil { + panic(fmt.Errorf("failed to send telegram message: %s", err)) + } + if sentMsg.MessageId != 0 { + database.MsgIdAddNewPair(msgId, v.Info.MessageSource.Sender.String(), v.Info.Chat.String(), + cfg.Telegram.TargetChatID, sentMsg.MessageId, sentMsg.MessageThreadId) + } + } + + } + return } @@ -1245,6 +1313,72 @@ func PushNameEventHandler(v *events.PushName) { database.ContactUpdatePushName(v.JID.User, v.NewPushName) } +func UserAboutEventHandler(v *events.UserAbout) { + var ( + cfg = state.State.Config + logger = state.State.Logger + tgBot = state.State.TelegramBot + ) + defer logger.Sync() + + logger.Debug("new user_about update", + zap.String("jid", v.JID.String()), + zap.String("new_status", v.Status), + zap.Time("updated_at", v.Timestamp), + ) + + tgThreadId, threadFound, err := database.ChatThreadGetTgFromWa(v.JID.ToNonAD().String(), cfg.Telegram.TargetChatID) + if err != nil { + logger.Warn( + "failed to find thread for a WhatsApp chat (handling UserAbout event)", + zap.String("chat", v.JID.String()), + zap.Error(err), + ) + return + } + if !threadFound || tgThreadId == 0 { + logger.Warn( + "no thread found for a WhatsApp chat (handling UserAbout event)", + zap.String("chat", v.JID.String()), + ) + if !cfg.WhatsApp.CreateThreadForInfoUpdates { + return + } + } + + tgThreadId, err = utils.TgGetOrMakeThreadFromWa(v.JID.ToNonAD().String(), cfg.Telegram.TargetChatID, utils.WaGetContactName(v.JID.ToNonAD())) + if err != nil { + logger.Warn( + "failed to create a new thread for a WhatsApp chat (handling UserAbout event)", + zap.String("chat", v.JID.String()), + zap.Error(err), + ) + return + } + + updateMessageText := "User's about message was updated" + if time.Since(v.Timestamp).Seconds() > 60 { + updateMessageText += fmt.Sprintf( + "at %s:\n\n", + html.EscapeString( + v.Timestamp. + In(state.State.LocalLocation). + Format(cfg.TimeFormat), + ), + ) + } else { + updateMessageText += ":\n\n" + } + + updateMessageText += fmt.Sprintf("%s", html.EscapeString(v.Status)) + + tgBot.SendMessage( + cfg.Telegram.TargetChatID, + updateMessageText, + &gotgbot.SendMessageOpts{MessageThreadId: tgThreadId}, + ) +} + func RevokedMessageEventHandler(v *events.Message) { var ( cfg = state.State.Config