diff --git a/README.md b/README.md index 510e0b38..0e438a74 100644 --- a/README.md +++ b/README.md @@ -54,13 +54,16 @@ notifier.UseServices(telegramService) // Send a test message. _ = notifier.Send( + context.Background(), "Subject/Title", - "The actual message. Hello, you awesome gophers! :)", + "The actual message - Hello, you awesome gophers! :)", ) ``` ## Supported services +> Please create feature requests for missing services (see #3 for example) + - *Amazon SES* - *Discord* - *Email* @@ -74,11 +77,6 @@ _ = notifier.Send( - *Twitter* - *WhatsApp* -## Roadmap - -- [ ] Add tests (see [#1](https://github.com/nikoksr/notify/issues/1)) -- [ ] Add more notification services (Issues and PRs are welcome!) - ## Credits - Amazon SES support: [aws/aws-sdk-go](https://github.com/aws/aws-sdk-go) diff --git a/go.mod b/go.mod index b023e7d0..561c5530 100644 --- a/go.mod +++ b/go.mod @@ -15,12 +15,11 @@ require ( github.com/cschomburg/go-pushbullet v0.0.0-20171206132031-67759df45fbb github.com/dghubble/go-twitter v0.0.0-20201011215211-4b180d0cc78d 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.3 // indirect github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible github.com/magefile/mage v1.11.0 // indirect - github.com/mailgun/mailgun-go/v4 v4.3.3 + github.com/mailgun/mailgun-go/v4 v4.3.4 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 @@ -28,15 +27,15 @@ require ( github.com/plivo/plivo-go v5.5.1+incompatible github.com/sendgrid/rest v2.6.2+incompatible // indirect github.com/sendgrid/sendgrid-go v3.8.0+incompatible - github.com/sirupsen/logrus v1.7.1 // indirect + github.com/sirupsen/logrus v1.8.0 // indirect github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect github.com/slack-go/slack v0.8.1 github.com/stretchr/objx v0.3.0 // indirect github.com/stretchr/testify v1.7.0 github.com/technoweenie/multipartstreamer v1.0.1 // indirect - 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-20210216224549-f992740a1bac // indirect + golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 // indirect + golang.org/x/sync v0.0.0-20210220032951-036812b2e83c + golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43 // indirect google.golang.org/protobuf v1.25.0 // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect ) diff --git a/go.sum b/go.sum index 21d807ae..58bf17a1 100644 --- a/go.sum +++ b/go.sum @@ -31,7 +31,6 @@ github.com/aws/smithy-go v1.1.0 h1:D6CSsM3gdxaGaqXnPgOBCeL6Mophqzu7KJOu7zW78sU= github.com/aws/smithy-go v1.1.0/go.mod h1:EzMw8dbp/YJL4A5/sbhGddag+NPT7q084agLbB9LgIw= github.com/bwmarrin/discordgo v0.23.2 h1:BzrtTktixGHIu9Tt7dEE6diysEF9HWnXeHuoJEt2fH4= github.com/bwmarrin/discordgo v0.23.2/go.mod h1:c1WtWUGN6nREDmzIpyTp/iD3VYt4Fpx+bVyfBG7JE+M= -github.com/cenkalti/backoff v2.1.1+incompatible h1:tKJnvO2kl0zmb/jA5UKAt4VoEVw1qxKWjE/Bpp46npY= 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= @@ -58,8 +57,6 @@ github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870 h1:E2s37DuLxFhQD github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= github.com/go-chi/chi v4.0.0+incompatible h1:SiLLEDyAkqNnw+T/uDTf3aFB9T4FTrwMpuYrgaRcnW4= github.com/go-chi/chi v4.0.0+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= -github.com/go-chi/chi v4.1.2+incompatible h1:fGFk2Gmi/YKXk0OmGfBh0WgmN3XB8lVnEyNz34tQRec= -github.com/go-chi/chi v4.1.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible h1:2cauKuaELYAEARXRkq2LrJ0yDDv1rW7+wrTEdVL3uaU= 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= @@ -67,7 +64,6 @@ github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3a github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 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.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= @@ -83,7 +79,6 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw 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.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w= github.com/google/go-cmp v0.5.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= @@ -102,25 +97,20 @@ github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible 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/magefile/mage v1.10.0 h1:3HiXzCUY12kh9bIuyXShaVe529fJfyqoVM42o/uom2g= github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= github.com/magefile/mage v1.11.0 h1:C/55Ywp9BpgVVclD3lRnSYCwXTYxmSppIgLeDYlNuls= github.com/magefile/mage v1.11.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= -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/mailgun/mailgun-go/v4 v4.3.4 h1:0cpSL0cOryR+UdNuoiCALCboWkdkhs8hNRqM3tp7P1k= +github.com/mailgun/mailgun-go/v4 v4.3.4/go.mod h1:fWuBI2iaS/pSSyo6+EBpHjatQO3lV8onwqcRy7joSJI= 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= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= 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= @@ -137,15 +127,13 @@ github.com/sendgrid/rest v2.6.2+incompatible h1:zGMNhccsPkIc8SvU9x+qdDz2qhFoGUPG github.com/sendgrid/rest v2.6.2+incompatible/go.mod h1:kXX7q3jZtJXK5c5qK83bSGMdV6tsOE70KbHoqJls4lE= github.com/sendgrid/sendgrid-go v3.8.0+incompatible h1:7yoUFMwT+jDI2ArBpC6zvtuQj1RUyYfCDl7zZea3XV4= github.com/sendgrid/sendgrid-go v3.8.0+incompatible/go.mod h1:QRQt+LX/NmgVEvmdRw0VT/QgUn499+iza2FnDca9fg8= -github.com/sirupsen/logrus v1.7.1 h1:rsizeFmZP+GYwyb4V6t6qpG7ZNWzA2bvgW/yC2xHCcg= -github.com/sirupsen/logrus v1.7.1/go.mod h1:4GuYW9TZmE769R5STWrRakJc4UqQ3+QQ95fyz7ENv1A= -github.com/skip2/go-qrcode v0.0.0-20190110000554-dc11ecdae0a9 h1:lpEzuenPuO1XNTeikEmvqYFcU37GVLl8SRNblzyvGBE= +github.com/sirupsen/logrus v1.8.0 h1:nfhvjKcUMhBMVqbKHJlk5RPrrfYr/NMo3692g0dwfWU= +github.com/sirupsen/logrus v1.8.0/go.mod h1:4GuYW9TZmE769R5STWrRakJc4UqQ3+QQ95fyz7ENv1A= github.com/skip2/go-qrcode v0.0.0-20190110000554-dc11ecdae0a9/go.mod h1:PLPIyL7ikehBD1OAjmKKiOEhbvWyHGaNDjquXMcYABo= 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/slack-go/slack v0.8.1 h1:NqGXuzni8Is3EJWmsuMuBiCCPbWOlBgTKPvdlwS3Huk= github.com/slack-go/slack v0.8.1/go.mod h1:FGqNzJBmxIsZURAxh2a8D21AnOVvvXZvGligs4npPUM= -github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.3.0 h1:NGXK3lHquSN08v5vWalVI/L8XU9hdzE/G6xsrze47As= github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= @@ -157,10 +145,9 @@ github.com/technoweenie/multipartstreamer v1.0.1 h1:XRztA5MXiR1TIRHxH2uNxXxaIkKQ 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 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= 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/crypto v0.0.0-20210220033148-5ea612d1eb83 h1:/ZScEX8SfEmUGRHs0gxpqteO5nfNW6axyZbBdw9A12g= +golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -176,18 +163,16 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/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-20190423024810-112230192c58/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/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4= 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-20210216224549-f992740a1bac h1:9glrpwtNjBYgRpb67AZJKHfzj1stG/8BL5H7In2oTC4= -golang.org/x/sys v0.0.0-20210216224549-f992740a1bac/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43 h1:SgQ6LNaYJU0JIuEHv9+s6EbhSCwYeAf5Yvj6lpYlqAE= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/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/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -211,7 +196,6 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ 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.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= @@ -220,7 +204,6 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -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= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/notifier.go b/notifier.go index 09dcf514..26b562f2 100644 --- a/notifier.go +++ b/notifier.go @@ -1,9 +1,11 @@ package notify +import "context" + // Notifier defines the behavior for notification services. // // The Send function simply sends a subject and a message string to the internal destination Notifier. // E.g for telegram.Telegram it sends the message to the specified group chat. type Notifier interface { - Send(string, string) error + Send(context.Context, string, string) error } diff --git a/send.go b/send.go index 0a3ac26f..982208a4 100644 --- a/send.go +++ b/send.go @@ -1,12 +1,14 @@ package notify import ( + "context" + "github.com/pkg/errors" "golang.org/x/sync/errgroup" ) // Send calls the underlying notification services to send the given subject and message to their respective endpoints. -func (n Notify) Send(subject, message string) error { +func (n Notify) Send(ctx context.Context, subject, message string) error { if n.Disabled { return nil } @@ -17,7 +19,7 @@ func (n Notify) Send(subject, message string) error { if service != nil { s := service eg.Go(func() error { - return s.Send(subject, message) + return s.Send(ctx, subject, message) }) } } diff --git a/service/amazonses/amazon_ses.go b/service/amazonses/amazon_ses.go index 7abf3773..03c2ca0d 100644 --- a/service/amazonses/amazon_ses.go +++ b/service/amazonses/amazon_ses.go @@ -48,7 +48,7 @@ func (a *AmazonSES) AddReceivers(addresses ...string) { // Send takes a message subject and a message body and sends them to all previously set chats. Message body supports // html as markup language. -func (a AmazonSES) Send(subject, message string) error { +func (a AmazonSES) Send(ctx context.Context, subject, message string) error { input := &ses.SendEmailInput{ Source: a.senderAddress, Destination: &types.Destination{ @@ -69,7 +69,7 @@ func (a AmazonSES) Send(subject, message string) error { }, } - _, err := a.client.SendEmail(context.Background(), input) + _, err := a.client.SendEmail(ctx, input) if err != nil { return errors.Wrap(err, "failed to send mail using Amazon SES service") } diff --git a/service/discord/discord.go b/service/discord/discord.go index 0c2d96cf..293d2b6a 100644 --- a/service/discord/discord.go +++ b/service/discord/discord.go @@ -1,6 +1,8 @@ package discord import ( + "context" + "github.com/bwmarrin/discordgo" "github.com/pkg/errors" ) @@ -88,13 +90,18 @@ func (d *Discord) AddReceivers(channelIDs ...string) { } // Send takes a message subject and a message body and sends them to all previously set chats. -func (d Discord) Send(subject, message string) error { +func (d Discord) Send(ctx context.Context, subject, message string) error { fullMessage := subject + "\n" + message // Treating subject as message title for _, channelID := range d.channelIDs { - _, err := d.client.ChannelMessageSend(channelID, fullMessage) - if err != nil { - return errors.Wrapf(err, "failed to send message to Discord channel '%s'", channelID) + select { + case <-ctx.Done(): + return ctx.Err() + default: + _, err := d.client.ChannelMessageSend(channelID, fullMessage) + if err != nil { + return errors.Wrapf(err, "failed to send message to Discord channel '%s'", channelID) + } } } diff --git a/service/mail/mail.go b/service/mail/mail.go index 55901bb4..3ca0abf0 100644 --- a/service/mail/mail.go +++ b/service/mail/mail.go @@ -1,6 +1,7 @@ package mail import ( + "context" "net/smtp" "net/textproto" @@ -41,7 +42,7 @@ func (m *Mail) AddReceivers(addresses ...string) { // Send takes a message subject and a message body and sends them to all previously set chats. Message body supports // html as markup language. -func (m Mail) Send(subject, message string) error { +func (m Mail) Send(ctx context.Context, subject, message string) error { msg := &email.Email{ To: m.receiverAddresses, From: m.senderAddress, @@ -51,9 +52,15 @@ func (m Mail) Send(subject, message string) error { Headers: textproto.MIMEHeader{}, } - err := msg.Send(m.smtpHostAddr, m.smtpAuth) - if err != nil { - err = errors.Wrap(err, "failed to send mail") + var err error + select { + case <-ctx.Done(): + err = ctx.Err() + default: + err = msg.Send(m.smtpHostAddr, m.smtpAuth) + if err != nil { + err = errors.Wrap(err, "failed to send mail") + } } return err diff --git a/service/mailgun/mailgun.go b/service/mailgun/mailgun.go index b021f0d9..87882490 100644 --- a/service/mailgun/mailgun.go +++ b/service/mailgun/mailgun.go @@ -39,10 +39,10 @@ func (m *Mailgun) AddReceivers(addresses ...string) { // Send takes a message subject and a message body and sends them to all previously set chats. Message body supports // html as markup language. -func (m Mailgun) Send(subject, message string) error { +func (m Mailgun) Send(ctx context.Context, subject, message string) error { mailMessage := m.client.NewMessage(m.senderAddress, subject, message, m.receiverAddresses...) - _, _, err := m.client.Send(context.Background(), mailMessage) + _, _, err := m.client.Send(ctx, mailMessage) if err != nil { return errors.Wrap(err, "failed to send mail using Mailgun service") } diff --git a/service/msteams/ms_teams.go b/service/msteams/ms_teams.go index 7e484767..dca565ae 100644 --- a/service/msteams/ms_teams.go +++ b/service/msteams/ms_teams.go @@ -1,6 +1,8 @@ package msteams import ( + "context" + goteamsnotify "github.com/atc0005/go-teams-notify/v2" "github.com/pkg/errors" ) @@ -43,15 +45,20 @@ func (m *MSTeams) AddReceivers(webHooks ...string) { // html as markup language. // For more information about telegram api token: // -> https://github.com/atc0005/go-teams-notify#example-basic -func (m MSTeams) Send(subject, message string) error { +func (m MSTeams) Send(ctx context.Context, subject, message string) error { msgCard := goteamsnotify.NewMessageCard() msgCard.Title = subject msgCard.Text = message for _, webHook := range m.webHooks { - err := m.client.Send(webHook, msgCard) - if err != nil { - return errors.Wrapf(err, "failed to send message to Microsoft Teams via webhook '%s'", webHook) + select { + case <-ctx.Done(): + return ctx.Err() + default: + err := m.client.SendWithContext(ctx, webHook, msgCard) + if err != nil { + return errors.Wrapf(err, "failed to send message to Microsoft Teams via webhook '%s'", webHook) + } } } diff --git a/service/plivo/README.md b/service/plivo/README.md index 9b002440..c0020865 100644 --- a/service/plivo/README.md +++ b/service/plivo/README.md @@ -16,34 +16,35 @@ following things: package main import ( - "log" + "context" + "log" - "github.com/nikoksr/notify" - "github.com/nikoksr/notify/service/plivo" + "github.com/nikoksr/notify" + "github.com/nikoksr/notify/service/plivo" ) func main() { - plivoSvc, err := plivo.New( - &plivo.ClientOptions{ - AuthID: "", - AuthToken: "", - }, &plivo.MessageOptions{ - Source: "", - }) - if err != nil { - log.Fatalf("plivo.New() failed: %s", err.Error()) - } - - plivoSvc.AddReceivers("Destination1") - - notifier := notify.New() - notifier.UseServices(plivoSvc) - - err = notifier.Send("subject", "message") - if err != nil { - log.Fatalf("notifier.Send() failed: %s", err.Error()) - } - - log.Printf("notification sent") + plivoSvc, err := plivo.New( + &plivo.ClientOptions{ + AuthID: "", + AuthToken: "", + }, &plivo.MessageOptions{ + Source: "", + }) + if err != nil { + log.Fatalf("plivo.New() failed: %s", err.Error()) + } + + plivoSvc.AddReceivers("Destination1") + + notifier := notify.New() + notifier.UseServices(plivoSvc) + + err = notifier.Send(context.Background(), "subject", "message") + if err != nil { + log.Fatalf("notifier.Send() failed: %s", err.Error()) + } + + log.Printf("notification sent") } ``` diff --git a/service/plivo/doc.go b/service/plivo/doc.go index 7009d40e..3729436d 100644 --- a/service/plivo/doc.go +++ b/service/plivo/doc.go @@ -29,7 +29,7 @@ Usage: notifier := notify.New() notifier.UseServices(plivoSvc) - err = notifier.Send("subject", "message") + err = notifier.Send(context.Background(), "subject", "message") if err != nil { log.Fatalf("notifier.Send() failed: %s", err.Error()) } diff --git a/service/plivo/mock_plivoMsgClient.go b/service/plivo/mock_plivoMsgClient.go index c0ec80b2..796607b6 100644 --- a/service/plivo/mock_plivoMsgClient.go +++ b/service/plivo/mock_plivoMsgClient.go @@ -1,4 +1,4 @@ -// Code generated by mockery v0.0.0-dev. DO NOT EDIT. +// Code generated by mockery v2.5.1. DO NOT EDIT. package plivo @@ -7,7 +7,7 @@ import ( mock "github.com/stretchr/testify/mock" ) -// mockPlivoMsgClient is an autogenerated mock type for the plivoMsgClient type +// mockPlivoMsgClient is an autogenerated mock type for the mockPlivoMsgClient type type mockPlivoMsgClient struct { mock.Mock } diff --git a/service/plivo/plivo.go b/service/plivo/plivo.go index 2eccf108..3c516ad5 100644 --- a/service/plivo/plivo.go +++ b/service/plivo/plivo.go @@ -1,6 +1,7 @@ package plivo import ( + "context" "fmt" "net/http" "strings" @@ -75,7 +76,7 @@ func (s *Service) AddReceivers(phoneNumbers ...string) { } // Send sends a SMS via Plivo to all previously added receivers. -func (s *Service) Send(subject, message string) error { +func (s *Service) Send(ctx context.Context, subject, message string) error { text := subject + "\n" + message var dst string @@ -90,13 +91,19 @@ func (s *Service) Send(subject, message string) error { dst = strings.Join(s.destinations, "<") } - _, err := s.client.Create(plivo.MessageCreateParams{ - Dst: dst, - Text: text, - Src: s.mopts.Source, - URL: s.mopts.CallbackURL, - Method: s.mopts.CallbackMethod, - }) + var err error + select { + case <-ctx.Done(): + return ctx.Err() + default: + _, err = s.client.Create(plivo.MessageCreateParams{ + Dst: dst, + Text: text, + Src: s.mopts.Source, + URL: s.mopts.CallbackURL, + Method: s.mopts.CallbackMethod, + }) + } return err } diff --git a/service/plivo/plivo_test.go b/service/plivo/plivo_test.go index 6f7893a7..5dad6e8b 100644 --- a/service/plivo/plivo_test.go +++ b/service/plivo/plivo_test.go @@ -1,6 +1,7 @@ package plivo import ( + "context" "errors" "testing" @@ -53,7 +54,8 @@ func TestSend(t *testing.T) { assert.NotNil(svc) // no receivers added - err = svc.Send("message", "test") + ctx := context.Background() + err = svc.Send(ctx, "message", "test") assert.NotNil(err) // test plivo client returning error @@ -62,7 +64,7 @@ func TestSend(t *testing.T) { Return(nil, errors.New("some error")) svc.client = mockClient svc.AddReceivers("67890") - err = svc.Send("message", "test") + err = svc.Send(ctx, "message", "test") assert.NotNil(err) mockClient.AssertExpectations(t) @@ -72,7 +74,7 @@ func TestSend(t *testing.T) { Return(nil, nil) svc.client = mockClient svc.AddReceivers("09876") - err = svc.Send("message", "test") + err = svc.Send(ctx, "message", "test") assert.Nil(err) mockClient.AssertExpectations(t) } diff --git a/service/pushbullet/pushbullet.go b/service/pushbullet/pushbullet.go index e4c3a18e..792e634b 100644 --- a/service/pushbullet/pushbullet.go +++ b/service/pushbullet/pushbullet.go @@ -1,6 +1,8 @@ package pushbullet import ( + "context" + "github.com/cschomburg/go-pushbullet" "github.com/pkg/errors" ) @@ -35,16 +37,21 @@ func (pb *Pushbullet) AddReceivers(deviceNicknames ...string) { // you will need Pushbullet installed on the relevant devices // (android, chrome, firefox, windows) // see https://www.pushbullet.com/apps -func (pb Pushbullet) Send(subject, message string) error { +func (pb Pushbullet) Send(ctx context.Context, subject, message string) error { for _, deviceNickname := range pb.deviceNicknames { - dev, err := pb.client.Device(deviceNickname) - if err != nil { - return errors.Wrapf(err, "failed to find Pushbullet device with nickname '%s'", deviceNickname) - } - - err = dev.PushNote(subject, message) - if err != nil { - return errors.Wrapf(err, "failed to send message to Pushbullet device with nickname '%s'", deviceNickname) + select { + case <-ctx.Done(): + return ctx.Err() + default: + dev, err := pb.client.Device(deviceNickname) + if err != nil { + return errors.Wrapf(err, "failed to find Pushbullet device with nickname '%s'", deviceNickname) + } + + err = dev.PushNote(subject, message) + if err != nil { + return errors.Wrapf(err, "failed to send message to Pushbullet device with nickname '%s'", deviceNickname) + } } } diff --git a/service/pushbullet/sms.go b/service/pushbullet/sms.go index 75087601..a2c86159 100644 --- a/service/pushbullet/sms.go +++ b/service/pushbullet/sms.go @@ -1,6 +1,8 @@ package pushbullet import ( + "context" + "github.com/cschomburg/go-pushbullet" "github.com/pkg/errors" ) @@ -43,7 +45,7 @@ func (sms *SMS) AddReceivers(phoneNumbers ...string) { // Send takes a message subject and a message body and sends them to all phone numbers. // see https://help.pushbullet.com/articles/how-do-i-send-text-messages-from-my-computer/ -func (sms SMS) Send(subject, message string) error { +func (sms SMS) Send(ctx context.Context, subject, message string) error { fullMessage := subject + "\n" + message // Treating subject as message title user, err := sms.client.Me() if err != nil { @@ -51,9 +53,14 @@ func (sms SMS) Send(subject, message string) error { } for _, phoneNumber := range sms.phoneNumbers { - err = sms.client.PushSMS(user.Iden, sms.deviceIdentifier, phoneNumber, fullMessage) - if err != nil { - return errors.Wrapf(err, "failed to send SMS message to %s via Pushbullet", phoneNumber) + select { + case <-ctx.Done(): + return ctx.Err() + default: + err = sms.client.PushSMS(user.Iden, sms.deviceIdentifier, phoneNumber, fullMessage) + if err != nil { + return errors.Wrapf(err, "failed to send SMS message to %s via Pushbullet", phoneNumber) + } } } diff --git a/service/sendgrid/sendgrid.go b/service/sendgrid/sendgrid.go index 6b361edb..11df3314 100644 --- a/service/sendgrid/sendgrid.go +++ b/service/sendgrid/sendgrid.go @@ -1,6 +1,7 @@ package sendgrid import ( + "context" "net/http" "github.com/pkg/errors" @@ -36,7 +37,7 @@ func (s *SendGrid) AddReceivers(addresses ...string) { // Send takes a message subject and a message body and sends them to all previously set chats. Message body supports // html as markup language. -func (s SendGrid) Send(subject, message string) error { +func (s SendGrid) Send(ctx context.Context, subject, message string) error { from := mail.NewEmail(s.senderName, s.senderAddress) content := mail.NewContent("text/html", message) @@ -53,13 +54,18 @@ func (s SendGrid) Send(subject, message string) error { mailMessage.AddContent(content) mailMessage.SetFrom(from) - resp, err := s.client.Send(mailMessage) - if err != nil { - return errors.Wrap(err, "failed to send mail using SendGrid service") - } + select { + case <-ctx.Done(): + return ctx.Err() + default: + resp, err := s.client.Send(mailMessage) + if err != nil { + return errors.Wrap(err, "failed to send mail using SendGrid service") + } - if resp.StatusCode != http.StatusAccepted { - return errors.New("the SendGrid endpoint did not accept the message") + if resp.StatusCode != http.StatusAccepted { + return errors.New("the SendGrid endpoint did not accept the message") + } } return nil diff --git a/service/slack/slack.go b/service/slack/slack.go index 875de91a..62e90e52 100644 --- a/service/slack/slack.go +++ b/service/slack/slack.go @@ -1,6 +1,8 @@ package slack import ( + "context" + "github.com/pkg/errors" "github.com/slack-go/slack" ) @@ -34,16 +36,22 @@ func (s *Slack) AddReceivers(channelIDs ...string) { // Send takes a message subject and a message body and sends them to all previously set channels. // you will need a slack app with the chat:write.public and chat:write permissions. // see https://api.slack.com/ -func (s Slack) Send(subject, message string) error { +func (s Slack) Send(ctx context.Context, subject, message string) error { fullMessage := subject + "\n" + message // Treating subject as message title for _, channelID := range s.channelIDs { - id, timestamp, err := s.client.PostMessage( - channelID, - slack.MsgOptionText(fullMessage, false), - ) - if err != nil { - return errors.Wrapf(err, "failed to send message to Slack channel '%s' at time '%s'", id, timestamp) + select { + case <-ctx.Done(): + return ctx.Err() + default: + id, timestamp, err := s.client.PostMessageContext( + ctx, + channelID, + slack.MsgOptionText(fullMessage, false), + ) + if err != nil { + return errors.Wrapf(err, "failed to send message to Slack channel '%s' at time '%s'", id, timestamp) + } } } diff --git a/service/telegram/telegram.go b/service/telegram/telegram.go index 0fa44846..87941518 100644 --- a/service/telegram/telegram.go +++ b/service/telegram/telegram.go @@ -1,6 +1,8 @@ package telegram import ( + "context" + tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api" "github.com/pkg/errors" ) @@ -38,17 +40,22 @@ func (t *Telegram) AddReceivers(chatIDs ...int64) { // Send takes a message subject and a message body and sends them to all previously set chats. Message body supports // html as markup language. -func (t Telegram) Send(subject, message string) error { +func (t Telegram) Send(ctx context.Context, subject, message string) error { fullMessage := subject + "\n" + message // Treating subject as message title msg := tgbotapi.NewMessage(0, fullMessage) msg.ParseMode = defaultParseMode for _, chatID := range t.chatIDs { - msg.ChatID = chatID - _, err := t.client.Send(msg) - if err != nil { - return errors.Wrapf(err, "failed to send message to Telegram chat '%d'", chatID) + select { + case <-ctx.Done(): + return ctx.Err() + default: + msg.ChatID = chatID + _, err := t.client.Send(msg) + if err != nil { + return errors.Wrapf(err, "failed to send message to Telegram chat '%d'", chatID) + } } } diff --git a/service/twitter/twitter.go b/service/twitter/twitter.go index a4ea1456..90876989 100644 --- a/service/twitter/twitter.go +++ b/service/twitter/twitter.go @@ -1,6 +1,8 @@ package twitter import ( + "context" + "github.com/dghubble/go-twitter/twitter" "github.com/dghubble/oauth1" "github.com/pkg/errors" @@ -68,30 +70,35 @@ func (t *Twitter) AddReceivers(twitterIDs ...string) { // Send takes a message subject and a message body and sends them to all previously set twitterIDs as a DM. // See https://developer.twitter.com/en/docs/twitter-api/v1/direct-messages/sending-and-receiving/api-reference/new-event -func (t Twitter) Send(subject, message string) error { +func (t Twitter) Send(ctx context.Context, subject, message string) error { directMessageData := &twitter.DirectMessageData{ Text: subject + "\n" + message, } for _, twitterID := range t.twitterIDs { - directMessageTarget := &twitter.DirectMessageTarget{ - RecipientID: twitterID, - } - directMessageEvent := &twitter.DirectMessageEvent{ - Type: "message_create", - Message: &twitter.DirectMessageEventMessage{ - Target: directMessageTarget, - Data: directMessageData, - }, - } + select { + case <-ctx.Done(): + return ctx.Err() + default: + directMessageTarget := &twitter.DirectMessageTarget{ + RecipientID: twitterID, + } + directMessageEvent := &twitter.DirectMessageEvent{ + Type: "message_create", + Message: &twitter.DirectMessageEventMessage{ + Target: directMessageTarget, + Data: directMessageData, + }, + } - directMessageParams := &twitter.DirectMessageEventsNewParams{ - Event: directMessageEvent, - } + directMessageParams := &twitter.DirectMessageEventsNewParams{ + Event: directMessageEvent, + } - _, _, err := t.client.DirectMessages.EventsNew(directMessageParams) - if err != nil { - return errors.Wrapf(err, "failed to send direct message to twitter ID '%s'", twitterID) + _, _, err := t.client.DirectMessages.EventsNew(directMessageParams) + if err != nil { + return errors.Wrapf(err, "failed to send direct message to twitter ID '%s'", twitterID) + } } } diff --git a/service/whatsapp/README.md b/service/whatsapp/README.md index 2a05d387..5d3322db 100644 --- a/service/whatsapp/README.md +++ b/service/whatsapp/README.md @@ -46,7 +46,7 @@ func main() { notifier := notify.New() notifier.UseServices(whatsappSvc) - err = notifier.Send("subject", "message") + err = notifier.Send(context.Background(), "subject", "message") if err != nil { log.Fatalf("notifier.Send() failed: %s", err.Error()) } diff --git a/service/whatsapp/doc.go b/service/whatsapp/doc.go index 6ea71e79..26b069e6 100644 --- a/service/whatsapp/doc.go +++ b/service/whatsapp/doc.go @@ -28,7 +28,7 @@ Usage: notifier := notify.New() notifier.UseServices(whatsappSvc) - err = notifier.Send("subject", "message") + err = notifier.Send(context.Background(), "subject", "message") if err != nil { log.Fatalf("notifier.Send() failed: %s", err.Error()) } diff --git a/service/whatsapp/mock_whatsappClient.go b/service/whatsapp/mock_whatsappClient.go index 2eaec39b..434367f6 100644 --- a/service/whatsapp/mock_whatsappClient.go +++ b/service/whatsapp/mock_whatsappClient.go @@ -1,13 +1,13 @@ -// Code generated by mockery v2.0.4. DO NOT EDIT. +// Code generated by mockery v2.5.1. DO NOT EDIT. package whatsapp import ( - "github.com/Rhymen/go-whatsapp" - "github.com/stretchr/testify/mock" + whatsapp "github.com/Rhymen/go-whatsapp" + mock "github.com/stretchr/testify/mock" ) -// mockWhatsappClient is an autogenerated mock type for the whatsappClient type +// mockWhatsappClient is an autogenerated mock type for the mockWhatsappClient type type mockWhatsappClient struct { mock.Mock } diff --git a/service/whatsapp/whatsapp.go b/service/whatsapp/whatsapp.go index 56c52b82..ab7c03f2 100644 --- a/service/whatsapp/whatsapp.go +++ b/service/whatsapp/whatsapp.go @@ -1,6 +1,7 @@ package whatsapp import ( + "context" "encoding/gob" "fmt" "os" @@ -164,19 +165,24 @@ func (s *Service) AddReceivers(contacts ...string) { } // 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 { +func (s *Service) Send(ctx context.Context, subject, message string) error { msg := whatsapp.TextMessage{ Text: subject + "\n" + message, } for _, contact := range s.contacts { - msg.Info = whatsapp.MessageInfo{ - RemoteJid: contact + "@s.whatsapp.net", - } + select { + case <-ctx.Done(): + return ctx.Err() + default: + msg.Info = whatsapp.MessageInfo{ + RemoteJid: contact + "@s.whatsapp.net", + } - _, err := s.client.Send(msg) - if err != nil { - return errors.Wrapf(err, "failed to send message to WhatsApp contact '%s'", contact) + _, err := s.client.Send(msg) + if err != nil { + return errors.Wrapf(err, "failed to send message to WhatsApp contact '%s'", contact) + } } } diff --git a/service/whatsapp/whatsapp_test.go b/service/whatsapp/whatsapp_test.go index 514372b5..31240579 100644 --- a/service/whatsapp/whatsapp_test.go +++ b/service/whatsapp/whatsapp_test.go @@ -1,6 +1,7 @@ package whatsapp import ( + "context" "testing" "github.com/Rhymen/go-whatsapp" @@ -37,7 +38,8 @@ func TestSend(t *testing.T) { }).Return("", errors.New("some error")) svc.client = mockClient svc.AddReceivers("Contact1") - err := svc.Send("subject", "message") + ctx := context.Background() + err := svc.Send(ctx, "subject", "message") assert.NotNil(err) mockClient.AssertExpectations(t) @@ -57,7 +59,7 @@ func TestSend(t *testing.T) { }).Return("", nil) svc.client = mockClient svc.AddReceivers("Contact1", "Contact2") - err = svc.Send("subject", "message") + err = svc.Send(ctx, "subject", "message") assert.Nil(err) mockClient.AssertExpectations(t) }