Skip to content

Commit

Permalink
Merge pull request #361 from matrix-org/devon/fcm-update
Browse files Browse the repository at this point in the history
Support for FCM v1 API
  • Loading branch information
devonh authored Feb 15, 2024
2 parents 9c40c7a + 3c0ff4d commit c8a85fd
Show file tree
Hide file tree
Showing 17 changed files with 515 additions and 43 deletions.
23 changes: 19 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,26 @@ For either type, it can accept:
### gcm

This sends messages via Google/Firebase Cloud Messaging (GCM/FCM)
and hence can be used to deliver notifications to Android apps. It
expects the 'api_key' parameter to contain the 'Server key',
which can be acquired from Firebase Console at:
`https://console.firebase.google.com/project/<PROJECT NAME>/settings/cloudmessaging/`
and hence can be used to deliver notifications to Android apps.

The expected configuration depends on which version of the firebase api you
wish to use.

For legacy API, it expects:

- the `api_key` parameter to contain the `Server key`,
which can be acquired from Firebase Console at:
`https://console.firebase.google.com/project/<PROJECT NAME>/settings/cloudmessaging/`

For API v1, it expects:

- the `api_version` parameter to contain `v1`
- the `project_id` parameter to contain the `Project ID`,
which can be acquired from Firebase Console at:
`https://console.cloud.google.com/project/<PROJECT NAME>/settings/general/`
- the `service_account_file` parameter to contain the path to the service account file,
which can be acquired from Firebase Console at:
`https://console.firebase.google.com/project/<PROJECT NAME>/settings/serviceaccounts/adminsdk`

Using an HTTP Proxy for outbound traffic
----------------------------------------
Expand Down
1 change: 1 addition & 0 deletions changelog.d/361.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Adds the ability to use the new FCM v1 API.
31 changes: 26 additions & 5 deletions docs/applications.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,14 @@ may be useful for reference.

### Firebase Cloud Messaging

The client will receive a message with an FCM `data` payload with this structure:
The client will receive a message with an FCM `data` payload with a structure depending on the api version used:

Please note that fields may be truncated if they are large, so that they fit
within FCM's limit.
Please also note that some fields will be unavailable if you registered a pusher
with `event_id_only` format.

#### Legacy API

```json
{
Expand All @@ -232,10 +239,24 @@ The client will receive a message with an FCM `data` payload with this structure
}
```

Please note that fields may be truncated if they are large, so that they fit
within FCM's limit.
Please also note that some fields will be unavailable if you registered a pusher
with `event_id_only` format.
#### API v1

```json
{
"event_id": "$3957tyerfgewrf384",
"type": "m.room.message",
"sender": "@exampleuser:example.org",
"room_name": "Mission Control",
"room_alias": "#exampleroom:example.org",
"sender_display_name": "Major Tom",
"content_msgtype": "m.text",
"content_body": "I'm floating in a most peculiar way."
"room_id": "!slw48wfj34rtnrf:example.org",
"prio": "high",
"unread": "2",
"missed_calls": "1"
}
```

### WebPush

Expand Down
2 changes: 1 addition & 1 deletion docs/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ EOF
```


## Example of an FCM request
## Example of an FCM request (Legacy API)

HTTP data sent to `https://fcm.googleapis.com/fcm/send`:

Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ dependencies = [
"attrs>=19.2.0",
"cryptography>=2.6.1",
"idna>=2.8",
"google-auth>=2.27.0",
"jaeger-client>=4.0.0",
"matrix-common==1.3.0",
"opentracing>=2.2.0",
Expand Down
Empty file added stubs/google/__init__.pyi
Empty file.
3 changes: 3 additions & 0 deletions stubs/google/auth/__init__.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from google.auth._default import default

__all__ = ["default"]
15 changes: 15 additions & 0 deletions stubs/google/auth/_default.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from typing import Optional

from google.auth.transport.requests import Request

class Credentials:
token = "token"

def refresh(self, request: Request) -> None: ...

def default(
scopes: Optional[list[str]] = None,
request: Optional[str] = None,
quota_project_id: Optional[int] = None,
default_scopes: Optional[list[str]] = None,
) -> tuple[Credentials, Optional[str]]: ...
3 changes: 3 additions & 0 deletions stubs/google/auth/transport/__init__.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from google.auth.transport.requests import Request

__all__ = ["Request"]
1 change: 1 addition & 0 deletions stubs/google/auth/transport/requests.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
class Request: ...
3 changes: 3 additions & 0 deletions stubs/google/oauth2/__init__.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from google.oauth2.service_account import Credentials

__all__ = ["Credentials"]
16 changes: 16 additions & 0 deletions stubs/google/oauth2/service_account.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from typing import Optional

from google.auth.transport.requests import Request

class Credentials:
token = "token"

def refresh(self, request: Request) -> None: ...
@staticmethod
def from_service_account_file(
service_account_file: str,
scopes: Optional[list[str]] = None,
request: Optional[str] = None,
quota_project_id: Optional[int] = None,
default_scopes: Optional[list[str]] = None,
) -> Credentials: ...
7 changes: 5 additions & 2 deletions sygnal.yaml.sample
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,12 @@ apps:

# This is an example GCM/FCM push configuration.
#
#com.example.myapp.android:
#im.vector.app:
# type: gcm
# api_key: your_api_key_for_gcm
# #api_key:
# api_version: v1
# project_id: project-id
# service_account_file: /path/to/service_account.json
#
# # This is the maximum number of connections to GCM servers at any one time
# # the default is 20.
Expand Down
12 changes: 12 additions & 0 deletions sygnal/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,18 @@ def __init__(self, *args: object, custom_retry_delay: Optional[int] = None) -> N
self.custom_retry_delay = custom_retry_delay


class NotificationQuotaDispatchException(Exception):
"""
To be used by pushkins for errors that are do to exceeding the quota
limits and are hopefully temporary, so the request should possibly be
retried soon.
"""

def __init__(self, *args: object, custom_retry_delay: Optional[int] = None) -> None:
super().__init__(*args)
self.custom_retry_delay = custom_retry_delay


class ProxyConnectError(ConnectError):
"""
Exception raised when we are unable to start a connection using a HTTP proxy
Expand Down
Loading

0 comments on commit c8a85fd

Please sign in to comment.