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