Skip to content

Commit

Permalink
update push notifications library to migrate GCM to http v1
Browse files Browse the repository at this point in the history
  • Loading branch information
khirvy019 committed Nov 6, 2024
1 parent 32dc0c6 commit dd3ea97
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 9 deletions.
2 changes: 1 addition & 1 deletion .env_template
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ POSTGRES_DB=watchtower
POSTGRES_USER=postgres
POSTGRES_PASSWORD=badpassword

FIREBASE_API_KEY=fcm-api-key
GOOGLE_APP_CREDENTIALS_PATH=compose/firebase-admin-credentials.json
GOOGLE_CLOUD_MESSAGING_API_KEY=gcm-api-key
APNS_CERTIFICATE_PATH=compose/certificate.pem
APNS_AUTH_KEY_ID=
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -212,3 +212,4 @@ supervisord.pid
# exclude pem certificates
**.pem
images
compose/firebase-admin-credentials.json
19 changes: 17 additions & 2 deletions notifications/utils/send.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
from firebase_admin import messaging
from django.db.models import OuterRef, Exists
from push_notifications.models import GCMDevice, APNSDevice
from notifications.models import DeviceWallet

from .send_response import parse_gcm_response

APNS_KWARGS = [
# part of push_notifications.apns._apns_send() func
"priority", "collapse_id",
Expand Down Expand Up @@ -58,7 +61,13 @@ def parse_send_message_for_gcm(message, **kwargs):
kwargs["priority"] = "high"
else:
kwargs["priority"] = "normal"


message = messaging.Message(
notification=messaging.Notification(
body=message,
),
)

return (message, kwargs)


Expand Down Expand Up @@ -119,9 +128,15 @@ def send_push_notification_to_wallet_hashes(wallet_hash_list, message, **kwargs)
print(f"GCM({multi_wallet_index}) | {filtered_gcm_devices}")
if not filtered_gcm_devices: continue
_gcm_send_response = filtered_gcm_devices.send_message(gcm_message, **gcm_kwargs)
_gcm_send_response = parse_gcm_response(_gcm_send_response)

if not isinstance(gcm_send_response, list): gcm_send_response = []
gcm_send_response += _gcm_send_response
if isinstance(_gcm_send_response, list):
gcm_send_response += _gcm_send_response
elif isinstance(getattr(_gcm_send_response, "responses", None), list):
gcm_send_response += _gcm_send_response.responses
else:
gcm_send_response.append(_gcm_send_response)

except Exception as exception:
gcm_send_response = exception
Expand Down
36 changes: 36 additions & 0 deletions notifications/utils/send_response.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from firebase_admin import messaging

def parse_gcm_response(gcm_response):
if isinstance(gcm_response, messaging.BatchResponse):
return [parse_gcm_response(resp) for resp in gcm_response.responses]

if isinstance(gcm_response, messaging.SendResponse):
return {
"success": gcm_response.success,
"msg_id": gcm_response.message_id,
"exception":gcm_response.exception,
}
return gcm_response

def has_successful_response(gcm_send_response, apns_send_response):
if isinstance(gcm_send_response, Exception) and isinstance(apns_send_response, Exception):
return False

if isinstance(gcm_send_response, list):
for gcm_response in gcm_send_response:
if isinstance(gcm_response, messaging.BatchResponse) and gcm_response.success_count > 0:
return True
elif isinstance(gcm_response, messaging.SendResponse) and gcm_response.success:
return True
elif isinstance(gcm_response, dict) and gcm_response.get("success"):
return True

if isinstance(apns_send_response, list):
for apns_response in apns_send_response:
if not isinstance(apns_response, dict):
continue
if any([result == 'Success' for result in apns_response.values()]):
return True

return False

31 changes: 26 additions & 5 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
apns2==0.7.2
apns2==0.7.1
appdirs==1.4.4
appnope==0.1.0
asgiref==3.8.1
atomicwrites==1.4.0
attrs==22.2.0
backcall==0.1.0
beautifulsoup4==4.10.0
BitCash==0.6.4
bitcoin==1.1.42
CacheControl==0.14.1
cachetools==5.5.0
celery==5.2.7
celery-heimdall==1.0.0
certifi==2019.11.28
Expand All @@ -24,7 +27,7 @@ django-filter==2.4.0
django-jinja==2.6.0
django-picklefield==3.0.1
django-postgres-extra==2.0.2
django-push-notifications==3.0.0
django-push-notifications==3.1.0
django-rename-app==0.1.6
django-rest-hooks==1.5.0
djangorestframework==3.11.0
Expand All @@ -33,8 +36,22 @@ django-dynamic-raw-id==2.8
drf-yasg==1.17.1
drf-extensions==0.7.1
filelock==3.0.12
firebase-admin==6.5.0
gevent==20.6.2
google-api-core==2.22.0
google-api-python-client==2.151.0
google-auth==2.35.0
google-auth-httplib2==0.2.0
google-cloud-core==2.4.1
google-cloud-firestore==2.19.0
google-cloud-storage==2.18.2
google-crc32c==1.5.0
google-resumable-media==2.7.2
googleapis-common-protos==1.65.0
greenlet==0.4.16
grpcio==1.34.0
grpcio-status==1.34.0
grpcio-tools==1.34.0
gunicorn==20.0.4
humanize==0.5.1
idna==2.9
Expand All @@ -61,8 +78,11 @@ psycopg2==2.8.4
ptyprocess==0.6.0
py==1.9.0
Pillow==9.4.0
protobuf==3.20.3
pyasn1==0.6.1
pyasn1_modules==0.4.1
Pygments==2.5.2
PyJWT==1.7.1
PyJWT==2.8.0
pyparsing==2.4.7
pytest==5.0.1
pytest-cov==2.7.1
Expand All @@ -73,6 +93,7 @@ pytz==2021.3
pyzmq==25.0.0
redis==4.3.4
requests==2.23.0
rsa==4.9
rpyc==4.1.5
ruamel.yaml==0.16.10
ruamel.yaml.clib==0.2.0
Expand All @@ -88,7 +109,7 @@ uritemplate==3.0.1
urllib3==1.25.8
wcwidth==0.1.8
web3==5.28.0
websockets==10.4
websockets==9.1
whitenoise==5.0.1
zipp==3.0.0
zope.event==4.4
Expand All @@ -104,4 +125,4 @@ ecdsa==0.18.0
python-slugify==8.0.1
uvicorn==0.32.0
uvloop==0.21.0
git+https://github.com/paytaca/python-bitcoinrpc
git+https://github.com/paytaca/python-bitcoinrpc
10 changes: 9 additions & 1 deletion watchtower/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,10 +225,18 @@ def decipher(value):

# Push notifications (django-push-notifications)
# See https://github.com/jazzband/django-push-notifications
import firebase_admin

# Initialize the default app (either use `GOOGLE_APPLICATION_CREDENTIALS` environment variable, or pass a firebase_admin.credentials.Certificate instance)
google_app_credentials_path = os.path.join(BASE_DIR, config('GOOGLE_APP_CREDENTIALS_PATH', 'compose/firebase-admin-credentials.json'))
google_app_cert = firebase_admin.credentials.Certificate(google_app_credentials_path)
firebase_app = firebase_admin.initialize_app(google_app_cert)

PUSH_NOTIFICATIONS_SETTINGS = {
"CONFIG": "push_notifications.conf.LegacyConfig",
# For Firebase (Android)
# -----------------------------------------
"FCM_API_KEY": config("FIREBASE_API_KEY"),
"FIREBASE_APP": firebase_app,

# For Google cloud messaging (Android)
# -----------------------------------------
Expand Down

0 comments on commit dd3ea97

Please sign in to comment.