Skip to content

Commit

Permalink
Merge pull request #379 from phil-6/fcm-Delivery-Method-updates
Browse files Browse the repository at this point in the history
FCM Delivery Method Updates
  • Loading branch information
excid3 authored Jan 23, 2024
2 parents 901bf4a + ab58bf8 commit 40f6b70
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 47 deletions.
35 changes: 18 additions & 17 deletions UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,41 +215,42 @@ Options for delivery methods have been renamed for clarity and consistency.

#### ActionCable

The `format` option has been renamed to `message`.
The `Noticed::NotificationChannel` has been removed and an example channel is provided in the [ActionCable docs](docs/delivery_methods/action_cable.md).
- The `format` option has been renamed to `message`.
- The `Noticed::NotificationChannel` has been removed and an example channel is provided in the [ActionCable docs](docs/delivery_methods/action_cable.md).

#### Email Delivery Method

`method` is now a required option. Previously, it was inferred from the notification name but we've decided it would be better to be explicit.
- `method` is now a required option. Previously, it was inferred from the notification name but we've decided it would be better to be explicit.

#### FCM

The `format` option has been renamed to `json`.
The `device_tokens` option is now required and should return an Array of device tokens.
The `invalid_token` option replaces the `cleanup_device_tokens` method for handling invalid/expired tokens.
- The `format` option has been renamed to `json`.
- The `device_tokens` option is now required and should return an Array of device tokens.
- The `invalid_token` option replaces the `cleanup_device_tokens` method for handling invalid/expired tokens.
- We no longer wrap the json payload in the `message{}` key. This means we are more compatible with the FCM docs and any future changes that Google make.

#### iOS

The `cert_path` option has been renamed to `apns_key` and should be given the key and not a path.
The `format` option has been renamed to `json`.
The `device_tokens` option is now required and should return an Array of device tokens.
The `invalid_token` option replaces the `cleanup_device_tokens` method for handling invalid/expired tokens.
- The `cert_path` option has been renamed to `apns_key` and should be given the key and not a path.
- The `format` option has been renamed to `json`.
- The `device_tokens` option is now required and should return an Array of device tokens.
- The `invalid_token` option replaces the `cleanup_device_tokens` method for handling invalid/expired tokens.

#### Microsoft Teams

The `format` option has been renamed to `json`.
- The `format` option has been renamed to `json`.

#### Slack

The `format` option has been renamed to `json`.
The `url` option now defaults to `"https://slack.com/api/chat.postMessage` instead of `Rails.application.credentials.dig(:slack, :notification_url)`
- The `format` option has been renamed to `json`.
- The `url` option now defaults to `"https://slack.com/api/chat.postMessage` instead of `Rails.application.credentials.dig(:slack, :notification_url)`

#### Twilio Messaging

Twilio has been renamed to `:twilio_messaging` to make room for `:twilio_voice` and other services they may provide in the future.
The `format` option has been renamed to `json`.
- Twilio has been renamed to `:twilio_messaging` to make room for `:twilio_voice` and other services they may provide in the future.
- The `format` option has been renamed to `json`.

#### Vonage SMS

Vonage has been renamed to `:vonage_sms` to make room for other Vonage services in the future.
The `format` option has been renamed to `json` and is now required.
- Vonage has been renamed to `:vonage_sms` to make room for other Vonage services in the future.
- The `format` option has been renamed to `json` and is now required.
99 changes: 70 additions & 29 deletions docs/delivery_methods/fcm.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,51 +26,92 @@ See the below instructions on where to store this information within your applic
class CommentNotification
deliver_by :fcm do |config|
config.credentials = Rails.root.join("config/certs/fcm.json")
config.device_tokens = ->(recipient) { recipient.notification_tokens.where(platform: "fcm").pluck(:token) }
config.json = ->(device_token) {
{
token: device_token,
notification: {
title: "Test Title",
body: "Test body"
message: {
token: device_token,
notification: {
title: "Test Title",
body: "Test body"
}
}
}
}
config.if = ->(recipient) { recipient.android_notifications? }
end
end
```

## Options

* `json`
Customize the Firebase Cloud Messaging notification object. This can be a Lambda or Symbol of a method name on the notifier. The callable object will be given the device token as an argument.
### `json`
Customize the Firebase Cloud Messaging notification object. This can be a Lambda or Symbol of a method name on the notifier.

The callable object will be given the device token as an argument.

* `credentials`
There are lots of options of now to structure a FCM notification message. See https://firebase.google.com/docs/cloud-messaging/concept-options for more details.

### `credentials`
The location of your Firebase Cloud Messaging credentials.
- When a String object: `deliver_by :fcm, credentials: "config/credentials/fcm.json"`
* Interally, this string is passed to `Rails.root.join()` as an argument so there is no need to do this beforehand.
- When a Pathname object: `deliver_by :fcm, credentials: Rails.root.join("config/credentials/fcm.json")`
* The Pathname object can point to any location where you are storing your credentials.
- When a Hash object: `deliver_by :fcm, credentials: credentials_hash`
```ruby
credentials_hash = {
"type": "service_account",
"project_id": "test-project-1234",
"private_key_id": ...,
etc.....
}
```

* A Hash which contains your credentials
- When a Symbol: `deliver_by :fcm, credentials: :fcm_credentials, format: :format_notification`
```ruby
def fcm_credentials
Rails.root.join("config/certs/fcm.json")
end
```
#### When a String Object

Internally, this string is passed to `Rails.root.join()` as an argument so there is no need to do this beforehand.

```ruby
deliver_by :fcm do |config|
config.credentials = "config/credentials/fcm.json"
end
```

#### When a Pathname object

The Pathname object can point to any location where you are storing your credentials.

```ruby
deliver_by :fcm do |config|
config.credentials = Rails.root.join("config/credentials/fcm.json")
end
```

#### When a Hash object

A Hash which contains your credentials

```ruby
deliver_by :fcm do |config|
config.credentials = credentials_hash
end

credentials_hash = {
"type": "service_account",
"project_id": "test-project-1234",
"private_key_id": ...,
etc.....
}
```

#### When a Symbol

Points to a method which can return a Hash of your credentials, Pathname, or String to your credentials like the examples above.

We pass the notification object as an argument to the method. If you don't need to use it you can use the splat operator `(*)` to ignore it.

```ruby
deliver_by :fcm do |config|
config.credentials = :fcm_credentials
config.json = :format_notification
end

def fcm_credentials(*)
Rails.root.join("config/certs/fcm.json")
end
```

* Points to a method which can return a Hash of your credentials, Pathname, or String to your credentials like the examples above.
#### Otherwise

Otherwise, if the credentials option is left out, it will look for your credentials in: `Rails.application.credentials.fcm`
If the credentials option is left out, it will look for your credentials in: `Rails.application.credentials.fcm`

## Gathering Notification Tokens

Expand Down
11 changes: 10 additions & 1 deletion lib/noticed/delivery_methods/fcm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def deliver
def send_notification(device_token)
post_request("https://fcm.googleapis.com/v1/projects/#{credentials[:project_id]}/messages:send",
headers: {authorization: "Bearer #{access_token}"},
json: notification.instance_exec(device_token, &config[:json]))
json: format_notification(device_token))
rescue Noticed::ResponseUnsuccessful => exception
if exception.response.code == "404" && config[:invalid_token]
notification.instance_exec(device_token, &config[:invalid_token])
Expand All @@ -23,6 +23,15 @@ def send_notification(device_token)
end
end

def format_notification(device_token)
method = config[:json]
if method.is_a?(Symbol) && event.respond_to?(method)
event.send(method, device_token)
else
notification.instance_exec(device_token, &method)
end
end

def credentials
@credentials ||= begin
value = evaluate_option(:credentials)
Expand Down

0 comments on commit 40f6b70

Please sign in to comment.