Skip to content

Commit

Permalink
Merge pull request #272 from svaloumas/feature/add-fcm-service
Browse files Browse the repository at this point in the history
  • Loading branch information
nikoksr committed May 9, 2022
2 parents 4564e02 + 44eb89d commit d448ef6
Show file tree
Hide file tree
Showing 8 changed files with 478 additions and 33 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ Yes, please! Contributions of all kinds are very welcome! Feel free to check our
| [DingTalk](https://www.dingtalk.com) | [service/dinding](service/dingding) | [blinkbean/dingtalk](https://github.com/blinkbean/dingtalk) |
| [Discord](https://discord.com) | [service/discord](service/discord) | [bwmarrin/discordgo](https://github.com/bwmarrin/discordgo) |
| [Email](https://wikipedia.org/wiki/Email) | [service/mail](service/mail) | [jordan-wright/email](https://github.com/jordan-wright/email) |
| [Firebase Cloud Messaging](https://firebase.google.com/docs/cloud-messaging) | [service/fcm](service/fcm) | [appleboy/go-fcm](https://github.com/appleboy/go-fcm) |
| [Line](https://line.me) | [service/line](service/line) | [line/line-bot-sdk-go](https://github.com/line/line-bot-sdk-go) |
| [Line Notify](https://notify-bot.line.me) | [service/line](service/line) | [utahta/go-linenotify](https://github.com/utahta/go-linenotify) |
| [Mailgun](https://www.mailgun.com) | [service/mailgun](service/mailgun) | [mailgun/mailgun-go](https://github.com/mailgun/mailgun-go) |
Expand Down
5 changes: 4 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@ require (
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
)

require github.com/google/go-cmp v0.5.8
require (
github.com/appleboy/go-fcm v0.1.5
github.com/google/go-cmp v0.5.8
)

require (
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.4 // indirect
Expand Down
34 changes: 2 additions & 32 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -48,54 +48,32 @@ github.com/RocketChat/Rocket.Chat.Go.SDK v0.0.0-20210506200512-3b3352a919f0 h1:1
github.com/RocketChat/Rocket.Chat.Go.SDK v0.0.0-20210506200512-3b3352a919f0/go.mod h1:rjP7sIipbZcagro/6TCk6X0ZeFT2eyudH5+fve/cbBA=
github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/appleboy/go-fcm v0.1.5 h1:fKbcZf/7vwGsvDkcop8a+kCHnK+tt4wXX0X7uEzwI6E=
github.com/appleboy/go-fcm v0.1.5/go.mod h1:MSxZ4LqGRsnywOjnlXJXMqbjZrG4vf+0oHitfC9HRH0=
github.com/atc0005/go-teams-notify/v2 v2.6.1 h1:t22ybzQuaQs4UJe4ceF5VYGsPhs6ir3nZOId/FBy6Go=
github.com/atc0005/go-teams-notify/v2 v2.6.1/go.mod h1:xo6GejLDHn3tWBA181F8LrllIL0xC1uRsRxq7YNXaaY=
github.com/aws/aws-sdk-go-v2 v1.16.2 h1:fqlCk6Iy3bnCumtrLz9r3mJ/2gUT0pJ0wLFVIdWh+JA=
github.com/aws/aws-sdk-go-v2 v1.16.2/go.mod h1:ytwTPBG6fXTZLxxeeCCWj2/EMYp/xDUgX+OET6TLNNU=
github.com/aws/aws-sdk-go-v2 v1.16.3 h1:0W1TSJ7O6OzwuEvIXAtJGvOeQ0SGAhcpxPN2/NK5EhM=
github.com/aws/aws-sdk-go-v2 v1.16.3/go.mod h1:ytwTPBG6fXTZLxxeeCCWj2/EMYp/xDUgX+OET6TLNNU=
github.com/aws/aws-sdk-go-v2/config v1.15.3 h1:5AlQD0jhVXlGzwo+VORKiUuogkG7pQcLJNzIzK7eodw=
github.com/aws/aws-sdk-go-v2/config v1.15.3/go.mod h1:9YL3v07Xc/ohTsxFXzan9ZpFpdTOFl4X65BAKYaz8jg=
github.com/aws/aws-sdk-go-v2/config v1.15.4 h1:P4mesY1hYUxru4f9SU0XxNKXmzfxsD0FtMIPRBjkH7Q=
github.com/aws/aws-sdk-go-v2/config v1.15.4/go.mod h1:ZijHHh0xd/A+ZY53az0qzC5tT46kt4JVCePf2NX9Lk4=
github.com/aws/aws-sdk-go-v2/credentials v1.11.2 h1:RQQ5fzclAKJyY5TvF+fkjJEwzK4hnxQCLOu5JXzDmQo=
github.com/aws/aws-sdk-go-v2/credentials v1.11.2/go.mod h1:j8YsY9TXTm31k4eFhspiQicfXPLZ0gYXA50i4gxPE8g=
github.com/aws/aws-sdk-go-v2/credentials v1.12.0 h1:4R/NqlcRFSkR0wxOhgHi+agGpbEr5qMCjn7VqUIJY+E=
github.com/aws/aws-sdk-go-v2/credentials v1.12.0/go.mod h1:9YWk7VW+eyKsoIL6/CljkTrNVWBSK9pkqOPUuijid4A=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.3 h1:LWPg5zjHV9oz/myQr4wMs0gi4CjnDN/ILmyZUFYXZsU=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.3/go.mod h1:uk1vhHHERfSVCUnqSqz8O48LBYDSC+k6brng09jcMOk=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.4 h1:FP8gquGeGHHdfY6G5llaMQDF+HAf20VKc8opRwmjf04=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.4/go.mod h1:u/s5/Z+ohUQOPXl00m2yJVyioWDECsbpXTQlaqSlufc=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.9 h1:onz/VaaxZ7Z4V+WIN9Txly9XLTmoOh1oJ8XcAC3pako=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.9/go.mod h1:AnVH5pvai0pAF4lXRq0bmhbes1u9R8wTE+g+183bZNM=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.10 h1:uFWgo6mGJI1n17nbcvSc6fxVuR3xLNqvXt12JCnEcT8=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.10/go.mod h1:F+EZtuIwjlv35kRJPyBGcsA4f7bnSoz15zOQ2lJq1Z4=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.3 h1:9stUQR/u2KXU6HkFJYlqnZEjBnbgrVbG6I5HN09xZh0=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.3/go.mod h1:ssOhaLpRlh88H3UmEcsBoVKq309quMvm3Ds8e9d4eJM=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.4 h1:cnsvEKSoHN4oAN7spMMr0zhEW2MHnhAVpmqQg8E6UcM=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.4/go.mod h1:8glyUqVIM4AmeenIsPo0oVh3+NUwnsQml2OFupfQW+0=
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.10 h1:by9P+oy3P/CwggN4ClnW2D4oL91QV7pBzBICi1chZvQ=
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.10/go.mod h1:8DcYQcz0+ZJaSxANlHIsbbi6S+zMwjwdDqwW3r9AzaE=
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.11 h1:6cZRymlLEIlDTEB0+5+An6Zj1CKt6rSE69tOmFeu1nk=
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.11/go.mod h1:0MR+sS1b/yxsfAPvAESrw8NfwUoxMinDyw6EYR9BS2U=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.3 h1:Gh1Gpyh01Yvn7ilO/b/hr01WgNpaszfbKMUgqM186xQ=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.3/go.mod h1:wlY6SVjuwvh3TVRpTqdy4I1JpBFLX4UGeKZdWntaocw=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.4 h1:b16QW0XWl0jWjLABFc1A+uh145Oqv+xDcObNk0iQgUk=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.4/go.mod h1:uKkN7qmSIsNJVyMtxNQoCEYMvFEXbOg9fwCJPdfp2u8=
github.com/aws/aws-sdk-go-v2/service/ses v1.14.3 h1:SNFIa2NvkZ46nkkUS6DlTjgQItjjYCjrh+UCpD5mF4Y=
github.com/aws/aws-sdk-go-v2/service/ses v1.14.3/go.mod h1:VPOcsfmvq+FyaT47LT8ReFGD0NXnPEbcJGbxm7mC3yg=
github.com/aws/aws-sdk-go-v2/service/ses v1.14.4 h1:ke4Kp6GolWjw9xTtE9PQPw+jN/zcBi9pcunAh9apAW8=
github.com/aws/aws-sdk-go-v2/service/ses v1.14.4/go.mod h1:YPeSVmu3+2iUSCUIspo+vvFe3LKCIW8x8Dxnuadh6AU=
github.com/aws/aws-sdk-go-v2/service/sns v1.17.4 h1:7TdmoJJBwLFyakXjfrGztejwY5Ie1JEto7YFfznCmAw=
github.com/aws/aws-sdk-go-v2/service/sns v1.17.4/go.mod h1:kElt+uCcXxcqFyc+bQqZPFD9DME/eC6oHBXvFzQ9Bcw=
github.com/aws/aws-sdk-go-v2/service/sns v1.17.5 h1:g04C27W8hBB+8T4q7t3TAF4i9ZbTYLr3i9bhFAERIzM=
github.com/aws/aws-sdk-go-v2/service/sns v1.17.5/go.mod h1:U7g4gHRcOB0H1VYv2yNzAOmGZS8dTEUZ/HkSSO6Pggg=
github.com/aws/aws-sdk-go-v2/service/sso v1.11.3 h1:frW4ikGcxfAEDfmQqWgMLp+F1n4nRo9sF39OcIb5BkQ=
github.com/aws/aws-sdk-go-v2/service/sso v1.11.3/go.mod h1:7UQ/e69kU7LDPtY40OyoHYgRmgfGM4mgsLYtcObdveU=
github.com/aws/aws-sdk-go-v2/service/sso v1.11.4 h1:Uw5wBybFQ1UeA9ts0Y07gbv0ncZnIAyw858tDW0NP2o=
github.com/aws/aws-sdk-go-v2/service/sso v1.11.4/go.mod h1:cPDwJwsP4Kff9mldCXAmddjJL6JGQqtA3Mzer2zyr88=
github.com/aws/aws-sdk-go-v2/service/sts v1.16.3 h1:cJGRyzCSVwZC7zZZ1xbx9m32UnrKydRYhOvcD1NYP9Q=
github.com/aws/aws-sdk-go-v2/service/sts v1.16.3/go.mod h1:bfBj0iVmsUyUg4weDB4NxktD9rDGeKSVWnjTnwbx9b8=
github.com/aws/aws-sdk-go-v2/service/sts v1.16.4 h1:+xtV90n3abQmgzk1pS++FdxZTrPEDgQng6e4/56WR2A=
github.com/aws/aws-sdk-go-v2/service/sts v1.16.4/go.mod h1:lfSYenAXtavyX2A1LsViglqlG9eEFYxNryTZS5rn3QE=
github.com/aws/smithy-go v1.11.2 h1:eG/N+CcUMAvsdffgMvjMKwfyDzIkjM6pfxMJ8Mzc6mE=
Expand All @@ -122,8 +100,6 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ=
github.com/dghubble/go-twitter v0.0.0-20220413154426-14d8abde2e80 h1:pq636dbda5rkQyrFUOeADrGeKQGlCHBvcpGKqsVZ4ZQ=
github.com/dghubble/go-twitter v0.0.0-20220413154426-14d8abde2e80/go.mod h1:7vl8uM4He/dTj20TDHBwvkKEBPUm60re8htWb7YRo+Q=
github.com/dghubble/go-twitter v0.0.0-20220428155120-ee736133298b h1:jNYx4ME9CcTvFinBz3T8p/5nZwhggUA7iXaWH0t2ffo=
github.com/dghubble/go-twitter v0.0.0-20220428155120-ee736133298b/go.mod h1:rJg8kU8GQWeH9lutdlROcjIGIgLab0tZfn7jgZ6FeBU=
github.com/dghubble/oauth1 v0.7.1 h1:JjbOVSVVkms9A4h/sTQy5Jb2nFuAAVb2qVYgenJPyrE=
Expand Down Expand Up @@ -194,7 +170,6 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
Expand Down Expand Up @@ -277,8 +252,6 @@ github.com/pkg/errors v0.8.1-0.20161029093637-248dadf4e906/go.mod h1:bwawxfHBFNV
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/plivo/plivo-go/v7 v7.8.0 h1:qa5SXRduZEgAYb6Uv2ZeYjm1ZnlQzCprS0xjHxB8EAU=
github.com/plivo/plivo-go/v7 v7.8.0/go.mod h1:Jw1e16x0WjW334botVeKQT4hcMXMN55r4HH0XoGsR6Q=
github.com/plivo/plivo-go/v7 v7.9.0 h1:wpSG28GoygIZ+kaYKYGmlyF6dihT1wbNAUmE5y72Kh8=
github.com/plivo/plivo-go/v7 v7.9.0/go.mod h1:Jw1e16x0WjW334botVeKQT4hcMXMN55r4HH0XoGsR6Q=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
Expand All @@ -296,8 +269,6 @@ github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic
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.10.2 h1:KMN/h2sgUninHXvQI8PrR/PHBUuWp2NPvz2Kr66tki4=
github.com/slack-go/slack v0.10.2/go.mod h1:5FLdBRv7VW/d9EBxx/eEktOptWygbA9K2QK/KW7ds1s=
github.com/slack-go/slack v0.10.3 h1:kKYwlKY73AfSrtAk9UHWCXXfitudkDztNI9GYBviLxw=
github.com/slack-go/slack v0.10.3/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw=
github.com/sony/sonyflake v1.0.0 h1:MpU6Ro7tfXwgn2l5eluf9xQvQJDROTBImNCfRXn/YeM=
Expand Down Expand Up @@ -520,7 +491,6 @@ golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
Expand Down
57 changes: 57 additions & 0 deletions service/fcm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Firebase Cloud Messaging (FCM)

[![go.dev reference](https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white&style=flat)](https://pkg.go.dev/github.com/nikoksr/notify/service/fcm)

## Prerequisites

Navigate to Firebase [console](https://console.firebase.google.com/), login with your Google account and create a new project.
You will find the `Server Key` in the project settings screen under `Cloud Messaging` tab. When the server is up and running
you can add Firebase to your applications following the instructions in the `Engage/Cloud Messaging` section.

To test the integration with a device you can use [FCM toolbox](https://simonmarquis.github.io/FCM-toolbox). You can also download the app
to your mobile, create a device token and test the reachability of your device.

## Usage

```go
package main

import (
"context"
"log"

"github.com/nikoksr/notify"
"github.com/nikoksr/notify/service/fcm"
)

func main() {
fcmSvc, err := fcm.New("server_api_key")
if err != nil {
log.Fatalf("fcm.New() failed: %s", err.Error())
}

fcmSvc.AddReceivers("deviceToken1")

notifier := notify.New()
notifier.UseServices(fcmSvc)

// Use context.Background() if you want to send a simple notification message.
ctx := context.Background()

// Optionally, you can include additional data in the message payload by adding the corresponding value to the context.
ctxWithData := context.WithValue(ctx, fcm.DataKey, map[string]interface{}{
"some-key": "some-value",
"other-key": "other-value",
})

// Optionally, you can specify a total of retry attempts per each message by adding the corresponding value to the context.
ctxWithDataAndRetries := context.WithValue(ctxWithData, fcm.RetriesKey, 3)

err = notifier.Send(ctxWithDataAndRetries, "subject", "message")
if err != nil {
log.Fatalf("notifier.Send() failed: %s", err.Error())
}

log.Println("notification sent")
}
```
48 changes: 48 additions & 0 deletions service/fcm/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
Package fcm provides message notification integration for Firebase Cloud Messaging (FCM).
Usage:
package main
import (
"context"
"log"
"github.com/nikoksr/notify"
"github.com/nikoksr/notify/service/fcm"
)
func main() {
fcmSvc, err := fcm.New("server_api_key")
if err != nil {
log.Fatalf("fcm.New() failed: %s", err.Error())
}
fcmSvc.AddReceivers("deviceToken1")
notifier := notify.New()
notifier.UseServices(fcmSvc)
// Use context.Background() if you want to send a simple notification message.
ctx := context.Background()
// Optionally, you can include additional data in the message payload by adding the corresponding value to the context.
ctxWithData := context.WithValue(ctx, fcm.DataKey, map[string]interface{}{
"some-key": "some-value",
"other-key": "other-value",
})
// Optionally, you can specify a total of retry attempts per each message by adding the corresponding value to the context.
ctxWithDataAndRetries := context.WithValue(ctxWithData, fcm.RetriesKey, 3)
err = notifier.Send(ctxWithDataAndRetries, "subject", "message")
if err != nil {
log.Fatalf("notifier.Send() failed: %s", err.Error())
}
log.Println("notification sent")
}
*/
package fcm
104 changes: 104 additions & 0 deletions service/fcm/fcm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package fcm

import (
"context"

"github.com/appleboy/go-fcm"
"github.com/pkg/errors"
)

// Compile-time check that fcm.Client satisfies fcmClient interface.
var _ fcmClient = &fcm.Client{}

var (
// DataKey is used as a context.Context key to optionally add data to the message payload.
DataKey = msgDataKey{}
// RetriesKey is used as a context.Context key to optionally set a total of retry attempts per each message.
RetriesKey = msgRetriesKey{}
)

type (
msgDataKey struct{}
msgRetriesKey struct{}
)

// fcmClient abstracts go-fcm for writing unit tests
type fcmClient interface {
SendWithRetry(*fcm.Message, int) (*fcm.Response, error)
}

// Service encapsulates the FCM client along with internal state for storing device tokens.
type Service struct {
client fcmClient
deviceTokens []string
}

// New returns a new instance of a FCM notification service.
func New(serverAPIKey string) (*Service, error) {
client, err := fcm.NewClient(serverAPIKey)
if err != nil {
return nil, err
}

s := &Service{
client: client,
deviceTokens: []string{},
}
return s, nil
}

// AddReceivers takes FCM device tokens and appends them to the internal device tokens slice.
// The Send method will send a given message to all those devices.
func (s *Service) AddReceivers(deviceTokens ...string) {
s.deviceTokens = append(s.deviceTokens, deviceTokens...)
}

// Send takes a message subject and a message body and sends them to all previously set devices.
func (s *Service) Send(ctx context.Context, subject, message string) error {
msg := &fcm.Message{
Notification: &fcm.Notification{
Title: subject,
Body: message,
},
}

if data, ok := getMessageData(ctx); ok {
msg.Data = data
}

retryAttempts := getMessageRetryAttempts(ctx)

for _, deviceToken := range s.deviceTokens {
select {
case <-ctx.Done():
return ctx.Err()
default:
msg.To = deviceToken

_, err := s.client.SendWithRetry(msg, retryAttempts)
if err != nil {
return errors.Wrapf(err, "failed to send message to FCM device with token '%s'", deviceToken)
}
}
}

return nil
}

func getMessageData(ctx context.Context) (data map[string]interface{}, ok bool) {
value := ctx.Value(DataKey)
if value != nil {
data, ok = value.(map[string]interface{})
}
return
}

func getMessageRetryAttempts(ctx context.Context) int {
value := ctx.Value(RetriesKey)
if value != nil {
if retryAttempts, ok := value.(int); ok {
return retryAttempts
}
}
return 0
}
Loading

0 comments on commit d448ef6

Please sign in to comment.