From 09ee9c672e976dfc43fd8fd4de00971f446f471d Mon Sep 17 00:00:00 2001 From: George Tourkas Date: Sun, 21 Mar 2021 14:59:21 +0200 Subject: [PATCH 01/14] wechat initial impl --- README.md | 2 + go.mod | 1 + go.sum | 22 ++++ service/wechat/README.md | 83 ++++++++++++++ service/wechat/img/wechat_sandbox_1.png | Bin 0 -> 39402 bytes service/wechat/img/wechat_sandbox_2.png | Bin 0 -> 69835 bytes service/wechat/img/wechat_usage.png | Bin 0 -> 14915 bytes service/wechat/wechat.go | 141 ++++++++++++++++++++++++ 8 files changed, 249 insertions(+) create mode 100644 service/wechat/README.md create mode 100644 service/wechat/img/wechat_sandbox_1.png create mode 100644 service/wechat/img/wechat_sandbox_2.png create mode 100644 service/wechat/img/wechat_usage.png create mode 100644 service/wechat/wechat.go diff --git a/README.md b/README.md index eef9694..5ba979c 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,7 @@ _ = notifier.Send( - *Telegram* - *Twitter* - *WhatsApp* +- *WeChat* ## Credits @@ -96,6 +97,7 @@ _ = notifier.Send( - 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) +- WeChat: [silenceper/wechat](https://github.com/silenceper/wechat) ## Author diff --git a/go.mod b/go.mod index 31b15d4..f79ed14 100644 --- a/go.mod +++ b/go.mod @@ -30,6 +30,7 @@ require ( github.com/plivo/plivo-go v5.5.1+incompatible github.com/sendgrid/rest v2.6.3+incompatible // indirect github.com/sendgrid/sendgrid-go v3.8.0+incompatible + github.com/silenceper/wechat/v2 v2.0.5 github.com/sirupsen/logrus v1.8.1 // indirect github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect github.com/slack-go/slack v0.8.1 diff --git a/go.sum b/go.sum index 43ab37a..9dff5ac 100644 --- a/go.sum +++ b/go.sum @@ -33,6 +33,8 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.1.2 h1:7Kxqov7uQeP8WUEO0iHz3j9Bh0E1r github.com/aws/aws-sdk-go-v2/service/sts v1.1.2/go.mod h1:zu7rotIY9P4Aoc6ytqLP9jeYrECDHUODB5Gbp+BSHl8= github.com/aws/smithy-go v1.2.0 h1:0PoGBWXkXDIyVdPaZW9gMhaGzj3UOAgTdiVoHuuZAFA= github.com/aws/smithy-go v1.2.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= +github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b h1:L/QXpzIa3pOvUGt1D1lA5KjYhPBAN/3iWdP7xeFS9F0= +github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA= 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/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= @@ -62,6 +64,8 @@ github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojt github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870 h1:E2s37DuLxFhQDg5gKsWoLBOB0n+ZW8s599zru8FJ2/Y= github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= +github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= @@ -83,6 +87,8 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/gomodule/redigo v1.8.1 h1:Abmo0bI7Xf0IhdIPc7HZQzZcShdnmxeoVuDDtIQp8N8= +github.com/gomodule/redigo v1.8.1/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= 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= @@ -101,6 +107,8 @@ github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoA 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/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw= +github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= @@ -110,6 +118,7 @@ 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/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 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= @@ -130,6 +139,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ 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/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy/FJl/rCYT0+EuS8+Z0z4= +github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= 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/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= @@ -155,6 +166,9 @@ github.com/sendgrid/rest v2.6.3+incompatible h1:h/uruXAzKxVyDDIQX/MkQI73p/gsdpEn github.com/sendgrid/rest v2.6.3+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/silenceper/wechat/v2 v2.0.5 h1:yBOeTMiMAzCAvmhR14ADMlrRrR3oOqmoz7I/bus7bTw= +github.com/silenceper/wechat/v2 v2.0.5/go.mod h1:hksYXWXGl7/E6TQojFNgxv8ouTF9CPPjfvWWJouJJGs= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/skip2/go-qrcode v0.0.0-20190110000554-dc11ecdae0a9/go.mod h1:PLPIyL7ikehBD1OAjmKKiOEhbvWyHGaNDjquXMcYABo= @@ -164,11 +178,14 @@ github.com/slack-go/slack v0.8.1 h1:NqGXuzni8Is3EJWmsuMuBiCCPbWOlBgTKPvdlwS3Huk= github.com/slack-go/slack v0.8.1/go.mod h1:FGqNzJBmxIsZURAxh2a8D21AnOVvvXZvGligs4npPUM= github.com/sony/sonyflake v1.0.0 h1:MpU6Ro7tfXwgn2l5eluf9xQvQJDROTBImNCfRXn/YeM= github.com/sony/sonyflake v1.0.0/go.mod h1:Jv3cfhf/UFtolOTTRd3q4Nl6ENqM+KfyZ5PseKfZGF4= +github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= 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= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -177,6 +194,7 @@ github.com/technoweenie/multipartstreamer v1.0.1/go.mod h1:jNVxdtShOxzAsukZwTSw6 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-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b h1:wSOdpTq0/eI46Ez/LkDwIsAKA71YP2SRKBODiRWM0as= golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= @@ -207,6 +225,7 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h 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-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -255,8 +274,11 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 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/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/h2non/gock.v1 v1.0.15 h1:SzLqcIlb/fDfg7UvukMpNcWsu7sI5tWwL+KCATZqks0= +gopkg.in/h2non/gock.v1 v1.0.15/go.mod h1:sX4zAkdYX1TRGJ2JY156cFspQn4yRWn6p9EMdODlynE= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/service/wechat/README.md b/service/wechat/README.md new file mode 100644 index 0000000..9961f0d --- /dev/null +++ b/service/wechat/README.md @@ -0,0 +1,83 @@ +# WeChat + +## Prerequisites + +To use the service you need to apply for a [WeChat Official Account](https://mp.weixin.qq.com). +Application approval is a manual process and might take a while. In the meantime, you +can test your code using the [sandbox](https://developers.weixin.qq.com/sandbox). + +You need the following configuration information to sent out text messages with an Official Account: + +1. AppID +2. AppSecret +3. Token +4. EncodingAESKey +5. Verification URL + +The `AppID` and `AppSecret` are provided to you by WeChat. The `Token`, `EncodingAESKey` and +the Verifications URL, you set yourself and are needed by the authentication method. More on +this [here](https://developers.weixin.qq.com/doc/offiaccount/en/Basic_Information/Access_Overview.html). + +## Getting Started + +Until your application is approved, sign in to the sandbox to get an `AppID`, an `AppSecret` and +set the `Token` and the Verification URL. Typically, you need a service like [ngrok](https://ngrok.com/) +for the latter. You don't need to/cannot set the `EncodingAESKey`, because it's not required in the +sandbox environment: + +![wechat_sandbox_1.png](img/wechat_sandbox_1.png) + +You also need a user subscribed to your Official Account. You can use your own: + +![wechat_sandbox_2.png](img/wechat_sandbox_2.png) + +## Usage + + +```go +package main + +import ( + "log" + "context" + "fmt" + "net/http" + "github.com/nikoksr/notify" + "github.com/nikoksr/notify/service/wechat" +) + +func main() { + + wechatSvc := wechat.New(wechat.Config{ + AppID: "abcdefghi", + AppSecret: "jklmnopqr", + Token: "mytoken", + EncodingAESKey: "IGNORED-IN-SANDBOX", + }) + + // do this only once, or when settings are updated + devMode := true + wechatSvc.WaitForOneOffVerification(":7999", devMode, func(r *http.Request, verified bool) { + if !verified { + fmt.Println("unknown or failed verification call") + } else { + fmt.Println("verification call done") + } + }) + + wechatSvc.AddReceivers("some-user-openid") + + notifier := notify.New() + notifier.UseServices(wechatSvc) + + err := notifier.Send(context.Background(), "subject", "message") + if err != nil { + log.Fatalf("notifier.Send() failed: %s", err.Error()) + } + + log.Println("notification sent") +} +``` + +![wechat_usage.png](img/wechat_usage.png) + diff --git a/service/wechat/img/wechat_sandbox_1.png b/service/wechat/img/wechat_sandbox_1.png new file mode 100644 index 0000000000000000000000000000000000000000..b2b11fd61fb602d53ca2ee05902ce2e4c795aa8d GIT binary patch literal 39402 zcmd43bySq!|1U~+ib#i|fKoGbhX@D^prDlW5F%aDt$;LAL!-1JEm9KFFob}FQi61M zGk1@lkA8o@yVhCvth>%R_s$=)oQH|$+0WkZ_p7$A9;hpk644W3U|^6c-@m7cfq}z? zfq{u4zynA840HxCFaj`?@5w##Fj~*R9cTPD5pp}B`l*vUcqGqle!uFTd^d2eJxD$P zhkzoT;^tFU!fSz?QKnAh_X76(kGfI3d!)v9m9Zv#YPZ(BN~SWVn8aKx7aIl|mXIXM z_x^e0h9llc%KiJo{MlQ*>o@*+Jbr2UGVGtnBkEM@e~)TDeyaWN(fg0z{GWJpyLk$A zj$)L`XYV6*)Ww#6qNd92yaezhltCPWQEK9xVqO{a(*NL_&Ptj?T-x_EH&e=cG4a9QKi>7g^}vg7y_rUx>+W-TvLx0n|Ie3#ZzlRlJxd28OQrt% z?o_j(;=iAL^jNv_?%y{*zST$c`)trpj}ryC&}a7hz~jg7k}Yv#MC2A$EOr<&XHMH` zj34Fi_}xWaoUWB}4S4fh797vKvNqeh*zM)>clzEo^2uT5JZsnW&-Xpk*ZM5L1;O#! zUyhrBQ@m(-@Cdf`{iBW7;e?e|C>hf(3URqokfpt-mCiRKWHZVwb$L9$(kC(l%aCv{ zvC!Qn8Rs>u`?ca$q*b8qX3w?f0j_iypT*|^R8JRmjYmIM*zWs?b$A;J!g+eImOL}# zKI6NRsAHszjYrZoEX4QcTGZaZ)3L-2^eZ*`Jmhz_k*qF#@@oX#57!}Ojy$QONr8>V zvrX$5sl)sDjE=Ix4AQ5|Ir~GZe0h3S8A3wOMmX_LXz|{c)IAelN_TPA#tttgfCYZ| zG%fz2W-i=%uTMk+pV`C2BE?+4;b8QM^@oq6D!ts5Fn#ClTQ=53c}Xh0d`&)e%Woqp zUQw*|`ba!qM_ki0k8>S24b5u_#$Q_4X4?Diz4duGTQ2wxJ8|zTRC$TWjE_s*P6xxV z=Tb(pCBihM>hg4L$$HGt-7s^y#%Vq)G4Ai3+IZ(~iCd~;}xGf=UGsQV9)$1=UyJ`>Iq9#a_M6eVZu7MwItMDsLc6w1`Grff-sCb z((cog@Q3=%x|K}tO=X+X&(EJt)wu}^cA2nJ1$k~&|FHKwNj7}0H!6cV8L;(3^7nGD zEa$|OASlC*+^0RQgz2A8xs4TPJpX>XsUKW}r=P@nnf!Nf5qn&FEmh6i9?Ne+cTo^| zZ9R*`s>M{B{BJtOQXi^@RIC>gb=3V&dW|c7?le7r^>-n>Q#j};mc>~#=bZFf`>+zi zVBeKOhQPDR@_jChcTLwM&=oA5C7s4Bc(m9ZOWYf+b8``V{ULZMS0i}qp6c6{w^u+I zFZT;%@@^&R-r%X34f3Qz;3KGATbfzLQ0IFtqa9%AlV861+Tgh-2o4m0FUmL5zW0f$ zLJ&fu+ZiP?EoxWZeoc>-?T6hb!-c*4H2YL~!KV*a=61GQ$*n4bka7N~vze85?@Qi= z4IrRvA3kMTzWn#@6j`f-^JnGcV3-4+Q_1o@)XS7fp|(nQQWR$3ZP@-&HF%de&!(i7 zod>+AeUD>_J0+`2-VyDw(@x`(OeSp%X3b4sO49|1<0YnXN`sDzG|qV)5j zzOVpGso$3A% zW;2wlEUY=Mjto~~_PjYjm4mGn6d6O2wFGW@RSO=&Q*F+F7jf$1qf#VMojD{48!j75 zEw|kS7Dj=uwLdr?#fFeFFPhTlH1ZE!>u(LR9xTv~sRyKDt+r&h|;zfGa8VZxI`*D)h3@X00;^<3~IZ znazd2_=PWpIug}PC6Ov@ms-iVJl8^Xm)1LI9jERYWEvN)#9hB$aq{Z=&OJ(g=<=N} zKHYP=_O%PUqE~1sEp{a8veLa)i#)egJ9=3e=40i_x;yUoCh_darYSKx-Q$67OnYyA zASu&B7MrY-j5<{I3BLztB=O(R$V!_v=#*UM9Kt|GOJJ%!_#ub4G6>4mmB3mbSd2sR z@^ItF67)7i0)k5`8jmEp>};5~zAkCBKj|{ihwZ%kg2K-mtdzx*?fsayykOEc@R}WD5GxX#fqrV2+ zmJ7j_J4Y920d5Ed7%5fLOwYxl1Hst0dUA(gZb4*VF|~`STr!Obo$>vWd&rgArOaMK zIa+_L;lP=%w|*7oME9^01Us5JmXWksRj`6emzLhrvIV6Wzl3mg6^kCv2JdarT4B4q z+=4s-cV0G?ggN|c%OR*)h9}l+k{7`T*NM&Ff2i(RYvW%Yy?d?mheK1w*arjkKh5;f z$9K~y)U;%h7Quo1bQ(dM*IWl!*JeQ3M~Kj+&NGa@S>4&q|FW-SMt4x5rh^COT;!53l(sk%}U@4qQcC z_}$njO86tlA@(9p)(O+pox|@orII0SpysC?f+>IAG*{8>Gn;6!$E0z^8gzyJe$ln! zO7>^kWws>v9huo&gj2d*>9a-5#S%@O&9efAG7wG(m&eUJz1Lf@f-OPo>YE8Ia=JJe z8`IbL0}|e)J_ZE_hE=B+%j2|?mu#71mY-tTvxqAvosXkOC3y>HFUS^`S*M3h9(w0X z@i=Jll_|{_2r!%)bu0O4ntO|VTA%EvcG=WZIN(}>HlxM-%N7q^>rFBvnOYE6Bvleo zk_RJNiM({C+S@NEU@>MQ6#O@qJAxp5$9z+=<9PfE+E460N>1bb=;epNwGEuwZJ(B@ zA%hE2%j`*rdY-q%-}}#q>U`$sf?zD)kvk#_^5Un5@JNFbQ5ltQ4Iv!{@GXUufSFF^ zP>#gl6>VCOTX=zQETNn>7CZLD6~;4j`h97mxXinRgGy(p0VAnEi7zDIQ&j@-b17Ozu=+|fQvuBayu{I&iZd}(0unU zSMSZ=v3d9Uzr63A%6}?Q!n-^F;}2;*Mo{~n?*DD~2|cOrEEQsyr8Iw3+i9f<+x_|e z+j$k+MB60np~}Ksj>>4f7edZb^7pTaFLfZ___=hqyW-e-;}!lP1m@y+r6%uEso4}G zIW?|P{(i)*&^BQ85&iRmvWQ-g>kpH7H&{&Z?|a_et-Sm1;dey;dGnqBC2uynat!L{ zaE#0)VrH*r=>aUu==f(S%Mh5_BJI`Q>*M9tNCb4Do63B$#>u)l0Mk>79dE7EOMThB zoaLV@GhfZo+u=G{eP23+MkAU2mnY{ZuQ)RAgVLq1Z=IJ|p>5>3P&KSBk@v&Co(F&W zAmh`t7nfbr#i8|Jw%kG~`>VCmCTS-3NvDNwx1l`MlbEWLxwwNAW};zm2;R`I=tX z7QyU)zO&zqO`Z!nyV%7+slQq%v)5C4DNx$T4v1lC?bn`gTZzC3(M7y!>iLgEjIhJldS%8di#COu^QvqmQMQExQ10;!z`uq=%ysUmZ!qZV%T<^jYk6`8zX5 z>k|Tf0Q;|ik?+rP00UD6;KSG{>2?zuGznP`<&N%KC-OBO-;e@JT(6yI58%rDg`_9E zz9$RGD*zQ9>v`g3`Rpott(SKWfyIAPxp@tZ@4PlXj%lJUFNSex3}OYe!d;gKuYU$# zE*5{ogieXc?UBCChmV?LC5Bv<3Qc|&yMAy_^XjrD-RY$)|IEb<_v!tePL_iH42h+> zhv_T_Z*@wIWS)rpGc!*viU2EXS*_^hO%onB39jlFU&~dXF%+Bv5c{MafJ2TCWnYM_ zXMB(P0yja|&q~s>OtCeCQyO&56A2g{GL`B1_;tX0ylQQ4pM9F~lkksu6@b~| zKWgYcl}_jcuz{rj0etp+Z(v}iymZ+}{!=uXU7?a^egi6&9jSbRrp_1H=P5LF+@Xxl z_vwY6JrY(u?hEHCL5u=)P<1rzy;Q=o&JY;}#tyROp1*V9v)7k=Bx3UH>q{#Yi+`zm zSFRRcUpSaIJQ*HyuM*{0l(#qnEF2Y(;dGXW>r75 zqglN86|a%6a82)~mHR&z+%=MCluC{B4yQEt5!vz`(-a+s>ioy1P71Vn@C&0LuxTCCnC&M{4>NFYvm7JI~t%vyQ zS3QkGb12E}r?T3(7G1~8h`S^PdN{$s_H^dDCbn0_&bM2+COFNXnQ)dFi@U8R)bGW5 z%5~rvxPDcz21KWS%h+or4^5k_*luJ;5KUaARX62tZ!X*(lqa_kc)=^zmnzf?cle{a zzl zRRO}vDN@1Im0)6QTf2}nu{~}U!7~J;i!8w1V*R~;zNE?jQ2qT*QxlkUF7A~4>_Olk zd^{gVG$-!AIU`$p#ArfQY4++?QrE$sZjkF$2$=R>8!UTG$y`Ztw~NiwfG9|_E^zx1 z!R9Ew-H+$ULrOKdgR zzIf2sV8+=#uM}aa;5yGK?Ui6nd(~X~h29P*W!jBn|2DBAb%3i|GWJp|Q*V=36X4WN z#x3zm1xr;w`*tU$+;PGpd0~rADG(#2h3!PTqqqiezuhB}$@|Y0U3Cg=0@ScvDhRqt zShG2(f^DN81G=6{?gw=T)29dHN0&*mD>i24oSdhj=R)F%fQ84P9R31-j_p?6T8V+Q zc`1el_Rk|^@>bW=779#~n{^4GL^7WU1lyD}o~~LSZ~r_IP^5&%O!}iPPF%hgXY)e& zI%+X0Zja-`;2A>ycI12}a0NRXpJoGJC2zg8fsU>F8JOSr}vXOLJ6 z)4ACLu5aXL@x{>vS$^XF`9^UcTjJ$cgXE#@Q_4{}3AMm3;11p;>hj#+lvE4>q7vLe{_x;5t ziz|&a=$XuX^8Wyke5rhi|9~`x|J5Mv{|WwqLeLI?geGX<=wAO<)jeQ{piS5HQPJE& zhC9u7garLRrGz(iA)xRfpjbTc1dVGZ*>8tR z=JFW6`s0(sWgp*#_CKSZ%PYv0{}7Pa`h8H0a<9vWBs8VIjieX4V+YvS3IL1!S?)k4 z8_89UA1dt_2GVU60DHNlB9jnbAk+$Q@||cHF8RZR)i&I2(}|gXd$dpC%@v+fVW6BnKyBz zSPM)6=ah!i)%S_^G~5xzc=-x?rZ{CrE=Z^nnxPH>8B{A}AR*-77$BozptbBSp+!$2 zfJkrSk)1JMm&4biD#F8L2NboOP&s z62)a}{eVm-7V*NO!rr{30rWl3x_<`nym3Uea_%LK(S23kTJz1uvagB^c`vW&bE1{w z6A3JX&11BLVg31FRP}vvg^Iq8RQzC0ak%5No;;AY_D`cS3WUOW!Kv)VtZe@0jab0H$p%93Z_*WfQluq z0K5H~dChZog2`hx&@=6}K+m1(csFr?f%Y7#C!Ko@rV|Wl?;zN@$#+m-j6^p+A5EY5 z2h@J4D`y50uH|>9PNw0v5xl9SY@=x>{N$rMz(wdo{YxrmV!W)iP41;X|8AW)FlOMQ zCQMtyfZD9z%Kwd80T(+VlNSFKEAK2DIUzgPcZ3$&`x{w@&Cr5WpfHMq)AF(f*f8nA z&uaGiB`SAX#z|$jRb$nf`!jrltU7#H3m5kYInrZ;{io54Mr_c3vvz5hzxxquK;wM0 z#I7@870{<BEDo3pA_1I0`z0r8_~quc2#OfV-TRlwQ#9WHZNo%xSKLQ?5PPnp zKf%4xNVBa_=2fbYAvkR<{w?bT-kW$(a<rv;Rl$`oKgoOAG$w_Wk{WbxUS zo5rWT5{yUM<9729Ggd7KGtdd!+~&b1jgg1xr4IlNc}?dFd=oG_iRZTc3C$!w{S$=n z@b)Zc;O8c=vW5ZaGj1z$B#@g=L}(v1DO~)+{Ni2#_)k=)MX^m~>n!32uC&*EhAOtuaTLIs`Nr@$Jx zMiPdc=oBkLW(Flq@M~wJtVUN2x7ld5_2-v#~FkN9x_T(lH@3K6?wWn3*fpb}1G~%4jf>1!V%DJIg@PJnrgs;y_H{K~bF$UbOXJUYMa?N0#z1&J+Ib+Z& zAPBiS!AX0iSmKQHDNx@^sMh(AL_I=ySE+x`ueg~kFuh`NWyeT^ei}ZXxMc^{sMrQe zWsp6qE3qjo0wX>MBXNhYtC+Qmw}b`{f2Ok095)>>#@aK2d|b@ky#bjlQvCd{cEJl@ zr7*FBVAvIs5NZfLLDE{#Ocq!zi32!$IP1vZEeb`93A$nlxKx?C!{-BSQ(mpiIwVmf zQ(f0!R1h*Wz@D*~C83Y#(*4_GoyUHvG!%6&a3ZY+kTC1zJ|@Sc;vAktM%0cE22;DS<#F^)`Xf3ShY5=;;M;1YgCMQ9~fC04M?zgULspuaeqxCJKAm(b~q zf#ri&cym4wBUNHCQlt5p$d#_SnKkT|V~1cElxukr6MlbYg4@w!!cCmi7taq7L6Fm7nERI5UF-mZ$F4TwiE0&&LEmUvpp z5?7C@>6RNX5FTRYKOA*v*ipPZf09N`(nffmydLgBM3lmQp1Dr+TQ+a_Li^>>+hPwa z;l1s*T1_K1ac z+psLbAze)Hftifi==rE6E*_O0A41r?zKnd_pX41KJk$iJ);*C2Errdo;ho85kT~iu z=d`N9k&$9c>BGo>fgJ9R{QW8xKR{wFg?{iDy@HK8l%r z6Uy9!hl_2?FKRWMuV&*$h`HH3158CRcu;d40UZ?}LaVE9>rqEI zgKul&G)a+3aQ72!PmG1xBNGptofiqTvGFriPru%nav6}C(B+h-d|8km%hTcqK#Y=0 zlA4oIbA>022absK43zr@$|4ZBZC7Le>G&`vz{sIc{c773{0?riGTj#?SmsyS3{O{> z>TYf{{NR^`JbW?{|?CiUy?Wf`_8%jDwGS%0i{30 zPDO1gRTGw^2L+IRe+G3a;!2sP z8?cYRp2}_DYW$g4Uu1yD2H=Ln-ybdFZorZZ?w0%OgePcf!Tu+0m;dh79E=tp1CD@Z zGMZV^zR%RQ0PE8}If~EOWz)XPU0-62>hOT4(;@u z9d2lWXuz&b*Z@fWr~~!1I8Qx8e8H-HcLp7NvOX8SG#>LF`S9eE{@SZRC(u=M0YT(( zV9C1O3ycNM&wzYQlyR2W?D*4OwUt&xR#nS68>1FfbP0qtl4!WzcmVdY!rzLjarakH^Am$lFz z1T%)wR0TK=nS#Ld9rco0&JG?zOTCMLRh;+iqa!1}0RD;X%>(I9<+mvV5Z|z-Do^54 zB@iO>@{*0}cBS)YJm#aQsW4sUTFGT#0Crf3Z#QG_HR!rWrU1$97TT}z^oGdmYBbLK z)6$|1W^ur1hi@08zaDc4p|iY??uX*Q-qZphdzY*CPIA#7}|w zylLLjBg^jqSDD`aoXPL_XW~FHpP`f)33=Ts6KzK4uInp+0wLF~&IznF{`YjwGjy%&2YV3Ucm zGI=e(L8rC)ExU}oHxirR;xq8ORlt@&H~I@e0FirE-$D9k*Xy@b0CIJOxANoipdQ<^ z2GYfyV5+C1RPhM#dU@;DH7T=hvmvSe69>^!Mf=#a*IGl#2jF}Z9`Oo+$^n7fOEM@i z_o8eG0!;4)t4KU#7=$a_kT=|{n4lviTjKuLVpaxBcmVe+uwFJSQ$S$fqee^a6P`KyVb7zXSF zfbo@m&`*1X#=ucdn1*05rNaaP5?yAQii$1%mwQ=^T^jH7T3C}{a3hk!Zj(%NX9JK) zncUN)4%!9VUk6TteSZx)8?vha8Trtlv@RqgRNuF9ZU6k1s{ zl%p`%QLUH>(_Ja7Di7{anVtb3R5|4d^$=5^?>9a?2-p% z)fl%z5hHC8NtD^q;x+VPJVICA4R}NIXMSE^Zx)+<*5fZd)3mZCrT8bYz`t$-A_X5_5I*d(NVf=Ii z+beUj)$(XHM7jA0K?b^3e~XL;HeqE@ft3l_z2|aaGms`gn3+TCKz=gUBH2)w{B5^v zTAbe3V!g@+*rL-{1)7CT4&?i%+S{BDE0`b@cS*duYv>g!gFGKtf-qU)3p*4grU*eUHqsyhonIp+YxnR`)sgRFAg`{Ya zoWSGAaMcv1?s{QDKXs?;T{8?Fu5mfUHRL5YYz-p-mz8NfRqtMUi~lOYs^>53uf-r! zL*9bwGS7a33s<=ZDi4jheVL!RN14y1YCg81I3Ve^*=L==K#!x2p|+4lP@hXzm-1Gc zyGVZq;0 z_fH7%^fNjmgyl(sTW2=-5=$$Pn>gPcnCcg6#;Bet0fKSL;0Hqr!Kk(z)ow*r>|l;p zu_+I)?X?9olK{=db-tOR#oQ$F)iT}}XS4&C9w!%qJ4}~`m4n5G!4}+^X%AE%u^-qu zY;B@f5FEC|6W67@4~vJ3O*|3g2zu9Ba*;A}V^{I^&ClwdZ=|C2OUaNt6_WVT3NxE&faW8N(pInw-_pLM2473&kWj?KYW} zU|#CZPR3b;!3UN3$w7{eF}^qmLLB}DhczOwgboGp2*|Xi5a6K9?Xzjg=RwQu(-@nL zD?%ohTt`sTVw-~{hn*8VW5&Im!r{c4iSvc+-U;7chbu@Xb5(T9r9heSW0V)VInc@G zOnka4XwkMmU)Sy1W0ymMVTc$l!Ub*PYEZQxS`a4FKvs0)UXY-->}D;XbwSZ=o3}4h?_k6Rb8n0 zojl2+VC#lyAgX$1BP+&}KxlLk)#*PGQaK0>(2pnrh2?xC#e!j26}SYAgl+Tg zI2+LITUl)Pvvh^!3Ax?)G(pS zw;+631h7{Tum%29sRT{EzZ(W>Zpw#{D8oA<|4ZZwY&Ce6Le1^*t1E7y`!B5x)`0*j zOv$F0z!CAUz2Zt@6!@QQ6{PHrqcm5gbqyh#B=$8 zUW4|37P?n}e5uOwq?%i!ANU01*8j%0nhJs8^6hjBZ6-~Fg|9yxaNx1^`KTwJBZbBP zyu2d1A>2y`6OuivvxXXGu`&*9ZOdJ3E&^{AeUq*3@Fb9l45%{{q+kM z%_wvdrI&lwedNogn@s0K=~ap?$Y&mt&Fy>2NoG)Rd?t0p14?}GmM(V!}o z@2~A7lt!!%Ki~Mia6tMr$B~z})ic1$(AKKVAo|StM^5US$?!Wy62HShqZ1wT^E}sD;4E~cX@1rN0QDAJ-BbwbCFrWCucSk>m5e%vLS|9uvpojrI?XSUPI zJfFX`ugdnp_LkO?-^Uo^{Er&~KNq6ji(Nz&P0YUSNRrOkQZ49q=)6QM^`d@OHo}KR zTK$c9n;x|*enT!r4cPRzHf>A9t)!qWr~8b+&RPLE-rg+hu5$pTl}QvM)fgcf8Xz}!)n85Q%yz$?1mu)9w;ih+4c8^ z879{U;`@X0l^({Uz`}?}N7eOd&>IPOHSp=F1qTU8^rq24Ck7K(j;W??@%fN~=+&|) zbW-O#m|7KwGybUap1KOD24+BX^Z+Yzs5{^71 z%=#%zQweLe^H#Ef=COj^Qw-pZWr}s(b_Pqi0Q_$0Xw?nCqE$4cPt2zqfi)(8-j?!v zSBLEnwiroGC;?V&PVJ^i2=$t4ZJ=^% z#sLTi5AWI-ii0Y!2Q?`d)J_YQ}H1sGLXw28-*%qPJ1*YL&$|no?I9JKtUJXzY z)%lUGXQ9&{O-s6F7oue74J|&*zeIn!0JZ1N;y0jv=!&hNKu@X)Wml+$#GiaiOP!tQpQdw?E!93;ON>ruoQ%d_AnOAy4;EJ|K+xHuA=8uTyX(XZK}R!hkX`W(n=VLy8siO2xz75 zVXVnq7yYE<9kfQh)^!pm-g5F2K(-GD-aShVd;O|trDVZN1N;`GG+_7VI8SR`nQ_FA z=GvDVcdGHRRt49txFvcS6n~-;FcT%4Kxxq*j)8DzLNv%97&H~-wA+v^E&!uCW#DMR z26Ihy!jT6T$sZjf8jY~>Sxi3#>c!|Os`MrQ?4%2rFAD?QF)n>zp2q!n0N9v%9Z0V_ zU;O&0>(5z_R$M+|2aJJ<&Ht(3ZZXGLsVK)o;qwp|4`i@c%WetSXi)_Oi(hVU?0P+= zN=#Y&pzIf)C$d#o{V$%h4j1@#Hu=A6{j?IU)4A385bg&{ZsM=f9*p|BqkptDrzGRXO}YE{$wA|R+kQPAD2Q`60AD-Sg>C#xV?KAAET5npGtznBg~TcRy@4y zB(tG3OqvFS~_wd%O`|xes_9h9-1)N^5Qi|{SrEtd18^iXn>x&|R^?E|v!Y)@uK=1=1 zu%g7(zYES<9}mjbf*i5Syhza9e44FsWABZRiFi0sR=i&6=hkiLko1XE)5%!VsV97uEfhpUFD*!*r;{W{p+M0uSe-TV2Cc76f#{s4H`b-E=o`6*F5ZmHQd)jUR%v#VEs8ygwjb{>+1vUrnE@C0;hA?UXsonLy zNB7k+bLatwy7)?Nk5!U#tM%Q%W-9k?wiyuyvv$4)R!nu-2#`&EoJ3il6` za?b=KYgN0w9M>syhnH_b-ewN#E=;z%kLdNhB_SOn6&`05sTM2UW?1F#oJ4DZz1al4 z1?i$4x-mduJq^QO1qu(A$T`T~dr)EV|d^nM2LbkXkZ~ zh5FTZ?-zX;_5Cjn_N09PSpv0s{KI=cjNV_2w4H);v`a?@RN5j*(6Vf?U=d+fS;q4t|cC%2bk+%#4hQ4utM> zUe1b!2OuimWa6)5mt^6jD%AA580J)^u)W&pcCwC%jnq7jF!%Ae=NJmXhJy%EM>$Z2u8+eW3VQw{WRY3a|;5e zC)jz`pv9?Kny1zCmCNlVVi%~>J$yljUTWSx`)|u)Q8#hp*81$9ZWpN1H^NzGsLNUTB3NDpLxBthGTSV zBv#OF^0S~rd1j{AzQ8dV6mQ1Pd93X{$-R|NEAPfaEwE=VtJ#J!wxYU1DgnDLT0*7XUp$?@~G`_(EyoxfsBX|f>Y@mw@sa9ujQwGORbu)nvBF4Z)f6o*VOfq?xf>!3$Y3!{5Z zK)vEuf}bS>d)x)PP=DULf*#gkLlkcV@3DcM6{9_i_)%Aa6tS9XM8A66yw4@9a?G^m z4EVwlF@$Ei0-?_K(L*VygN{Zhh>QL)Evo@VuXQO7=XpNCf>H`)Ld6HcFS__axIy&! zRLx0zmkIbZ4|(TsunpQMqsZxNcT((b957M?mU=^~`8qs+U{%oE@L{(%iGm zxQ19)P_BkcQJ$WY~`rEfWlANG#yccb}Kp$zSP99u>j9~rT-4}yiaz574nG{NQ#0*mCQu2U>F z^p@+w0v9FKWHE}_mg;srli~EO;Rkp2 z?Y!yOh~5*#MWYELIOGew7RYbb$!aE1EH)bd9cK( zI+|$1vbSWQY-r{$Kw24Y%_xI&O#95Bl8yMKZ1jwibu(l|Q_^Ih^!AJ&uU-(mE3%3PwS7{d>GxY+vK z#c#H*|GBete#y4V#Dg(Hvj{ybMydpPM&e?QwE?cZTuBcW_XRN{F?B>V^xh#S_?Y)0 z%W#enmFzH?X}xIZ1N@q4XZtU@mcCE}&i8~C$(Wrt7yA>0xdL3SjfrJvc6f%sGlg*- zN!u~Ft?DsC9-VX$I+8`9G?Z(EA8bt+7qfNJbkZ$RMaxG&?BU8TaUsE8!j7Kjv^jJ) z=K%11I>HjSOfp*Jkh+6ZhNLCP2gZll&r5u~JrkvpoPzUku$$kn!H3&#rajqYjpj?N4wC**8 zj&et=W5aMgau%DGJ`3LTHC{%^9uWtfgi15&RhHyvtxe15q|q}S{c0Y0YqKGYp~pfa z%=pdSMRD!ZgQPZvf67?p)GlYV1S-ee?+iWsDs}#8rKyW;f(!#jg+LphF(yT zljeWiHn*Fces)iM>E(6LGl=@~rn8zF-Rs1m%Qa{%Nf5paZHn}%Gt7vOU;NmAxt`wi z#pHSav2Elb#>v362>~vfy0^zb-lb zZSJ&#Us7vr?V%z1I8g4;4r}Ps5@PzBK>x>+`XL`2d64_Fx1x1}yvGvPJ!IU7-Z~6P zO#fBT$Ae|%*A6|LZ?Mn+_?~y%VYfBtiFbZbkT&d!60CFaQ*nAnzIa=MP)bg?jTyy% zNExM%#lC4&!S{5TlGRBk{8av=-O$wp#q)W8NbD&-Jw%^N$W~pV3Bff_&`+b%&4~&mVF=e9k4hf^Af(RCs=mrtd z`eD3{BrDA^<%(HPRSZlG5CSkwD>-H)0=FkwsZT8ry!$wa9T zSK+WlWsq##ZW~FqlMZv5i?Q(@9~WAfIsJY)dsbSa=g-wkG?! zA0x!ck}mraM$ivuouU9Q<ZyY`j7GQ+ z?!D=!_~m$%=t705J7P8K-Y(%>EO3ws&Qy$-Fk}Knn>pE?!6=HaRXswrx#(Q{)uU7P zi|DV0Ug@{CqE^%cRwEA8$$LamuB*=JF7pklzH=g!gN|eild$bpzXHj^qxAV>sWZ_- ziIzKS9a{u9i)a?$R|+zn_D4*HrsnfC`gIlhafVuXDzoRO<)`9(D#gt$`HME!>_$yKQE5Gn z=$YlYKuFN-GiMs|lAZPU6?#3-Au_8fJLg{n53Lc@#pD*uQ}93=vbAQAA!uJ?O^|C3Xi&xXb>eBR|(DQ zEBek0EGe&ES%O9jML!(nu@7>}Se#@m`@s04N!4C}#?S z8OZO)_z3b_-Mo6>5p{WRT9yu_FcF2YnKrGgF8!Y|VsJXtPIth*Hajj>31O$?T6xy;vQYlReDSV#JDhh*LC`LZgTL~2e|aulkE%rw@L-MtzS?XIDd_B zJptbR#qe5CcFA}R2L}7cWQ)U@_P?@nbiKNui*{q(qUE3mFj45FDYrc*HkeN@O-Ozf^p_?+PR#3Jols8?S@ zxSN?Kr=|7-cWY#&S~_+S7h~`U;k^f%{pXli*H>{5GEJ&Hrg>)c%sox(FxW{f+Qb^u z6YuI(%y6_9b3V@@9+x@it-A#S|2c|O_l>!9Sax4|->K84<>iP@K4qEHCHwI!FZtLu z>G|Uh^9B8`YRAak%!6#^I6@s^u0pPJk&<3hZ5WdAm(M+>#dP`4*(I8&Zb6KmAb1!& zVNZ<&uh;vK+)V&Uv`V$a*58ys+Ih3-b{h4F`=Lk(=>tW?xhZ6ug`eO?#I5{21`?N5 z;W6=^XdOR|jCsixPoY(znfN?eih->F{@<0%rGF`1m!wAQa6&s;3C0nm4#=VG!vqBc zS(P!TM1K^N6FO7rK)J-xFR>$bNPHIIa(~ieRv)=DaPZm3E^q3Aur~&F=tiWQ=>%=I zt<2J$XlRA_4F(P*kx9LncHuB%tF6QmWshJ7uc?1W6iI&?44zrcw!t9XdHE&QRHi(7 z-DXvKk$>qrf4C^0qn}BW)@3>i#POK)Al&A@EsL9E#jOb?TBJ`XI|tVbyZj4U5x;T# zVy!A6vFIB1HiW>raL2=WuO2_VLxCmgemTbY1gN5@9Z3(@Drs-dhpweL+M6S)J*o52 zwxp|kDEQ|a46!AYp)%qSsc%l_AAhby&n&Xm?R3tQhH`w5QBjkoOAP*{YFspx7mN&- zx4G;cCodhrSyV6$nB48(2LICxX0XOkJ60D=bp0!)n0&A&)8k6px+KP(<7QXKc+8d0 zM)L!PrrPI280j>EsP5usg6nYjn#7rQoqOzu0L-0k9r)0Nol?HPq!cFuK93AbMzr_a zd;_KEt>;%P+i&rNhMBD+WmcM6*>5fKCggiQ$>q?8T`>6VrTNhK9&k?xQ# zMHJ}{N$Gm#*5A3$ea`h<&-GmA&H4X%gR<6MYwfw_9CM5@=lFaH-7ajVt=+tfde?ui zbFduN3Kv2w{H13do}AA|jnxkj+(2LLBlo0}!6=fq z#)PgqXu~+fhIot zOc00tYw3K@%Z0Y?thU!ttOPjyVOX~KEj`My0acI~_|Elc@p3FmJ7zn}E=i!;{xF3H z|65Hl0{MA!wYO!Ns`7g}4Eb^Mud$w%K6^;TS9!^$05(@JPIyL2ZEc4OHb)ZYx_(PJ zi2AiENA{z|{1bC-d++g>=euVYX^tj=BwGqfNiNLu1(~)@;{nz*J&O6iRnW7r#AEK$ zxNLK12ie{kPXmU=P9!S~+KWkyLfZ9^2oeJ4k8z+W#z-w?Az-b2FCEWGz`CmHyR^ei zVAC(wCDiXdd7A=q6on-aqaD=tCatGZ75$T^w4nbEgGvwa0B@u%m7gd^ln250@>1+T zo{PW(GsXm8Qg;fFJqKCh6@D{FtWcA6DsuL;hgraqem>2Bc? zrES+(CBNWyrTBJ<;Eipm{zS=6PY4F>7&Pjt?|S8@lDxbirt>T_tUJV<7RN=1>9f{C zvUex_i%s7&y0%>|+Uo%qt`{`Z7$$?k>Vn6Qe&Xa9!&2Tl%2_H`C^Ul<+v4S&X5P-T z@GAwB$Fgg;HZADzw*6z>(Ws84j$Wdq_^Q+M#J=u4dU>UhyZ3Am_gF4axR-63xR3(X z;3r?$%XDaEOQ}>Z&06yMb7g}H^;nNpQ^L@g!$B6v$ES9hA8QrI}_oV_CQHNqqJM2zf zO;NcyOHmsuhtd}oikeT&ra|ObFeuPlNaPwH1t@{hs_qX>$&g)nt#%G_Cyv z_mYipxLspg_uS=r;pc;Tt)i%l^eq#wO9oJ_lF718L8|GN$15Zcr`)7zExHEf!}M#V zX&ftYflz7`V>y_9w|o*6;S;tngTd#nkE0Ixr!`)1H#BrJ<I5u`Ctz zFpu7(ZII0z!%|=j#d6ydi&Vm`DW4VJ{8D@o?W#tlQzP;=hPph{5d_o69i{U>d!4(T zJ3oe6WNx7picizc$eVlB&~rM z8^+I_`Dsx4R_eqdTwxA|Ya1U>bYQ^njM9L@!i60x{-N`a>R`a(a6`8>UB?w??flB)14Mo3cg|07X=V-Efp{Rqj zgM=j1nqW@}8jan;x$FK)89KqxqP)H6PLyUd3XK6m&kUECd~`J8E(bei4A}OCyE+t_ zd~+v*V^M?vk6(T)ZQ)JuLk0QISw1^y2;K^Onx~>PHcewr3$ZMLO41qj+C#W0$`-*r zYSF~Q-p+`nPolV7Ji09`>gWMISXS7SvsCM^PMWkQMT^moc_^*Wy4Lm8=Ar3SN!Afe zk#|)|_&YFiG2AeCjRROr$h%SEbb{U(1d?bmR0pBFRev%&3X4Dq?>P*qE&n+b8pfo6 zN>Bx2y)%j-s(${RB(mjE!R6b+A)G{o%rp(6ZMILU9+WCtV^L0P z{A@=#u;g1Ag?$lm9(1N6!$ifQ^=6^VKhR6N94>yX8Lz;Sajrnk5-SxXL8EU8`5k#w zjNdC?PYa3ht$iukU#oF%rLhx3giZzHebWJTorT&=l+>>z>Nyo}k-O08h<5o=#o(+S zv3AN{sWtLgu1$gqOc(;p}XIAztHw$Lf8e#7o`V;)MhN_9+qv-0qcPv z9ZwG3VMs$`zE-24So=MtLI%pz+Uh6zC3~EQyts~OcP%8>aJ%UB&7-o(463TR)+8=32JsqwYj?gYd8TMHLaSAwS=B8-F6T0qj$>4&pdo0Bk#B zfjZghY&*yArA)=05QHg3j(Ue|%zWaN?smrAd6jt0-23z4g7k}(KMY#a)9gewUJKN`7=$vh+$&dDnX|;B`b>`>smgE>e zvr+33(u^MzYV*q-t{CaWw`x44`^I!VBBa&QlRAVujF-6<>7>ymxNzPkR&6SX1H?LhK{{J-BVtc-1wAnjx|GqEwf(}-&k-OwSVZiT(3J)E8DD{OSvooo4;}H*$N>59^45i4+r@=P=WYH)!|X%O~vep-!tF ziQldEROdmDJ9t9Gl!&GjT**mQm$)+e3*+tbdLg>2IN>1KIER?hBha;g0^AS=kkhLhbhYU!N8ppR2o|nt#BK=D&7{J&hy^x#3+H4o|%}c z{y2XNdRyu4386)P{$1O>G2&bjF=WvriJ78vzyl^KPOIM0J)G)WchLkKX}QJk+4>Nl zb{{8wB7#nge_z8`8Ed;+Djp+DGazbaZWzrYKd(lg$E@s|$3J0H=(nG~K}RVH>(tG4 zpv<|eKuj0ocdR0MZlim5{%!@8revOT_paa)Y$uJwJFG<*1&$~rm^atLBO}F#hf-}!^YrG|)^_YJn&831yB235GIz>23w&(o# z%}>tO^kswSk_D^y zF6zWo+C+;}R!k48aEe=n2v{Q8;zurPPp4KuL0aYQN>nkS0mwK`52sPAPMJ>T0E{Bw zAU5Fj3T0zpQg3O*AnxGBdZeBhPnsju*Dsc3Lh@dBGh_}6o6u@s-3Vp5YDIIjdFwEc zw5wv}c0%5s996R&K}5*_m}{1;Cg3F=P_PKMMkj6uF-FX$$y zaJsjMr@PLwR&;hbQ_YX2HNk z$q{d7neJut3&9lFCzrD5-T+r=5x#kNLAG)V!*l@LH1=Vc6z^-vffj^O31yP<+1O$l z%$RbC=AkGLXZYgVz9J07(;kWNLxPKvsmbWT&%vNJS0d+`q464Ae^ZM6o(b4=-ZOXr zh>Ed7#he_m0{y`!AiG3_x}>-lLa=jgp%+i0Ky0EL#V?_!pVYA-4FhQ7YbNU4t|Nux9v z9L9r+9rKu`ALHxK^ks8eu2@l@H;m$xoghnmAm=xr%zJKkcP}8F*rOm|zI7^KC04Ui zhyWxK8%{!i1;DTt<(*oE#7@bg<*v7o5*zm}Z3LJ_W1$$ZW9%tAFIf84J$qPaqvuqV zgc9#X-dz<%K#3;Ezt^N)*reUl?SP)7;HH^o+)-+lLtH$uP5=_xM}<@Y6hpW)Zyw%N zuJo^`rKuRM^u-VqeFsT^h@x-u4e%GPq9492qurM3kv6-|Up?q|o9)d~=;zvb<3gE~ zHclKpc5OS@yZfdRci&SjmWXDXgcn>i=%gVCwyLRhr!ynW>F2{`8TVHxjri_~ z!UcKC-1ZOE-!7Q$V1Y=qYp^!JjB`B0AYAYjL>`!5;?sBs_0CNDI4l--rcDe~wwOI+ zVcJ!P^RN%je4Q(NFm_&MTEUk&mxU^KTcRgDEKPhZhiWkKMl1Ytz&zdE&K$5oLh$01 zJWsaE{+abc50ONl1NFN}fGXI`ZVrg-i# zhxjpeK`OD%n^e0ci5PP}tI3TenM4phn_{x;doc(R}T*Th>vkU#Mc5Q>l947SVhpP=!s*q<2hA4;}`QZ=g{Smpt2Pbjot9 ztfwR2k#X4d@*k;YfURX$jqGf-elvVsxWo0tO0Ltzh+a0%J_e%Rn%6VP;*R;ZAd}8QAp>>Q7=%a%5Y#98%N0 z(1yhCWWEw47&JQmw#@@EKCF0CGWl>Ts3OQc;wa-6#|PT8diFJiGn0D<6+sqQ17WV! zZlA>bSX#vi9vgvM3sh!K$&uZyo*{u(_%okc&LFPWC>f}ff*kO4lWbMxDGADUCT<0E zoI-z6Bq=bE8LA5MV|siuQxBEEOL?^8qktC^5^pv;o&5ayiyAnUu%&YoruF!RvO}um zCl@1KLn30y`&OUyth1aq22jjYKv2ppY3%-X#BM zW33IW4&dBc-)>12;u+79b9k{C10($W$k#N=M7zxH@+8yY(44r^WgxO1@#C4=5)9f| z$R9Zn;J|U2(>mdszk3?`APl;V9yR?zm&ni_uD})?EUqsK+gM=@M1S0{D+RSC#N{fT zXBtLLiG*^vWR|*+4)n3=o5Cs%JT$0aqlb@W(Txe_t0fk=DYA0{bnrc;M%-q))SkbaPLmr7xHso;O4F+B3hXl@Yej=HHMx8`DE0aZfwFxm(CE>CK zTE)+j{0dp8MK!^Wml8MDGI@%_GonG8uL zSd>eFXS4i#?S)$1ut4e_0R`0zG?NTekvGx_|jrlSSG~U zZdbZ&awyXBbCqUq$(J|$M52*tgvZwEEEhK1uXuU5Yqtkrgk;1n#w#a<4ote760rxg zB~4WiD)|qx)LG&TcE@)gOfz1LH<8}O%aKkq`@Y6UMLK+YN^@^|s=UybwU;KAg_rWU z9;0nT5hD_TIen*6igaqE((zu};}!uTK^RdkZ8xX`piJ%CB(AOWH#amm`TlKn?Y{2L z1RUG!h1IM}sb#a3U*WG7PWre=1kIf4`$kcLGrCFr6qbRUCFp?gN4lk>k|XZ9kxJf= zU1q+^)l=4$BTRb*kBBb}oalyvCH;uD(5KnT3l@j`Vy|S{HGZU$W*(-+hp%-1Chx^T zOtW$>iNH(|hT1&PV}l1DOU+u_g!n=)cd;f0#5xYleoXb8wpW>F-px6*X8@g>6 zar1N*CWlFhVkV0q=P};OlbEb=P=ZNb9{n(IXpL+_)v3+RIba#167HG(p7pG`MMluJ1s#Z;AAtp=>zWchOUJ4u1@8+dDoQr6u@9PC@rY^cm7ey2&cPE{L2y z5KYzaos$?_$WOLi+9WxYm~jtG3~3s;&!DHZpXc)E(zn#Y7!!SqxO_qCOio`yX9A%i z2xDetHP6oPzu#~^Qk8d0t(z*dEB~a*uV^olOscRk!mHz@9JY+cXX=4~qo||Mxp=Ii zfrmIt9zt;wzvkLr>iQ{XAHDNTj(1Pluz%N$K5gzy3`(C3{M6;PbRK)gCLRO8Hn%FT z+^YCt-0pyycWj~qx6j5?)@iCk!J`5z`eB|lz&DpN%YZ+Yw(`A~4CPKKo!}*_wctM0 zowvO|+@R`_a4B-;pfM%k?D+I2tsi=;fIB+sT%Sh;KAcFR&+@vO!9`Ky(0dhi+GF+| zn(i(5YAHtucWJpUO^JFnK_$_>4=_@0{Y+w^ku-r2+oo(m{6P+G61zCv-{Ytu{?zdT zjE9yF(!{%0*Ds$RYhGIU3HTS0s@>C)#xYGa7pFWHxTKg=OOcw^uXI;3+}ZXhaa$XR zv+RLB!JQ^bM)z}k`Vys9E=5_WbUv-!JEP~0xe3Sme0ALt@y$42#1;B(K~RTZ_OFPe zEZdd(nj6i5m|x-q(XW?8;Edl>U3hbMY||FQ9vWCmRA{bH zwOjN^&WR9N?PfbY`c-r5Rp4{C0fOq=<^HnWt|qCzVky* zo07jUYGuG;mEeN*SfTVA@0vLt+NABQ3X16^?NpKA?!kPxSBLkoi)Bu?tO&t+e?4)l z(1*2B5e)J{eW#u7hOQSnpX$jIs)#IP*)L^d5q7TK7UI21h3S?fekmQYG9TLzbE*2P zIQPT=@2xI6O)o|DhvtESkH9W-{QX|ENtMY5eir-EP7ffh68dVrcCk>5hrmzT(r;nB z1vm2%9k!pkaf)r*wK6fAX17zjnEY~|mD!G6bVWMiq$0-OGju~XCy!TAw2yrorMffWeH!bF zPMdFea&(9tMxmDBMphxg*J4uAqAuO`>SPVpnaAr*rzSPCOwwEwXo1HbBe(>P9`veU zHt-OV*uK_RY@D_ZeU|ORH%pkjp>gU1)G&+{W76&g9rhIagwUOLlpn-O=iAcD zMqL7yp9H^8pAXPn9B!{H;TfG@jzNb=`D$#Bqo$86GQB!Mn9yq!!vgjtGVLC!s;6Ob z2hv51KMHnZi%uleFo%sTO4Th6pA@vLmyGvcNSL|4G31pVfmTVE&M$|Lto5T|YqYQs zG<83sEBjHc#M(9=&=;6VhCz6q+2wqz^93w$v5N)DaQK+8EHiUOKMUr3Utdvzx`4FT z+DZ7{!i_GKgaS6UrL4#ib)k#$O3b&1X_P)#1C+Y+2Rqz89y%tZdf|yi8lLdG8#~xu zTa=Rz%NQ!v;bDWH+&VBdCdVH=;NG@nSZR&(>gywg^(~$h>=T{N_{f#NEr2W#=DZ3* z)leV*un6BNIe@Gh;X;Z7gcxnKha{6f6(gD#my;|9BuCsTuSMbvM$V)LQb(+Ohsrly zNs~TRlF}%AjeEz%Zn~7xOCNR8S~l*ezT||ANtoV_to!|nj{wK>CUGL3DKUw& zl{<+mH4PnWh0|O??#b_6n{w=<-hcGMOuUb`C6N5_%a=6!pp|Y_t}TXvsI$JNCs)?K z_h#fEoCYa_A}RFA!rYmq6JEt_eKK1Z0};O}J*8Bg&;}2HV>I5^5|a3Y+mKhk)}A~6 z3?`;7GVP6PnWmz9T=G*3VPUdxQt7AtP!-B_?4|n~avNvw)IKCZmlWQMb2!dNYHOfe zAatXVGV#N_0dibCU&U7#iN~?LZ9V1xfs4~By{aYuOw}oCZ`#00*Ws+WG|u)0Bio|2 z|G3S?aq~XU1cgckrzOK%$D7Ww*c)``(TcRbT z$#)I&tI#++^PzxNep!sMW!q!Mw=}UhE5H>`<~sf;z3N+Pbk?ABul;%ZadyY!6t;=s zt+N>2VFP__#Psr!y7-OtO~&zBi6!Qi%!rPHmFe*FL6;}ZYo7$|?W}DX`#tts+?v)t z9l!{@Gma14D%B8}y+vO(UyfM6Mi?HZ=x$JyV@#?O%_U}BRnv>mZ;QYt4_|l^Y_Wyj zh?u5RhHzd|WG_v%Ne)&rnR=uXwnSZ#ZMo}sw9nt(5Nnn=w!CEU^Pk1Y`bPQ9b#m?U z^s{X6FIGks?90hZceCb^lda5NK_Y`zi87J7bn(F#xYJnE82%$hOfHDfD=4f?gp=zq z=SuD{!n<53KLH33SXZe5Z)^r?y`Ze<&T zQcxK`<(1cMArzRp%N&CSq;lbtI6sxqL!j2~kDX~B%BJq+12@N+?Z6B}ooB}2uDC{T zsElchiSV_@Jnce3&+fvfiH}QNv93$=srbbGaIzv z?|{cjf^_@#(YMvE;P+f~Zc#(k3T&Y~1{+Tzd)4)I^xu?J6yi!_ixHMSlPq>wOy)T7 z@!Rib9jV0U%)iWJb=FSMNK5y~MA~uTI!8N3@mFvZM z@VI{1S+VmaC5KN*{%A=APt5k`s2Qtw2$Rp6Z5bVXqK6+!+>^<6L}hf##`(Uw45l`9 zBrS6`P-wxk@&E$27x1b*^FQnLS_VM#0RXzN5 zDPB4I@H?XU!=xx(X^x%6nUBS5<~#WZ38w98u)cntR^?Ko!NbB7>bXuALlZ8CEgyfK zoWzRRs>iF-{D-%1H(SnX87#BD8d=2%x^KboeE-FF2MJ~?dYh*xvSoXfac0w|GYvzI zg$cvb*0hUH((Ypnq^xl^vHxOeYs!BFnRcx-k6)_RZu{(ZkT%!noq~<-BQ{V5gWGk; z1|)8M{m{CLF{fIW_=&gA`OT~@UM}54yJWv)ig=<1e8-FPQP;uniP0{!Ffo#FAmu12 zg>M5_YFc(0jZX&tyrinL7362O7B*9)%9lK<{PHQ3?8?a*if+V@V9BCHI-iq?*9&~f z{Vi^?9SEksRPrsHCVDWNOD%e6Y4ec!X>Pu07ZsF?EI9S)xcN?0#XwmUyfM;PSs7b! zMbVmbmNeUW>F~7KoG~+2hPS+iX!WE>tA@*ma+-V>A*XGZ*CYFSS1p*QT5i=RpyQ;# zYvhs}ivVZj@bU5Vg9k6Dg|bRTY_(icWDajZQ#8HH>KrxGI5s|R%>DMi|3m*!!Z_j{ zrNSh|K&Cu5Weo%M#eMsTCwig@j_SEg%z5dWdb-`u9DBkVpu++wB^^UEionG zcr@j{M@N?$&&cHpp==5_3)V8fx76xJX8Sbxtvgzz! zUb<4q^A@{a=H=xvOM`-5L`Mh?MO3%8zUAfVex7NoAEGOQM5rklG?zVFw zN%O)hn2@T0??qqLg3C@CPn|S_`sd0}%sAxjX~AVTfv`&i$7X_V`D0K5Hu_d2j%w;Y zXn!$$9$hG+JDOS~Qd3QP#uHGFlmJGW0Qpv)ey&h_M6Gx4oyVU>{%8%)dk0$is}!>F z^M8nxYCQr6HnWf~Mf(@EUNJW~a5Rj3StZAYmT)2K;Y>l-)xpIHL|+0MqCbgizl+T0 zWVtV~v+E@pk0qdfyjPz9Y9bUlrnPq8?~i;#|F0K7;gf08 zAZMHdAn66NoYOl#I|HWIE~n$EE#xhGp#mX}K1;L^(aq-vI=FpE2 zDA0ej7v_Dcs>@!enbR`9* zozleZ;pwV)E42~)%j=IgJcO|M04Gq3PLWf#4y1C{K@V8j2XrmQFnsES=EWHnElHqL z!yWf$k2Hh0Jt6lU0Da8d|+3 zB>)-qfNd7PjnvfN26fsCpIPEcrLPx={HgfsmlL+3yTb=71D&95?Ga91WSssQs2zSe z_u-?s&*|P?a=Fh6{jWP#Lm5zjwK3cXV{113GmyV#Bf8JG!ZGnEN`FfhZi(casn-FL z*P=ydqz9!Qs43b~rY zMwg$NUKk=VGZvO1w$wl=X2ms~ViL9CW>36O;N|vv;`Vv4gp1{ib0qBhe2>^m$0|-Jm5Js{u@QO!5XBI%| zeDqSSG=T3pUkmwqZISqGA*;?|a#%zRbUm^3Mz-HOc6Z0#s{F)4mbmvzvnIh#e!4FC zET6DRj~u8;y;6>%2n9eZo?1QbTcz{jt046&1~{mXEx+HhwD{X4-Rbo}65c`&iGW@J z^}+7E#``zJ9xY^q;Kuz_&@kvOe`zl5XJmE>iMDgL`-C+JNtCz-ur0nB9_d>uz-@;r zfb8p8JCoY#2akJ1MKurV<_VCzZ=^Wok|RO}J=w2;ZR|(DzRqcxPbraN4iF^diTzjw z+BOua0lE!pG#5DJ&Q!Mx-H@2$5Q~`GZ{GD42vaAL`K@)SzB&g`6bv^xew`5{Eavd``I=}W=e>69aK@{3 zmHkf?55KD&k^vPMt4z&kp=!`sdn`LWRR5#lfh~Y-S9HD$gBlNEAuyp5WfeNXY}-^iA^|m}>c9|< zfP1y(Ah)1RMeckIHjLR5O-=SK5j-+`m??%}sQ@6rL@Ts`rs{)bsiX6$+BBmY-Xqr9 zW60LDcp+F05k~R{x_Uz}bhmZ37!2=frC}R6HoN1qK>Q=&y>j4aZvZQScb^Aw&7NNe z1T9E4k-fW>gnLhF%BoGQ{jwEst?go{xshlAr(H zAY*jJlx;=Jb}D#{YxK0=5x&3Ef!kC1*+^1rp+HzO6^mGJ*+P$4PcVXOon4+yjIrX? zXaI#^4GkxaoS#o=L=mpb{=Nb>J$d<54gkqlR=t`V3pEQmVturEb0~M?np|NHO2MPH zxICJfjB^{&05`Cz|3!T#W**jzFoX@#dKweL+?3ky_v161!+$@@v@6~Yi2$_C`T;;4 z<~CRzXsgsF94<8h^M~3~T6f?IYROGT{XkiU0iC=-YD{=3KT)H9w$hwI=mFCpQ%#-} zHYBZ1N#ol0aBU=R;_fqIMO;I@J)uIGA10oaOV^k|2RARkR-E1R)N#yLZ-XcG7 z9n!xcMZm)V1YxG^S#}8(2JpEDYYaKfx3L=T<=+?JqkIlH9sL$5)E_Xx%u5!G&Hbz7 zND-F@a!Vfm%HzYm8F`3&8x`Trk?9SThu`g)DxYY@)$w#MKWmLm?hCxRJ|CpY(2`ls z*#{XUbQ4}VvWBWH-yTpNLg8lJzwa9&rn{*hj(oRgO}FG1JgPqk&DhRQg`lv8LThZ8 z@7y~KvFs7+5FQjNhls7e=@9Gw5OijTmil$3M>G^#s#%kg_xgV9BzFzJ?NeUDjpir+ zYK!@IlF8}~*jgY#E&AYF{rS+N8{PCbdA{+fI}2HnDRLNpTYo3k*bc=^z))|-n~3w;u- zIo1#aJO7^^2%xO zVZ{*SqGB$ccgE$h;Zg_ytONnw$0O%^z@o@%NPRGYFhSfP$u>fYYO#gOd_0gyDl!&6 z+C8rt-2KTyZrZ;t*t28=Cefb2Vhs>+ERoxmLhpW{xU7ZBBO$TdB#{Crclvt_U4kGTimVa^qc?HxBeM* z&saSQ460I#%e#efyJ}RBB&L8lbq_pZKdqP6>d+3Cpj}sSx=+2mvIv&X>ccQa&Q7 zY?VxQFO32c{Yswr&K7n9`3_9{2D^#dYLw!JQ7{A)tDTBJmM33a) z`F$SZ9OTQ4F@I+7*bxFtrR6VV*E#tmm<}jh(w16{f>z2LVkVx^S-%_)pn1S z!;p4S99OC(bo|JE$HgmkJO!=u*ShR~BZF`6I&nWV0z*W_aZ9eGX#9RfVw|P?vmjAV zR{in%Dvg3{g$E^V2U%`>xo3(&2o-EM_Vi zeR=e%jAldp(Bv%H@A0Pw_Y~X*vLE~+gwIe=s0&o@DCl-?STO8)Nfb&j{!VNQDI=|s zzIU2g*irTS`{jT~u!)Eo1FC{ulO>52#uOSvH`9`luwaJS}q{RWRwoZE7 zBd=t4z+cBukLeCKmQPIsf=S2E@fp$e?`zAyb_W@Z*>^;`D@0*7Kx>Y7ZY%4CLD1F} zl|157-qlSUy-eY8d%(dPbLab#=+f~FA=G<}sU&Bg3`4lt_yxkVr7`P9~* zwlig&&A%Cn`4zLnftha~$MphtVd-MVH(f=?4|KD-g-}r7YT_g$_-wFQfR=3UC0tA6T z<>Ewwt~gb6EeJVz4Qq-|IY3PZ9O7rHzlZq2O5?J`SQuw)gj2NfqlQM*~>UmXyPvXWVlT}WX4`uIH_kJWG{HPW9Q0J2<5_Tp#a zGUE0>Y8H*SVa%2pbtYMQpzG@H{vBfFUqhit(C}#oWeai3?*f6)5#Jrxg}IxnxlRxQ ze?L8qGQBiM>TyOnmUy0T6m^1>K+~{D{%tS0P-uD6!TmH*TkU;YRYQ({?AK;TQm0)Is-W(Pk_^*>8}#NDXdrYW(K~x1&g5vFD4#{KYEN*mD_t2=ffHebm#PZTF-_Y!vLnVs{#Q)S9n0k zEwX&69*KymM9W4B9PRhtfZ?jBq@=X%0rt3Sc9 zC(u1#+%nMc;pY{$ zVNqP>pajh$kXev#GXUoZb|pk!B14;A?c9z_$D3oveGeeOD5Y1b!-GHSVgZ`Rd>)JQ)-o*C>v zfa2|1NU+r;oPtagBM(VaY(R+FhSA))-szB|A6X|6lIpx5HFu`LMsCpHW{a;3;g^Ri zyw9k)3?rnck^P-V)IBFq((;e#FbRda_2rU2kbmWL(3k9Ict`6YyU!HRu(99?K#Ke7 zJypO%;qFH|O-V>T8Wt)3kG_|@3MzijbbGpsdn?QVOD%ThNdgkqh=mFWk%m6%C-@D6 zqrcDww~(a9>m0LSJ%XCBwm2XdH)W0nY@_)U;0Z6?Bm#+-5KW&&vgAs|^+KgB>W;`J zbA^aXAXeDrz=Y(+*KL(Gnh#KR5TnJ&98a;-p5L>1nCNl%O1Jet`(%TY)7R|AAXcOq z&jBg{OLN(PKo3{29KsXBp4@0@4Ua&e$F@Y{Wy3Wzh3h<&+U>=ulNa%MdluT_&oN^=G8~h!uS~gL^+1f6hd#K&>8R!%-pd9QDBwm!w$%4IhzfI zjI3!0A*D*BIZ9;zV=g4*v6*f4++XZxio)^OHH*Jn*02V(c-*^mdGs^zR!k0xh9QnL zpoHst5kByxOkTb`oQs=eFP)zRhUBQ6Cyo(-TBkZ#-ShHj2^AjB1_fya=n3K*XRxTB z_UpHhI(p&uWHJSq6YK8GDtw9+#lm5}E31dKKwAF51Fs%n;ufc<-LMy$-2@OOD4!I8 zGNvof?n-UpYx`P*?OB$8?+GSHA;!J>ma!E0CT$@NF_Bs{i;lf5SkegN2Swh)>3$!3$=0ca|A*ul>bt zuu1?{IYN=EFkm7H17zQjjftXgFh-4dDb!4oC0tj#MxO&ese9%v@S6FT#+12N1@h@Q4BK-&2J!sCRFQfT;u0FVqL0)_w8k>wp{n zAF#^xKlFD0CkuGC?uc%%Skjrmrp61_!9e8j_t%$VElNj?5B#Oblr~VDy_+WCTKJ!b z!4en+|CjcXDDfgaO1-J7j(>d+9Qi?E^v^=0-k*31e4YQpmlgm2H2A2L@YN9YLcurF zr@Ul*j;X4S>V#1#eB8s_$WM<;3WHwk$Y(-+4O?BUP&x5cd_61`PTx@TQA_d@ft1`V z|7EL!br?>$Cg-r&-%kjFPY_)m?jqi6On2v+_wqNws}yZ2SKdzdv@H&?;YC$zAYW-s z3UKtlmY|P7re$k8xuNa@kqL(IQMNnCgI}bP2luZug-hW|wi5;RX3|8+t7{)3ug>vX z?t6tfLFf+C-`@Sj=TFSgoe_l`&k3xz1wa&P39nrJXB~KG;LmboY5m`bQTq`2r9MJ< zYImD-rr0kC85~chV&9W11}?rhta?x+w%^>nX4LTSC-c$k5i4ej&VO<0Tz|cITf6MIAL8J<;-&v8A& zm7Fa2Zx^*YTd!T{C(#do<$AaKhDeoy7@lK`biWhGA^oQx}_dXu3|EzI8eGClaJGM?- z#qgPiU(jpVxu#I*RP*#~<>F1pdx5a1FcTWd-x9oZvnR!)dAlTtDIS&%#xN7o+RYl@ zsq(eJyqoAi#Fw9Ah%cFA`;MKo19d$oLxwOZze$nm@NWOJi}iYo4hhX1ecSr6pZ_ei zXQU!cEhs#pAip?~g#CUk%cP!u9@|{0TUeqhectgGDoi~+>3rK&7EwH$>L{S zsjo|K>`!?I3-KCq7w7($_XyR?uj+m~9WoGRN)k3mLnG$v8Re-Ghs|-x^82+Alc@R@ znYZQ^?F~K5)d?p1n&Mi<k~IPWQs4JEHvd&h8%`Jrn-@_{=B<*Z%*gA)g6fw z7vZQPSdV%-IW?4A!H!SlQ2X0^3OXXiOr8_Ic<#t}?XjI>@hMKiaVUn5)xrO|Y}DQ* zZq!oyo2N=V_#=)9y9b^Lt=cCp8S~V5u`CZ<@z@rw*#oyIl}`k58a}*Or1p}ZV&WVb zUZ_!>Y~tmad~06xkp4Z+vJem!yu_y-H8Do_-#d{5HGabP{Q?!mIIiXno$74D*D_U) zrdIZ4I((NHqxqPr!WTCTlq^11=%kuhaK;;|jD8IsValC)J1vViT|TSNr(xzrR4O;$_F{&yx!Yh}2L-b$BnTNZf{pV%llXGScXEqz8`> zmh*ex#?Ls@^?W)RzqhvL5EpDoA!m&=a?|OxhB4N?3qrT=Tt%7+5o}+1=7;QS_`=h7sJDvg>OY?NHy%=PVGK9Nk6}n zChY(8^dcmDHoFIE0pA`y6>o?XTchbHbPDP$LAGll4sM6^0BCPqvHs$fJdjF|{t)2ak;YTvU+h5=M z;r6A%5|4QprQ?Ih$lBKs4(v6g&Cx_@)BSB*#$qhFG1 zq(|N}1WdCm;yj4D+W?tLRW$^o{@o^cTT0WwoCRX?@$&Mdevq`MbfELqfj9WrI!_`` zOPEXm9^!flc&m=tvf^~#cDtN>S`&F=LcN?1+9r?#1s^Z9#URrXd2+t{pLIg;um4;2 zM*aDY|3~fC`rmk>gX}OU5H-LBOTq#mm_WYDO)3M_^!5fg$ovcBh&w)3SN|`rE}ZiT z=GKoo1W5QJcX<`EE%nBMtz-Y`4QsE3MhBFdnS9XsJBAa!{QTQH|JSzECEuX0lUTj( Tq{%fy0Y9qB8h6SR&4T_PJNI#N literal 0 HcmV?d00001 diff --git a/service/wechat/img/wechat_sandbox_2.png b/service/wechat/img/wechat_sandbox_2.png new file mode 100644 index 0000000000000000000000000000000000000000..cef296a9bf4c09c510a09a886924adbdef9b38e0 GIT binary patch literal 69835 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%0Af$)<&In=T%Ghx9KxU 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 QnnNj!^vsYIR~#e%2c4ABIRF3v literal 0 HcmV?d00001 diff --git a/service/wechat/wechat.go b/service/wechat/wechat.go new file mode 100644 index 0000000..383c6b3 --- /dev/null +++ b/service/wechat/wechat.go @@ -0,0 +1,141 @@ +package wechat + + +import ( + "context" + "fmt" + "github.com/pkg/errors" + "github.com/silenceper/wechat/v2" + "github.com/silenceper/wechat/v2/cache" + "github.com/silenceper/wechat/v2/officialaccount/config" + "github.com/silenceper/wechat/v2/officialaccount/message" + "github.com/silenceper/wechat/v2/util" + "net/http" + "sync" +) + + +// Config is the Service configuration. +type Config struct { + AppID string + AppSecret string + Token string + EncodingAESKey string +} + +// Service encapsulates the WeChat client along with internal state for storing users. +type Service struct { + config Config + messageManager *message.Manager + userIDs []string +} + +// New returns a new instance of a WeChat notification service. +func New(cfg Config) *Service { + + wc := wechat.NewWechat() + wcCfg := &config.Config{ + AppID: cfg.AppID, + AppSecret: cfg.AppSecret, + Token: cfg.Token, + EncodingAESKey: cfg.EncodingAESKey, + Cache: cache.NewMemory(), + } + + oa := wc.GetOfficialAccount(wcCfg) + + return &Service{ + config: cfg, + messageManager: oa.GetCustomerMessageManager(), + } +} + +// WaitForOneOffVerification waits for the verification call from the WeChat backend. +// +// Should be running when (re-)applying settings in wechat configuration. +// +// Set devMode to true when using the sandbox. +// +// See https://developers.weixin.qq.com/doc/offiaccount/en/Basic_Information/Access_Overview.html +func (s *Service) WaitForOneOffVerification( + addr string, + devMode bool, + callback func(r *http.Request, verified bool)) error { + + srv := &http.Server{Addr: addr} + verificationDone := &sync.WaitGroup{} + verificationDone.Add(1) + + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + query := r.URL.Query() + + echoStr := query.Get("echostr") + if devMode { + if callback != nil { + callback(r, true) + } + w.Write([]byte(echoStr)) + // verification done; dev mode + verificationDone.Done() + return + } else { + // perform signature check + timestamp := query.Get("timestamp") + nonce := query.Get("nonce") + suppliedSignature := query.Get("signature") + computedSignature := util.Signature(s.config.Token, timestamp, nonce) + if suppliedSignature == computedSignature { + if callback != nil { + callback(r, true) + } + w.Write([]byte(echoStr)) + // verification done; prod mode + verificationDone.Done() + return + } + } + // verification not done (keep waiting) + if callback != nil { + callback(r, false) + } + }) + + var err error + go func() { + if innerErr := srv.ListenAndServe(); innerErr != http.ErrServerClosed { + err = errors.Wrapf(innerErr, "failed to wait for verification at '%s'", addr) + } + }() + + // wait until verification is done and shutdown the server + verificationDone.Wait() + + srv.Shutdown(context.TODO()) + + return err +} + +// AddReceivers takes user ids and adds them to the internal users list. The Send method will send +// a given message to all those users. +func (s *Service) AddReceivers(userIDs ...string) { + s.userIDs = append(s.userIDs, userIDs...) +} + +// Send takes a message subject and a message content and sends them to all previously set users. +func (s *Service) Send(ctx context.Context, subject, content string) error { + + for _, userID := range s.userIDs { + select { + case <-ctx.Done(): + return ctx.Err() + default: + text := fmt.Sprintf("%s\n%s", subject, content) + if err := s.messageManager.Send(message.NewCustomerTextMessage(userID, text)); err != nil { + return errors.Wrapf(err, "failed to send message to WeChat user '%s'", userID) + } + } + } + + return nil +} + From d61e3712f53eeeabfd279393d4ffc4ba682a6e3c Mon Sep 17 00:00:00 2001 From: gtourkas Date: Sun, 21 Mar 2021 17:08:31 +0200 Subject: [PATCH 02/14] adding tests --- service/wechat/mock_wechatMessageManager.go | 27 +++++++++++ service/wechat/wechat.go | 7 ++- service/wechat/wechat_test.go | 52 +++++++++++++++++++++ 3 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 service/wechat/mock_wechatMessageManager.go create mode 100644 service/wechat/wechat_test.go diff --git a/service/wechat/mock_wechatMessageManager.go b/service/wechat/mock_wechatMessageManager.go new file mode 100644 index 0000000..975964d --- /dev/null +++ b/service/wechat/mock_wechatMessageManager.go @@ -0,0 +1,27 @@ +// Code generated by mockery 2.7.4. DO NOT EDIT. + +package wechat + +import ( + message "github.com/silenceper/wechat/v2/officialaccount/message" + mock "github.com/stretchr/testify/mock" +) + +// mockWechatMessageManager is an autogenerated mock type for the wechatMessageManager type +type mockWechatMessageManager struct { + mock.Mock +} + +// Send provides a mock function with given fields: msg +func (_m *mockWechatMessageManager) Send(msg *message.CustomerMessage) error { + ret := _m.Called(msg) + + var r0 error + if rf, ok := ret.Get(0).(func(*message.CustomerMessage) error); ok { + r0 = rf(msg) + } else { + r0 = ret.Error(0) + } + + return r0 +} diff --git a/service/wechat/wechat.go b/service/wechat/wechat.go index 383c6b3..46638c7 100644 --- a/service/wechat/wechat.go +++ b/service/wechat/wechat.go @@ -23,10 +23,15 @@ type Config struct { EncodingAESKey string } +// wechatMessageManager abstracts go-wechat's message.Manager for writing unit tests +type wechatMessageManager interface { + Send(msg *message.CustomerMessage) error +} + // Service encapsulates the WeChat client along with internal state for storing users. type Service struct { config Config - messageManager *message.Manager + messageManager wechatMessageManager userIDs []string } diff --git a/service/wechat/wechat_test.go b/service/wechat/wechat_test.go new file mode 100644 index 0000000..6ecbd52 --- /dev/null +++ b/service/wechat/wechat_test.go @@ -0,0 +1,52 @@ +package wechat + +import ( + "context" + "github.com/silenceper/wechat/v2/officialaccount/message" + "github.com/pkg/errors" + "github.com/stretchr/testify/require" + "testing" +) + +func TestAddReceivers(t *testing.T) { + assert := require.New(t) + + svc := &Service{ + userIDs: []string{}, + } + userIDs := []string{"User1ID", "User2ID", "User3ID"} + svc.AddReceivers(userIDs...) + + assert.Equal(svc.userIDs, userIDs) +} + +func TestSend(t *testing.T) { + assert := require.New(t) + + svc := &Service{ + userIDs: []string{}, + } + + // test wechat message manager returning error + mockMsgManager := new(mockWechatMessageManager) + mockMsgManager.On("Send", message.NewCustomerTextMessage("UserID1", "subject\nmessage")). + Return(errors.New("some error")) + svc.messageManager = mockMsgManager + svc.AddReceivers("UserID1") + ctx := context.Background() + err := svc.Send(ctx, "subject", "message") + assert.NotNil(err) + mockMsgManager.AssertExpectations(t) + + // test success and multiple receivers + mockMsgManager = new(mockWechatMessageManager) + mockMsgManager.On("Send", message.NewCustomerTextMessage("UserID1", "subject\nmessage")). + Return(nil) + mockMsgManager.On("Send", message.NewCustomerTextMessage("UserID2", "subject\nmessage")). + Return(nil) + svc.messageManager = mockMsgManager + svc.AddReceivers("UserID1", "UserID2") + err = svc.Send(ctx, "subject", "message") + assert.Nil(err) + mockMsgManager.AssertExpectations(t) +} From 5dbd63751f01c25885c4120eaafea33b5db5acbc Mon Sep 17 00:00:00 2001 From: gtourkas Date: Sun, 21 Mar 2021 18:09:47 +0200 Subject: [PATCH 03/14] fmt/linter ran in correct order --- Makefile | 2 +- service/wechat/wechat.go | 192 +++++++++++++++++----------------- service/wechat/wechat_test.go | 31 +++--- 3 files changed, 112 insertions(+), 113 deletions(-) diff --git a/Makefile b/Makefile index 73a46a4..4a878f6 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ test: # gofumports and gci all go files fmt: - find . -name '*.go' -not -wholename './vendor/*' | while read -r file; do gofumports -w "$$file"; done + find . -name '*.go' -not -wholename './vendor/*' | while read -r file; do gofumpt -w "$$file"; done gci -w -local github.com/nikoksr/notify . .PHONY: fmt diff --git a/service/wechat/wechat.go b/service/wechat/wechat.go index 46638c7..6a19f63 100644 --- a/service/wechat/wechat.go +++ b/service/wechat/wechat.go @@ -1,58 +1,56 @@ package wechat - import ( - "context" - "fmt" - "github.com/pkg/errors" - "github.com/silenceper/wechat/v2" - "github.com/silenceper/wechat/v2/cache" - "github.com/silenceper/wechat/v2/officialaccount/config" - "github.com/silenceper/wechat/v2/officialaccount/message" - "github.com/silenceper/wechat/v2/util" - "net/http" - "sync" -) + "context" + "fmt" + "net/http" + "sync" + "github.com/pkg/errors" + "github.com/silenceper/wechat/v2" + "github.com/silenceper/wechat/v2/cache" + "github.com/silenceper/wechat/v2/officialaccount/config" + "github.com/silenceper/wechat/v2/officialaccount/message" + "github.com/silenceper/wechat/v2/util" +) // Config is the Service configuration. type Config struct { - AppID string - AppSecret string - Token string - EncodingAESKey string + AppID string + AppSecret string + Token string + EncodingAESKey string } // wechatMessageManager abstracts go-wechat's message.Manager for writing unit tests type wechatMessageManager interface { - Send(msg *message.CustomerMessage) error + Send(msg *message.CustomerMessage) error } // Service encapsulates the WeChat client along with internal state for storing users. type Service struct { - config Config - messageManager wechatMessageManager - userIDs []string + config Config + messageManager wechatMessageManager + userIDs []string } // New returns a new instance of a WeChat notification service. func New(cfg Config) *Service { + wc := wechat.NewWechat() + wcCfg := &config.Config{ + AppID: cfg.AppID, + AppSecret: cfg.AppSecret, + Token: cfg.Token, + EncodingAESKey: cfg.EncodingAESKey, + Cache: cache.NewMemory(), + } - wc := wechat.NewWechat() - wcCfg := &config.Config{ - AppID: cfg.AppID, - AppSecret: cfg.AppSecret, - Token: cfg.Token, - EncodingAESKey: cfg.EncodingAESKey, - Cache: cache.NewMemory(), - } + oa := wc.GetOfficialAccount(wcCfg) - oa := wc.GetOfficialAccount(wcCfg) - - return &Service{ - config: cfg, - messageManager: oa.GetCustomerMessageManager(), - } + return &Service{ + config: cfg, + messageManager: oa.GetCustomerMessageManager(), + } } // WaitForOneOffVerification waits for the verification call from the WeChat backend. @@ -63,84 +61,84 @@ func New(cfg Config) *Service { // // See https://developers.weixin.qq.com/doc/offiaccount/en/Basic_Information/Access_Overview.html func (s *Service) WaitForOneOffVerification( - addr string, - devMode bool, - callback func(r *http.Request, verified bool)) error { + addr string, + devMode bool, + callback func(r *http.Request, verified bool)) error { + srv := &http.Server{Addr: addr} + verificationDone := &sync.WaitGroup{} + verificationDone.Add(1) - srv := &http.Server{Addr: addr} - verificationDone := &sync.WaitGroup{} - verificationDone.Add(1) + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + query := r.URL.Query() - http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - query := r.URL.Query() + echoStr := query.Get("echostr") + if devMode { + if callback != nil { + callback(r, true) + } + _, _ = w.Write([]byte(echoStr)) + // verification done; dev mode + verificationDone.Done() + return + } - echoStr := query.Get("echostr") - if devMode { - if callback != nil { - callback(r, true) - } - w.Write([]byte(echoStr)) - // verification done; dev mode - verificationDone.Done() - return - } else { - // perform signature check - timestamp := query.Get("timestamp") - nonce := query.Get("nonce") - suppliedSignature := query.Get("signature") - computedSignature := util.Signature(s.config.Token, timestamp, nonce) - if suppliedSignature == computedSignature { - if callback != nil { - callback(r, true) - } - w.Write([]byte(echoStr)) - // verification done; prod mode - verificationDone.Done() - return - } - } - // verification not done (keep waiting) - if callback != nil { - callback(r, false) - } - }) + // perform signature check + timestamp := query.Get("timestamp") + nonce := query.Get("nonce") + suppliedSignature := query.Get("signature") + computedSignature := util.Signature(s.config.Token, timestamp, nonce) + if suppliedSignature == computedSignature { + if callback != nil { + callback(r, true) + } + _, _ = w.Write([]byte(echoStr)) + // verification done; prod mode + verificationDone.Done() + return + } - var err error - go func() { - if innerErr := srv.ListenAndServe(); innerErr != http.ErrServerClosed { - err = errors.Wrapf(innerErr, "failed to wait for verification at '%s'", addr) - } - }() + // verification not done (keep waiting) + if callback != nil { + callback(r, false) + } + }) - // wait until verification is done and shutdown the server - verificationDone.Wait() + var err error + go func() { + if innerErr := srv.ListenAndServe(); innerErr != http.ErrServerClosed { + err = errors.Wrapf(innerErr, "failed to start verification listener '%s'", addr) + } + }() - srv.Shutdown(context.TODO()) + // wait until verification is done and shutdown the server + verificationDone.Wait() - return err + if innerErr := srv.Shutdown(context.TODO()); innerErr != nil { + err = errors.Wrap(innerErr, "failed to shutdown verification listerer") + } + + return err } // AddReceivers takes user ids and adds them to the internal users list. The Send method will send // a given message to all those users. func (s *Service) AddReceivers(userIDs ...string) { - s.userIDs = append(s.userIDs, userIDs...) + s.userIDs = append(s.userIDs, userIDs...) } // Send takes a message subject and a message content and sends them to all previously set users. func (s *Service) Send(ctx context.Context, subject, content string) error { + for _, userID := range s.userIDs { + select { + case <-ctx.Done(): + return ctx.Err() + default: + text := fmt.Sprintf("%s\n%s", subject, content) + if err := s.messageManager.Send(message.NewCustomerTextMessage(userID, text)); err != nil { + return errors.Wrapf(err, "failed to send message to WeChat user '%s'", userID) + } + } + } - for _, userID := range s.userIDs { - select { - case <-ctx.Done(): - return ctx.Err() - default: - text := fmt.Sprintf("%s\n%s", subject, content) - if err := s.messageManager.Send(message.NewCustomerTextMessage(userID, text)); err != nil { - return errors.Wrapf(err, "failed to send message to WeChat user '%s'", userID) - } - } - } - - return nil + return nil } - diff --git a/service/wechat/wechat_test.go b/service/wechat/wechat_test.go index 6ecbd52..324153b 100644 --- a/service/wechat/wechat_test.go +++ b/service/wechat/wechat_test.go @@ -1,11 +1,12 @@ package wechat import ( - "context" - "github.com/silenceper/wechat/v2/officialaccount/message" - "github.com/pkg/errors" - "github.com/stretchr/testify/require" + "context" "testing" + + "github.com/pkg/errors" + "github.com/silenceper/wechat/v2/officialaccount/message" + "github.com/stretchr/testify/require" ) func TestAddReceivers(t *testing.T) { @@ -24,29 +25,29 @@ func TestSend(t *testing.T) { assert := require.New(t) svc := &Service{ - userIDs: []string{}, + userIDs: []string{}, } // test wechat message manager returning error mockMsgManager := new(mockWechatMessageManager) - mockMsgManager.On("Send", message.NewCustomerTextMessage("UserID1", "subject\nmessage")). - Return(errors.New("some error")) - svc.messageManager = mockMsgManager + mockMsgManager.On("Send", message.NewCustomerTextMessage("UserID1", "subject\nmessage")). + Return(errors.New("some error")) + svc.messageManager = mockMsgManager svc.AddReceivers("UserID1") ctx := context.Background() err := svc.Send(ctx, "subject", "message") assert.NotNil(err) - mockMsgManager.AssertExpectations(t) + mockMsgManager.AssertExpectations(t) // test success and multiple receivers - mockMsgManager = new(mockWechatMessageManager) - mockMsgManager.On("Send", message.NewCustomerTextMessage("UserID1", "subject\nmessage")). - Return(nil) - mockMsgManager.On("Send", message.NewCustomerTextMessage("UserID2", "subject\nmessage")). - Return(nil) + mockMsgManager = new(mockWechatMessageManager) + mockMsgManager.On("Send", message.NewCustomerTextMessage("UserID1", "subject\nmessage")). + Return(nil) + mockMsgManager.On("Send", message.NewCustomerTextMessage("UserID2", "subject\nmessage")). + Return(nil) svc.messageManager = mockMsgManager svc.AddReceivers("UserID1", "UserID2") err = svc.Send(ctx, "subject", "message") assert.Nil(err) - mockMsgManager.AssertExpectations(t) + mockMsgManager.AssertExpectations(t) } From ebe28ca829dc27dfc47363aa681eae1f192e64f5 Mon Sep 17 00:00:00 2001 From: gtourkas Date: Sun, 21 Mar 2021 18:54:10 +0200 Subject: [PATCH 04/14] feat: added support for WeChat --- README.md | 2 + go.mod | 1 + go.sum | 22 +++ service/wechat/README.md | 83 +++++++++++ service/wechat/img/wechat_sandbox_1.png | Bin 0 -> 39402 bytes service/wechat/img/wechat_sandbox_2.png | Bin 0 -> 69835 bytes service/wechat/img/wechat_usage.png | Bin 0 -> 14915 bytes service/wechat/mock_wechatMessageManager.go | 27 ++++ service/wechat/wechat.go | 144 ++++++++++++++++++++ service/wechat/wechat_test.go | 53 +++++++ 10 files changed, 332 insertions(+) create mode 100644 service/wechat/README.md create mode 100644 service/wechat/img/wechat_sandbox_1.png create mode 100644 service/wechat/img/wechat_sandbox_2.png create mode 100644 service/wechat/img/wechat_usage.png create mode 100644 service/wechat/mock_wechatMessageManager.go create mode 100644 service/wechat/wechat.go create mode 100644 service/wechat/wechat_test.go diff --git a/README.md b/README.md index eef9694..5ba979c 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,7 @@ _ = notifier.Send( - *Telegram* - *Twitter* - *WhatsApp* +- *WeChat* ## Credits @@ -96,6 +97,7 @@ _ = notifier.Send( - 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) +- WeChat: [silenceper/wechat](https://github.com/silenceper/wechat) ## Author diff --git a/go.mod b/go.mod index 31b15d4..f79ed14 100644 --- a/go.mod +++ b/go.mod @@ -30,6 +30,7 @@ require ( github.com/plivo/plivo-go v5.5.1+incompatible github.com/sendgrid/rest v2.6.3+incompatible // indirect github.com/sendgrid/sendgrid-go v3.8.0+incompatible + github.com/silenceper/wechat/v2 v2.0.5 github.com/sirupsen/logrus v1.8.1 // indirect github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect github.com/slack-go/slack v0.8.1 diff --git a/go.sum b/go.sum index 43ab37a..9dff5ac 100644 --- a/go.sum +++ b/go.sum @@ -33,6 +33,8 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.1.2 h1:7Kxqov7uQeP8WUEO0iHz3j9Bh0E1r github.com/aws/aws-sdk-go-v2/service/sts v1.1.2/go.mod h1:zu7rotIY9P4Aoc6ytqLP9jeYrECDHUODB5Gbp+BSHl8= github.com/aws/smithy-go v1.2.0 h1:0PoGBWXkXDIyVdPaZW9gMhaGzj3UOAgTdiVoHuuZAFA= github.com/aws/smithy-go v1.2.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= +github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b h1:L/QXpzIa3pOvUGt1D1lA5KjYhPBAN/3iWdP7xeFS9F0= +github.com/bradfitz/gomemcache v0.0.0-20190913173617-a41fca850d0b/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA= 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/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= @@ -62,6 +64,8 @@ github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojt github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870 h1:E2s37DuLxFhQDg5gKsWoLBOB0n+ZW8s599zru8FJ2/Y= github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= +github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= @@ -83,6 +87,8 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/gomodule/redigo v1.8.1 h1:Abmo0bI7Xf0IhdIPc7HZQzZcShdnmxeoVuDDtIQp8N8= +github.com/gomodule/redigo v1.8.1/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= 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= @@ -101,6 +107,8 @@ github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoA 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/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw= +github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= @@ -110,6 +118,7 @@ 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/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 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= @@ -130,6 +139,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ 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/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy/FJl/rCYT0+EuS8+Z0z4= +github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= 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/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= @@ -155,6 +166,9 @@ github.com/sendgrid/rest v2.6.3+incompatible h1:h/uruXAzKxVyDDIQX/MkQI73p/gsdpEn github.com/sendgrid/rest v2.6.3+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/silenceper/wechat/v2 v2.0.5 h1:yBOeTMiMAzCAvmhR14ADMlrRrR3oOqmoz7I/bus7bTw= +github.com/silenceper/wechat/v2 v2.0.5/go.mod h1:hksYXWXGl7/E6TQojFNgxv8ouTF9CPPjfvWWJouJJGs= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/skip2/go-qrcode v0.0.0-20190110000554-dc11ecdae0a9/go.mod h1:PLPIyL7ikehBD1OAjmKKiOEhbvWyHGaNDjquXMcYABo= @@ -164,11 +178,14 @@ github.com/slack-go/slack v0.8.1 h1:NqGXuzni8Is3EJWmsuMuBiCCPbWOlBgTKPvdlwS3Huk= github.com/slack-go/slack v0.8.1/go.mod h1:FGqNzJBmxIsZURAxh2a8D21AnOVvvXZvGligs4npPUM= github.com/sony/sonyflake v1.0.0 h1:MpU6Ro7tfXwgn2l5eluf9xQvQJDROTBImNCfRXn/YeM= github.com/sony/sonyflake v1.0.0/go.mod h1:Jv3cfhf/UFtolOTTRd3q4Nl6ENqM+KfyZ5PseKfZGF4= +github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= 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= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -177,6 +194,7 @@ github.com/technoweenie/multipartstreamer v1.0.1/go.mod h1:jNVxdtShOxzAsukZwTSw6 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-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b h1:wSOdpTq0/eI46Ez/LkDwIsAKA71YP2SRKBODiRWM0as= golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= @@ -207,6 +225,7 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h 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-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -255,8 +274,11 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 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/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/h2non/gock.v1 v1.0.15 h1:SzLqcIlb/fDfg7UvukMpNcWsu7sI5tWwL+KCATZqks0= +gopkg.in/h2non/gock.v1 v1.0.15/go.mod h1:sX4zAkdYX1TRGJ2JY156cFspQn4yRWn6p9EMdODlynE= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/service/wechat/README.md b/service/wechat/README.md new file mode 100644 index 0000000..9961f0d --- /dev/null +++ b/service/wechat/README.md @@ -0,0 +1,83 @@ +# WeChat + +## Prerequisites + +To use the service you need to apply for a [WeChat Official Account](https://mp.weixin.qq.com). +Application approval is a manual process and might take a while. In the meantime, you +can test your code using the [sandbox](https://developers.weixin.qq.com/sandbox). + +You need the following configuration information to sent out text messages with an Official Account: + +1. AppID +2. AppSecret +3. Token +4. EncodingAESKey +5. Verification URL + +The `AppID` and `AppSecret` are provided to you by WeChat. The `Token`, `EncodingAESKey` and +the Verifications URL, you set yourself and are needed by the authentication method. More on +this [here](https://developers.weixin.qq.com/doc/offiaccount/en/Basic_Information/Access_Overview.html). + +## Getting Started + +Until your application is approved, sign in to the sandbox to get an `AppID`, an `AppSecret` and +set the `Token` and the Verification URL. Typically, you need a service like [ngrok](https://ngrok.com/) +for the latter. You don't need to/cannot set the `EncodingAESKey`, because it's not required in the +sandbox environment: + +![wechat_sandbox_1.png](img/wechat_sandbox_1.png) + +You also need a user subscribed to your Official Account. You can use your own: + +![wechat_sandbox_2.png](img/wechat_sandbox_2.png) + +## Usage + + +```go +package main + +import ( + "log" + "context" + "fmt" + "net/http" + "github.com/nikoksr/notify" + "github.com/nikoksr/notify/service/wechat" +) + +func main() { + + wechatSvc := wechat.New(wechat.Config{ + AppID: "abcdefghi", + AppSecret: "jklmnopqr", + Token: "mytoken", + EncodingAESKey: "IGNORED-IN-SANDBOX", + }) + + // do this only once, or when settings are updated + devMode := true + wechatSvc.WaitForOneOffVerification(":7999", devMode, func(r *http.Request, verified bool) { + if !verified { + fmt.Println("unknown or failed verification call") + } else { + fmt.Println("verification call done") + } + }) + + wechatSvc.AddReceivers("some-user-openid") + + notifier := notify.New() + notifier.UseServices(wechatSvc) + + err := notifier.Send(context.Background(), "subject", "message") + if err != nil { + log.Fatalf("notifier.Send() failed: %s", err.Error()) + } + + log.Println("notification sent") +} +``` + +![wechat_usage.png](img/wechat_usage.png) + diff --git a/service/wechat/img/wechat_sandbox_1.png b/service/wechat/img/wechat_sandbox_1.png new file mode 100644 index 0000000000000000000000000000000000000000..b2b11fd61fb602d53ca2ee05902ce2e4c795aa8d GIT binary patch literal 39402 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 Tq{%fy0Y9qB8h6SR&4T_PJNI#N literal 0 HcmV?d00001 diff --git a/service/wechat/img/wechat_sandbox_2.png b/service/wechat/img/wechat_sandbox_2.png new file mode 100644 index 0000000000000000000000000000000000000000..cef296a9bf4c09c510a09a886924adbdef9b38e0 GIT binary patch literal 69835 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%0Af$)<&In=T%Ghx9KxU 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 QnnNj!^vsYIR~#e%2c4ABIRF3v literal 0 HcmV?d00001 diff --git a/service/wechat/mock_wechatMessageManager.go b/service/wechat/mock_wechatMessageManager.go new file mode 100644 index 0000000..975964d --- /dev/null +++ b/service/wechat/mock_wechatMessageManager.go @@ -0,0 +1,27 @@ +// Code generated by mockery 2.7.4. DO NOT EDIT. + +package wechat + +import ( + message "github.com/silenceper/wechat/v2/officialaccount/message" + mock "github.com/stretchr/testify/mock" +) + +// mockWechatMessageManager is an autogenerated mock type for the wechatMessageManager type +type mockWechatMessageManager struct { + mock.Mock +} + +// Send provides a mock function with given fields: msg +func (_m *mockWechatMessageManager) Send(msg *message.CustomerMessage) error { + ret := _m.Called(msg) + + var r0 error + if rf, ok := ret.Get(0).(func(*message.CustomerMessage) error); ok { + r0 = rf(msg) + } else { + r0 = ret.Error(0) + } + + return r0 +} diff --git a/service/wechat/wechat.go b/service/wechat/wechat.go new file mode 100644 index 0000000..6a19f63 --- /dev/null +++ b/service/wechat/wechat.go @@ -0,0 +1,144 @@ +package wechat + +import ( + "context" + "fmt" + "net/http" + "sync" + + "github.com/pkg/errors" + "github.com/silenceper/wechat/v2" + "github.com/silenceper/wechat/v2/cache" + "github.com/silenceper/wechat/v2/officialaccount/config" + "github.com/silenceper/wechat/v2/officialaccount/message" + "github.com/silenceper/wechat/v2/util" +) + +// Config is the Service configuration. +type Config struct { + AppID string + AppSecret string + Token string + EncodingAESKey string +} + +// wechatMessageManager abstracts go-wechat's message.Manager for writing unit tests +type wechatMessageManager interface { + Send(msg *message.CustomerMessage) error +} + +// Service encapsulates the WeChat client along with internal state for storing users. +type Service struct { + config Config + messageManager wechatMessageManager + userIDs []string +} + +// New returns a new instance of a WeChat notification service. +func New(cfg Config) *Service { + wc := wechat.NewWechat() + wcCfg := &config.Config{ + AppID: cfg.AppID, + AppSecret: cfg.AppSecret, + Token: cfg.Token, + EncodingAESKey: cfg.EncodingAESKey, + Cache: cache.NewMemory(), + } + + oa := wc.GetOfficialAccount(wcCfg) + + return &Service{ + config: cfg, + messageManager: oa.GetCustomerMessageManager(), + } +} + +// WaitForOneOffVerification waits for the verification call from the WeChat backend. +// +// Should be running when (re-)applying settings in wechat configuration. +// +// Set devMode to true when using the sandbox. +// +// See https://developers.weixin.qq.com/doc/offiaccount/en/Basic_Information/Access_Overview.html +func (s *Service) WaitForOneOffVerification( + addr string, + devMode bool, + callback func(r *http.Request, verified bool)) error { + srv := &http.Server{Addr: addr} + verificationDone := &sync.WaitGroup{} + verificationDone.Add(1) + + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + query := r.URL.Query() + + echoStr := query.Get("echostr") + if devMode { + if callback != nil { + callback(r, true) + } + _, _ = w.Write([]byte(echoStr)) + // verification done; dev mode + verificationDone.Done() + return + } + + // perform signature check + timestamp := query.Get("timestamp") + nonce := query.Get("nonce") + suppliedSignature := query.Get("signature") + computedSignature := util.Signature(s.config.Token, timestamp, nonce) + if suppliedSignature == computedSignature { + if callback != nil { + callback(r, true) + } + _, _ = w.Write([]byte(echoStr)) + // verification done; prod mode + verificationDone.Done() + return + } + + // verification not done (keep waiting) + if callback != nil { + callback(r, false) + } + }) + + var err error + go func() { + if innerErr := srv.ListenAndServe(); innerErr != http.ErrServerClosed { + err = errors.Wrapf(innerErr, "failed to start verification listener '%s'", addr) + } + }() + + // wait until verification is done and shutdown the server + verificationDone.Wait() + + if innerErr := srv.Shutdown(context.TODO()); innerErr != nil { + err = errors.Wrap(innerErr, "failed to shutdown verification listerer") + } + + return err +} + +// AddReceivers takes user ids and adds them to the internal users list. The Send method will send +// a given message to all those users. +func (s *Service) AddReceivers(userIDs ...string) { + s.userIDs = append(s.userIDs, userIDs...) +} + +// Send takes a message subject and a message content and sends them to all previously set users. +func (s *Service) Send(ctx context.Context, subject, content string) error { + for _, userID := range s.userIDs { + select { + case <-ctx.Done(): + return ctx.Err() + default: + text := fmt.Sprintf("%s\n%s", subject, content) + if err := s.messageManager.Send(message.NewCustomerTextMessage(userID, text)); err != nil { + return errors.Wrapf(err, "failed to send message to WeChat user '%s'", userID) + } + } + } + + return nil +} diff --git a/service/wechat/wechat_test.go b/service/wechat/wechat_test.go new file mode 100644 index 0000000..324153b --- /dev/null +++ b/service/wechat/wechat_test.go @@ -0,0 +1,53 @@ +package wechat + +import ( + "context" + "testing" + + "github.com/pkg/errors" + "github.com/silenceper/wechat/v2/officialaccount/message" + "github.com/stretchr/testify/require" +) + +func TestAddReceivers(t *testing.T) { + assert := require.New(t) + + svc := &Service{ + userIDs: []string{}, + } + userIDs := []string{"User1ID", "User2ID", "User3ID"} + svc.AddReceivers(userIDs...) + + assert.Equal(svc.userIDs, userIDs) +} + +func TestSend(t *testing.T) { + assert := require.New(t) + + svc := &Service{ + userIDs: []string{}, + } + + // test wechat message manager returning error + mockMsgManager := new(mockWechatMessageManager) + mockMsgManager.On("Send", message.NewCustomerTextMessage("UserID1", "subject\nmessage")). + Return(errors.New("some error")) + svc.messageManager = mockMsgManager + svc.AddReceivers("UserID1") + ctx := context.Background() + err := svc.Send(ctx, "subject", "message") + assert.NotNil(err) + mockMsgManager.AssertExpectations(t) + + // test success and multiple receivers + mockMsgManager = new(mockWechatMessageManager) + mockMsgManager.On("Send", message.NewCustomerTextMessage("UserID1", "subject\nmessage")). + Return(nil) + mockMsgManager.On("Send", message.NewCustomerTextMessage("UserID2", "subject\nmessage")). + Return(nil) + svc.messageManager = mockMsgManager + svc.AddReceivers("UserID1", "UserID2") + err = svc.Send(ctx, "subject", "message") + assert.Nil(err) + mockMsgManager.AssertExpectations(t) +} From 66d7a877f238f2172d5fc36c538a96acd033ae2e Mon Sep 17 00:00:00 2001 From: George Tourkas Date: Thu, 15 Apr 2021 10:52:22 +0300 Subject: [PATCH 05/14] using notify's style in error checking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Niko Köser --- service/wechat/wechat.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/service/wechat/wechat.go b/service/wechat/wechat.go index 6a19f63..43f5a3a 100644 --- a/service/wechat/wechat.go +++ b/service/wechat/wechat.go @@ -134,7 +134,8 @@ func (s *Service) Send(ctx context.Context, subject, content string) error { return ctx.Err() default: text := fmt.Sprintf("%s\n%s", subject, content) - if err := s.messageManager.Send(message.NewCustomerTextMessage(userID, text)); err != nil { + err := s.messageManager.Send(message.NewCustomerTextMessage(userID, text)) + if err != nil { return errors.Wrapf(err, "failed to send message to WeChat user '%s'", userID) } } From 4167bec54725cbe19a0dee9a00991b4345f832bc Mon Sep 17 00:00:00 2001 From: George Tourkas Date: Thu, 15 Apr 2021 10:52:58 +0300 Subject: [PATCH 06/14] using notify's style in object creation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Niko Köser --- service/wechat/wechat.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/service/wechat/wechat.go b/service/wechat/wechat.go index 43f5a3a..55150eb 100644 --- a/service/wechat/wechat.go +++ b/service/wechat/wechat.go @@ -45,7 +45,7 @@ func New(cfg Config) *Service { Cache: cache.NewMemory(), } - oa := wc.GetOfficialAccount(wcCfg) + account := wc.GetOfficialAccount(wcCfg) return &Service{ config: cfg, From 247c1861b5f1897abf7370ddc37ab7ba84580e24 Mon Sep 17 00:00:00 2001 From: George Tourkas Date: Thu, 15 Apr 2021 10:53:15 +0300 Subject: [PATCH 07/14] using notify's style in object creation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Niko Köser --- service/wechat/wechat.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/service/wechat/wechat.go b/service/wechat/wechat.go index 55150eb..57d3148 100644 --- a/service/wechat/wechat.go +++ b/service/wechat/wechat.go @@ -37,7 +37,7 @@ type Service struct { // New returns a new instance of a WeChat notification service. func New(cfg Config) *Service { wc := wechat.NewWechat() - wcCfg := &config.Config{ + clientConfig := &config.Config{ AppID: cfg.AppID, AppSecret: cfg.AppSecret, Token: cfg.Token, From 8898e786b0f1d84f14f0275c96e4b48ff5c70ce3 Mon Sep 17 00:00:00 2001 From: George Tourkas Date: Thu, 15 Apr 2021 10:53:25 +0300 Subject: [PATCH 08/14] using notify's style in object creation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Niko Köser --- service/wechat/wechat.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/service/wechat/wechat.go b/service/wechat/wechat.go index 57d3148..b94b309 100644 --- a/service/wechat/wechat.go +++ b/service/wechat/wechat.go @@ -36,7 +36,7 @@ type Service struct { // New returns a new instance of a WeChat notification service. func New(cfg Config) *Service { - wc := wechat.NewWechat() + client := wechat.NewWechat() clientConfig := &config.Config{ AppID: cfg.AppID, AppSecret: cfg.AppSecret, From 51184dc76878c4a3f5da41055ed1cc249489d31d Mon Sep 17 00:00:00 2001 From: George Tourkas Date: Thu, 15 Apr 2021 10:53:41 +0300 Subject: [PATCH 09/14] Alphabetical order in README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Niko Köser --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5ba979c..c11e25b 100644 --- a/README.md +++ b/README.md @@ -96,8 +96,8 @@ _ = 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) - WeChat: [silenceper/wechat](https://github.com/silenceper/wechat) +- WhatsApp: [Rhymen/go-whatsapp](https://github.com/Rhymen/go-whatsapp) ## Author From 2b791ae0ba89216d956edcde2dcbbcd9892256d2 Mon Sep 17 00:00:00 2001 From: George Tourkas Date: Thu, 15 Apr 2021 11:43:19 +0300 Subject: [PATCH 10/14] using configured cache MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Niko Köser --- service/wechat/wechat.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/service/wechat/wechat.go b/service/wechat/wechat.go index b94b309..669149c 100644 --- a/service/wechat/wechat.go +++ b/service/wechat/wechat.go @@ -42,7 +42,7 @@ func New(cfg Config) *Service { AppSecret: cfg.AppSecret, Token: cfg.Token, EncodingAESKey: cfg.EncodingAESKey, - Cache: cache.NewMemory(), + Cache: cfg.Cache, } account := wc.GetOfficialAccount(wcCfg) From da3ffb0a7dd380e5d81ae8e1f63ad37dbb03cb6e Mon Sep 17 00:00:00 2001 From: gtourkas Date: Thu, 15 Apr 2021 12:12:28 +0300 Subject: [PATCH 11/14] build-passing commit --- service/wechat/README.md | 61 ++++++++++++++++++++-------------------- service/wechat/wechat.go | 11 ++++---- 2 files changed, 37 insertions(+), 35 deletions(-) diff --git a/service/wechat/README.md b/service/wechat/README.md index 9961f0d..0c285b5 100644 --- a/service/wechat/README.md +++ b/service/wechat/README.md @@ -33,49 +33,50 @@ You also need a user subscribed to your Official Account. You can use your own: ## Usage - ```go package main import ( - "log" - "context" - "fmt" - "net/http" - "github.com/nikoksr/notify" - "github.com/nikoksr/notify/service/wechat" + "github.com/silenceper/wechat/v2/cache" + "log" + "context" + "fmt" + "net/http" + "github.com/nikoksr/notify" + "github.com/nikoksr/notify/service/wechat" ) func main() { - wechatSvc := wechat.New(wechat.Config{ - AppID: "abcdefghi", - AppSecret: "jklmnopqr", - Token: "mytoken", - EncodingAESKey: "IGNORED-IN-SANDBOX", - }) + wechatSvc := wechat.New(&wechat.Config{ + AppID: "abcdefghi", + AppSecret: "jklmnopqr", + Token: "mytoken", + EncodingAESKey: "IGNORED-IN-SANDBOX", + Cache: cache.NewMemory(), + }) - // do this only once, or when settings are updated - devMode := true - wechatSvc.WaitForOneOffVerification(":7999", devMode, func(r *http.Request, verified bool) { - if !verified { - fmt.Println("unknown or failed verification call") - } else { - fmt.Println("verification call done") - } - }) + // do this only once, or when settings are updated + devMode := true + wechatSvc.WaitForOneOffVerification(":7999", devMode, func(r *http.Request, verified bool) { + if !verified { + fmt.Println("unknown or failed verification call") + } else { + fmt.Println("verification call done") + } + }) - wechatSvc.AddReceivers("some-user-openid") + wechatSvc.AddReceivers("some-user-openid") - notifier := notify.New() - notifier.UseServices(wechatSvc) + notifier := notify.New() + notifier.UseServices(wechatSvc) - err := notifier.Send(context.Background(), "subject", "message") - if err != nil { - log.Fatalf("notifier.Send() failed: %s", err.Error()) - } + err := notifier.Send(context.Background(), "subject", "message") + if err != nil { + log.Fatalf("notifier.Send() failed: %s", err.Error()) + } - log.Println("notification sent") + log.Println("notification sent") } ``` diff --git a/service/wechat/wechat.go b/service/wechat/wechat.go index 669149c..d38496a 100644 --- a/service/wechat/wechat.go +++ b/service/wechat/wechat.go @@ -20,6 +20,7 @@ type Config struct { AppSecret string Token string EncodingAESKey string + Cache cache.Cache } // wechatMessageManager abstracts go-wechat's message.Manager for writing unit tests @@ -29,15 +30,15 @@ type wechatMessageManager interface { // Service encapsulates the WeChat client along with internal state for storing users. type Service struct { - config Config + config *Config messageManager wechatMessageManager userIDs []string } // New returns a new instance of a WeChat notification service. -func New(cfg Config) *Service { - client := wechat.NewWechat() - clientConfig := &config.Config{ +func New(cfg *Config) *Service { + wc := wechat.NewWechat() + wcCfg := &config.Config{ AppID: cfg.AppID, AppSecret: cfg.AppSecret, Token: cfg.Token, @@ -45,7 +46,7 @@ func New(cfg Config) *Service { Cache: cfg.Cache, } - account := wc.GetOfficialAccount(wcCfg) + oa := wc.GetOfficialAccount(wcCfg) return &Service{ config: cfg, From 28ee79a6bc83774c9afc141289a5f825c0a5c7ff Mon Sep 17 00:00:00 2001 From: George Tourkas Date: Fri, 23 Apr 2021 21:05:09 +0300 Subject: [PATCH 12/14] renaming callback to clarify intent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Niko Köser --- service/wechat/wechat.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/service/wechat/wechat.go b/service/wechat/wechat.go index d38496a..af4e599 100644 --- a/service/wechat/wechat.go +++ b/service/wechat/wechat.go @@ -14,6 +14,8 @@ import ( "github.com/silenceper/wechat/v2/util" ) +type verificationCallbackFunc func(r *http.Request, verified bool) + // Config is the Service configuration. type Config struct { AppID string From e874e41a36587a90c328d4826a7c1b434a77540f Mon Sep 17 00:00:00 2001 From: George Tourkas Date: Fri, 23 Apr 2021 21:05:36 +0300 Subject: [PATCH 13/14] renaming callback to clarify intent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Niko Köser --- service/wechat/wechat.go | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/service/wechat/wechat.go b/service/wechat/wechat.go index af4e599..79968b8 100644 --- a/service/wechat/wechat.go +++ b/service/wechat/wechat.go @@ -63,11 +63,8 @@ func New(cfg *Config) *Service { // Set devMode to true when using the sandbox. // // See https://developers.weixin.qq.com/doc/offiaccount/en/Basic_Information/Access_Overview.html -func (s *Service) WaitForOneOffVerification( - addr string, - devMode bool, - callback func(r *http.Request, verified bool)) error { - srv := &http.Server{Addr: addr} +func (s *Service) WaitForOneOffVerification(serverURL string, devMode bool, callback verificationCallbackFunc) error { + srv := &http.Server{Addr: serverURL} verificationDone := &sync.WaitGroup{} verificationDone.Add(1) From 43d3c4e5c01fca393053b5616b6d7342b9acb8cb Mon Sep 17 00:00:00 2001 From: gtourkas Date: Fri, 23 Apr 2021 21:09:02 +0300 Subject: [PATCH 14/14] build-passing commit --- service/wechat/wechat.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/service/wechat/wechat.go b/service/wechat/wechat.go index 79968b8..8009b91 100644 --- a/service/wechat/wechat.go +++ b/service/wechat/wechat.go @@ -106,7 +106,7 @@ func (s *Service) WaitForOneOffVerification(serverURL string, devMode bool, call var err error go func() { if innerErr := srv.ListenAndServe(); innerErr != http.ErrServerClosed { - err = errors.Wrapf(innerErr, "failed to start verification listener '%s'", addr) + err = errors.Wrapf(innerErr, "failed to start verification listener '%s'", serverURL) } }()