mirror of
https://github.com/nikoksr/notify.git
synced 2025-02-03 13:01:26 +02:00
feat(service): Add WhatsApp service
This commit is contained in:
parent
dbaa5cd07c
commit
8ce5ea97ec
@ -71,6 +71,7 @@ _ = notifier.Send(
|
||||
- *Slack*
|
||||
- *Telegram*
|
||||
- *Twitter*
|
||||
- *WhatsApp*
|
||||
|
||||
## Roadmap <a id="roadmap"></a>
|
||||
|
||||
@ -90,6 +91,7 @@ _ = notifier.Send(
|
||||
- Slack support: [slack-go/slack](https://github.com/slack-go/slack)
|
||||
- Telegram support: [go-telegram-bot-api/telegram-bot-api](https://github.com/go-telegram-bot-api/telegram-bot-api)
|
||||
- Twitter: [dghubble/go-twitter](https://github.com/dghubble/go-twitter)
|
||||
- WhatsApp: [Rhymen/go-whatsapp](https://github.com/Rhymen/go-whatsapp)
|
||||
|
||||
## Author <a id="author"></a>
|
||||
|
||||
|
9
go.mod
9
go.mod
@ -3,6 +3,8 @@ module github.com/nikoksr/notify
|
||||
go 1.15
|
||||
|
||||
require (
|
||||
github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f
|
||||
github.com/Rhymen/go-whatsapp v0.1.1
|
||||
github.com/atc0005/go-teams-notify/v2 v2.4.2
|
||||
github.com/bwmarrin/discordgo v0.23.2
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
|
||||
@ -11,10 +13,15 @@ require (
|
||||
github.com/dghubble/oauth1 v0.7.0
|
||||
github.com/go-chi/chi v4.1.2+incompatible // indirect
|
||||
github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible
|
||||
github.com/golang/protobuf v1.4.2 // indirect
|
||||
github.com/google/go-cmp v0.5.4 // indirect
|
||||
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/mailgun/mailgun-go/v4 v4.3.3
|
||||
github.com/mattn/go-colorable v0.1.8 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.1 // indirect
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/plivo/plivo-go v5.5.1+incompatible
|
||||
github.com/sendgrid/rest v2.6.2+incompatible // indirect
|
||||
@ -27,5 +34,7 @@ require (
|
||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad // indirect
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c // indirect
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||
)
|
||||
|
62
go.sum
62
go.sum
@ -1,3 +1,12 @@
|
||||
github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f h1:2dk3eOnYllh+wUOuDhOoC2vUVoJF/5z478ryJ+wzEII=
|
||||
github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f/go.mod h1:4a58ifQTEe2uwwsaqbh3i2un5/CBPg+At/qHpt18Tmk=
|
||||
github.com/Rhymen/go-whatsapp v0.0.0/go.mod h1:rdQr95g2C1xcOfM7QGOhza58HeI3I+tZ/bbluv7VazA=
|
||||
github.com/Rhymen/go-whatsapp v0.1.1 h1:OK+bCugQcr2YjyYKeDzULqCtM50TPUFM6LvQtszKfcw=
|
||||
github.com/Rhymen/go-whatsapp v0.1.1/go.mod h1:o7jjkvKnigfu432dMbQ/w4PH0Yp5u4Y6ysCNjUlcYCk=
|
||||
github.com/Rhymen/go-whatsapp/examples/echo v0.0.0-20190325075644-cc2581bbf24d/go.mod h1:zgCiQtBtZ4P4gFWvwl9aashsdwOcbb/EHOGRmSzM8ME=
|
||||
github.com/Rhymen/go-whatsapp/examples/restoreSession v0.0.0-20190325075644-cc2581bbf24d/go.mod h1:5sCUSpG616ZoSJhlt9iBNI/KXBqrVLcNUJqg7J9+8pU=
|
||||
github.com/Rhymen/go-whatsapp/examples/sendImage v0.0.0-20190325075644-cc2581bbf24d/go.mod h1:RdiyhanVEGXTam+mZ3k6Y3VDCCvXYCwReOoxGozqhHw=
|
||||
github.com/Rhymen/go-whatsapp/examples/sendTextMessages v0.0.0-20190325075644-cc2581bbf24d/go.mod h1:suwzklatySS3Q0+NCxCDh5hYfgXdQUWU1DNcxwAxStM=
|
||||
github.com/atc0005/go-teams-notify/v2 v2.4.2 h1:3KQ8e8LN4kwuWWHpnCNTXA15JdLRaNWcCS1VS0a4SO0=
|
||||
github.com/atc0005/go-teams-notify/v2 v2.4.2/go.mod h1:BSlh1HBcgWcGoNM3Abm36WMPcj+k8Wf0ZLZx6lBx2qk=
|
||||
github.com/bwmarrin/discordgo v0.23.2 h1:BzrtTktixGHIu9Tt7dEE6diysEF9HWnXeHuoJEt2fH4=
|
||||
@ -6,6 +15,7 @@ github.com/cenkalti/backoff v2.1.1+incompatible h1:tKJnvO2kl0zmb/jA5UKAt4VoEVw1q
|
||||
github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/cschomburg/go-pushbullet v0.0.0-20171206132031-67759df45fbb h1:7X9nrm+LNWdxzQOiCjy0G51rNUxbH35IDHCjAMvogyM=
|
||||
github.com/cschomburg/go-pushbullet v0.0.0-20171206132031-67759df45fbb/go.mod h1:RfQ9wji3fjcSEsQ+uFCtIh3+BXgcZum8Kt3JxvzYzlk=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@ -31,18 +41,46 @@ github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible h1:2cauKuaEL
|
||||
github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible/go.mod h1:qf9acutJ8cwBUhm1bqgz6Bei9/C/c93FPDljKWwsOgM=
|
||||
github.com/go-test/deep v1.0.4 h1:u2CU3YKy9I2pmu9pX0eq50wCgjfGIt539SqR7FbHiho=
|
||||
github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk=
|
||||
github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible h1:jdpOPRN1zP63Td1hDQbZW73xKmzDvZHzVdNYxhnTMDA=
|
||||
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible/go.mod h1:1c7szIrayyPPB/987hsnvNzLushdWf4o/79s3P08L8A=
|
||||
github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/mailgun/mailgun-go/v4 v4.3.3 h1:fS51t6ZQSkpK0t9irwHtcfzyVj4iR8u+m3oa0R+a12E=
|
||||
github.com/mailgun/mailgun-go/v4 v4.3.3/go.mod h1:fWuBI2iaS/pSSyo6+EBpHjatQO3lV8onwqcRy7joSJI=
|
||||
github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg=
|
||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
|
||||
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw=
|
||||
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
@ -51,6 +89,8 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLD
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
@ -65,6 +105,8 @@ github.com/sendgrid/sendgrid-go v3.8.0+incompatible h1:7yoUFMwT+jDI2ArBpC6zvtuQj
|
||||
github.com/sendgrid/sendgrid-go v3.8.0+incompatible/go.mod h1:QRQt+LX/NmgVEvmdRw0VT/QgUn499+iza2FnDca9fg8=
|
||||
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/skip2/go-qrcode v0.0.0-20190110000554-dc11ecdae0a9 h1:lpEzuenPuO1XNTeikEmvqYFcU37GVLl8SRNblzyvGBE=
|
||||
github.com/skip2/go-qrcode v0.0.0-20190110000554-dc11ecdae0a9/go.mod h1:PLPIyL7ikehBD1OAjmKKiOEhbvWyHGaNDjquXMcYABo=
|
||||
github.com/slack-go/slack v0.8.0 h1:ANyLY5KHLV+MxLJDQum2IuHTLwbCbDtaWY405X1EU9U=
|
||||
github.com/slack-go/slack v0.8.0/go.mod h1:FGqNzJBmxIsZURAxh2a8D21AnOVvvXZvGligs4npPUM=
|
||||
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
|
||||
@ -78,20 +120,40 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
||||
github.com/technoweenie/multipartstreamer v1.0.1 h1:XRztA5MXiR1TIRHxH2uNxXxaIkKQDeX7m2XsSOlQEnM=
|
||||
github.com/technoweenie/multipartstreamer v1.0.1/go.mod h1:jNVxdtShOxzAsukZwTSw6MDx5eUJoiEBsSvzDU9uzog=
|
||||
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190131182504-b8fe1690c613/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY=
|
||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a h1:DcqTD9SDLc+1P/r1EmRBwnVsrOwW+kk2vWf9n+1sGhs=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
||||
|
41
service/whatsapp/README.md
Normal file
41
service/whatsapp/README.md
Normal file
@ -0,0 +1,41 @@
|
||||
# WhatsApp
|
||||
|
||||
[![go.dev reference](https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/nikoksr/notify/service/whatsapp)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
You will need a registered WhatsApp phone number to be used as source for sending WhatsApp messages.
|
||||
|
||||
## Usage
|
||||
|
||||
In the current implementation, authentication requires scanning QR code from terminal using a registered WhatsApp device. Please refer [Login (go-whatsapp)](https://github.com/Rhymen/go-whatsapp#login) and [sigalor/whatsapp-web-reveng](https://github.com/sigalor/whatsapp-web-reveng) for more details.
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/nikoksr/notify"
|
||||
"github.com/nikoksr/notify/service/whatsapp"
|
||||
)
|
||||
|
||||
func main() {
|
||||
whatsappSvc, err := whatsapp.New()
|
||||
if err != nil {
|
||||
log.Fatalf("whatsapp.New() failed: %s", err.Error())
|
||||
}
|
||||
|
||||
whatsappSvc.AddReceivers("Contact1")
|
||||
|
||||
notifier := notify.New()
|
||||
notifier.UseServices(whatsappSvc)
|
||||
|
||||
err = notifier.Send("subject", "message")
|
||||
if err != nil {
|
||||
log.Fatalf("notifier.Send() failed: %s", err.Error())
|
||||
}
|
||||
|
||||
log.Println("notification sent")
|
||||
}
|
||||
```
|
35
service/whatsapp/doc.go
Normal file
35
service/whatsapp/doc.go
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
Package whatsapp provides message notification integration for WhatsApp.
|
||||
|
||||
Usage:
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/nikoksr/notify"
|
||||
"github.com/nikoksr/notify/service/whatsapp"
|
||||
)
|
||||
|
||||
func main() {
|
||||
whatsappSvc, err := whatsapp.New()
|
||||
if err != nil {
|
||||
log.Fatalf("whatsapp.New() failed: %s", err.Error())
|
||||
}
|
||||
|
||||
whatsappSvc.AddReceivers("Contact1")
|
||||
|
||||
notifier := notify.New()
|
||||
notifier.UseServices(whatsappSvc)
|
||||
|
||||
err = notifier.Send("subject", "message")
|
||||
if err != nil {
|
||||
log.Fatalf("notifier.Send() failed: %s", err.Error())
|
||||
}
|
||||
|
||||
log.Println("notification sent")
|
||||
}
|
||||
|
||||
*/
|
||||
package whatsapp
|
31
service/whatsapp/mock_whatsappClient.go
Normal file
31
service/whatsapp/mock_whatsappClient.go
Normal file
@ -0,0 +1,31 @@
|
||||
// Code generated by mockery v2.0.4. DO NOT EDIT.
|
||||
|
||||
package whatsapp
|
||||
|
||||
import mock "github.com/stretchr/testify/mock"
|
||||
|
||||
// mockWhatsappClient is an autogenerated mock type for the whatsappClient type
|
||||
type mockWhatsappClient struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// Send provides a mock function with given fields: msg
|
||||
func (_m *mockWhatsappClient) Send(msg interface{}) (string, error) {
|
||||
ret := _m.Called(msg)
|
||||
|
||||
var r0 string
|
||||
if rf, ok := ret.Get(0).(func(interface{}) string); ok {
|
||||
r0 = rf(msg)
|
||||
} else {
|
||||
r0 = ret.Get(0).(string)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(interface{}) error); ok {
|
||||
r1 = rf(msg)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
145
service/whatsapp/whatsapp.go
Normal file
145
service/whatsapp/whatsapp.go
Normal file
@ -0,0 +1,145 @@
|
||||
package whatsapp
|
||||
|
||||
import (
|
||||
"encoding/gob"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
qrcodeTerminal "github.com/Baozisoftware/qrcode-terminal-go"
|
||||
whatsapp "github.com/Rhymen/go-whatsapp"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
loginWaitTimeSeconds = 3
|
||||
clientTimeout = 5
|
||||
)
|
||||
|
||||
// whatsappClient abstracts go-whatsapp for writing unit tests
|
||||
type whatsappClient interface {
|
||||
Send(msg interface{}) (string, error)
|
||||
}
|
||||
|
||||
// Service encapsulates the WhatsApp client along with internal state for storing contacts.
|
||||
type Service struct {
|
||||
client whatsappClient
|
||||
contacts []string
|
||||
}
|
||||
|
||||
// New returns a new instance of a WhatsApp notification service.
|
||||
func New() (*Service, error) {
|
||||
client, err := whatsapp.NewConn(clientTimeout * time.Second)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = login(client)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
<-time.After(loginWaitTimeSeconds * time.Second)
|
||||
|
||||
s := &Service{
|
||||
client: client,
|
||||
contacts: []string{},
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// login helps with the WhatsApp authentication process.
|
||||
// Refer: https://github.com/Rhymen/go-whatsapp#login for more information.
|
||||
func login(client *whatsapp.Conn) error {
|
||||
session, err := readSession()
|
||||
if err == nil {
|
||||
session, err = client.RestoreWithSession(session)
|
||||
if err != nil {
|
||||
return fmt.Errorf("restoring session failed: %v", err)
|
||||
}
|
||||
} else {
|
||||
// No saved session found; need to login again.
|
||||
qr := make(chan string)
|
||||
go func() {
|
||||
terminal := qrcodeTerminal.New()
|
||||
terminal.Get(<-qr).Print()
|
||||
}()
|
||||
|
||||
session, err = client.Login(qr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error during login: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
err = writeSession(&session)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error saving session: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// readSession helps load saved WhatsApp session from local file system.
|
||||
func readSession() (whatsapp.Session, error) {
|
||||
session := whatsapp.Session{}
|
||||
file, err := os.Open(os.TempDir() + "/whatsappSession.gob")
|
||||
if err != nil {
|
||||
return session, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
decoder := gob.NewDecoder(file)
|
||||
err = decoder.Decode(&session)
|
||||
if err != nil {
|
||||
return session, err
|
||||
}
|
||||
|
||||
return session, nil
|
||||
}
|
||||
|
||||
// writeSession helps save WhatsApp session to local file system.
|
||||
func writeSession(session *whatsapp.Session) error {
|
||||
file, err := os.Create(os.TempDir() + "/whatsappSession.gob")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
encoder := gob.NewEncoder(file)
|
||||
err = encoder.Encode(*session)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddReceivers takes WhatsApp contacts and adds them to the internal contacts list. The Send method will send
|
||||
// a given message to all those contacts.
|
||||
func (s *Service) AddReceivers(contacts ...string) {
|
||||
s.contacts = append(s.contacts, contacts...)
|
||||
}
|
||||
|
||||
// Send takes a message subject and a message body and sends them to all previously set contacts.
|
||||
func (s *Service) Send(subject, message string) error {
|
||||
if len(s.contacts) == 0 {
|
||||
return fmt.Errorf("no contacts added as receivers")
|
||||
}
|
||||
|
||||
msgText := subject + "\n" + message
|
||||
for _, c := range s.contacts {
|
||||
contact := c + "@s.whatsapp.net"
|
||||
msg := whatsapp.TextMessage{
|
||||
Info: whatsapp.MessageInfo{
|
||||
RemoteJid: contact,
|
||||
},
|
||||
Text: msgText,
|
||||
}
|
||||
|
||||
if _, err := s.client.Send(msg); err != nil {
|
||||
return errors.Wrapf(err, "failed to send message to WhatsApp contact '%s'", c)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
67
service/whatsapp/whatsapp_test.go
Normal file
67
service/whatsapp/whatsapp_test.go
Normal file
@ -0,0 +1,67 @@
|
||||
package whatsapp
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
whatsapp "github.com/Rhymen/go-whatsapp"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestAddReceivers(t *testing.T) {
|
||||
assert := require.New(t)
|
||||
|
||||
svc := &Service{
|
||||
contacts: []string{},
|
||||
}
|
||||
contacts := []string{"Contact1", "Contact2", "Contact3"}
|
||||
svc.AddReceivers(contacts...)
|
||||
|
||||
assert.Equal(svc.contacts, contacts)
|
||||
}
|
||||
|
||||
func TestSend(t *testing.T) {
|
||||
assert := require.New(t)
|
||||
|
||||
svc := &Service{
|
||||
contacts: []string{},
|
||||
}
|
||||
|
||||
// no receivers added
|
||||
err := svc.Send("subject", "message")
|
||||
assert.NotNil(err)
|
||||
|
||||
// test whatsapp client returning error
|
||||
mockClient := new(mockWhatsappClient)
|
||||
mockClient.On("Send", whatsapp.TextMessage{
|
||||
Info: whatsapp.MessageInfo{
|
||||
RemoteJid: "Contact1@s.whatsapp.net",
|
||||
},
|
||||
Text: "subject\nmessage",
|
||||
}).Return("", errors.New("some error"))
|
||||
svc.client = mockClient
|
||||
svc.AddReceivers("Contact1")
|
||||
err = svc.Send("subject", "message")
|
||||
assert.NotNil(err)
|
||||
mockClient.AssertExpectations(t)
|
||||
|
||||
// test success and multiple receivers
|
||||
mockClient = new(mockWhatsappClient)
|
||||
mockClient.On("Send", whatsapp.TextMessage{
|
||||
Info: whatsapp.MessageInfo{
|
||||
RemoteJid: "Contact1@s.whatsapp.net",
|
||||
},
|
||||
Text: "subject\nmessage",
|
||||
}).Return("", nil)
|
||||
mockClient.On("Send", whatsapp.TextMessage{
|
||||
Info: whatsapp.MessageInfo{
|
||||
RemoteJid: "Contact2@s.whatsapp.net",
|
||||
},
|
||||
Text: "subject\nmessage",
|
||||
}).Return("", nil)
|
||||
svc.client = mockClient
|
||||
svc.AddReceivers("Contact1", "Contact2")
|
||||
err = svc.Send("subject", "message")
|
||||
assert.Nil(err)
|
||||
mockClient.AssertExpectations(t)
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user