V1.30 notification

This commit is contained in:
Tibor Bossanyi (Freelancer)
2021-10-01 15:53:20 +02:00
parent 405fefe7b9
commit 696ce5a368
24 changed files with 357 additions and 79 deletions
@@ -0,0 +1,97 @@
import datetime
from firebase_admin import messaging, initialize_app, exceptions
class FCM:
logo_url = 'https://workouttest.com/wp-content/uploads/2020/10/WT_long_logo.png'
# default constructor
def __init__(self):
# To learn more, visit the docs here:
# https://cloud.google.com/docs/authentication/getting-started>
default_app = initialize_app()
def send_to_multiple_token(self, title, body, registration_token, image_url = None):
try:
notification_image_url = image_url
#if image_url == None:
# notification_image_url = self.logo_url
message = messaging.MulticastMessage(
notification=messaging.Notification(
title=title,
body=body,
),
android=messaging.AndroidConfig(
ttl=datetime.timedelta(seconds=3600),
priority='normal',
notification=messaging.AndroidNotification(
image=notification_image_url,
),
),
apns=messaging.APNSConfig(
payload=messaging.APNSPayload(
aps=messaging.Aps(badge=1),
),
fcm_options= messaging.APNSFCMOptions(
image=notification_image_url,
)
),
tokens= registration_token,
)
response = messaging.send_multicast(message)
# Response is a message ID string.
print('Successfully sent message:', response);
except exceptions.FirebaseError as error:
print('Error sending message:', error);
except ValueError as value_error:
print('Error sending message:', value_error);
def send_to_token(self, title, body, image_url = None, registration_token = None):
if registration_token == None:
return "Registration token is null"
try:
#notification_image_url = image_url
#if image_url == None:
notification_image_url = self.logo_url
registration_token = 'cOqNt8rzo074gbIkBSpCgW:APA91bEBuNi3iVzGKb4JhxqN2j80MoJbNptLHk2qsdeKBQz5grpHtrPPXvDqn5BJVVSaj1nwGPwgN7pi6FIApog_TTP3g1yobgmgpPN6udrYgzILlVPMvdGGFDSDh6gKlczhlTL9NEp0'
print(f'image: {notification_image_url}' )
message = messaging.Message(
notification=messaging.Notification(
title=title,
body=body,
),
android=messaging.AndroidConfig(
ttl=datetime.timedelta(seconds=3600),
priority='normal',
notification=messaging.AndroidNotification(
image=notification_image_url,
),
),
apns=messaging.APNSConfig(
payload=messaging.APNSPayload(
aps=messaging.Aps(badge=1),
),
fcm_options= messaging.APNSFCMOptions(
image=notification_image_url,
)
),
token= registration_token,
)
response = messaging.send(message)
# Response is a message ID string.
print('Successfully sent message:', response);
rc = 'OK'
except exceptions.FirebaseError as error:
print('Error sending message:', error);
rc = error
except ValueError as value_error:
print('Error sending message:', value_error);
rc = value_error
return rc
@@ -0,0 +1,76 @@
import requests
import logging
from django.db import connections
import datetime
from ..models.customer import Customer
class Mautic:
def syncTrial(self):
tenDays = datetime.datetime - datetime.timedelta(days=10)
qs = Customer.objects.raw(
'SELECT * from customer WHERE trial_date < "' + tenDays + '" and trial_date is not null')
def sync(self):
logger = logging.getLogger(__name__)
logger.info("Syncronising...")
last_synced_date = self.get_last_synced_date()
if len(last_synced_date) != 0:
qs = Customer.objects.raw(
'SELECT * from customer WHERE date_add > "' + last_synced_date + '" or synced_date is null')
else:
qs = Customer.objects.raw(
'SELECT * from customer WHERE synced_date is null')
headers = {
'content-type': "application/x-www-form-urlencoded",
'cache-control': "no-cache"
}
index = 0
for customer in qs:
goal = customer.goal if customer.goal is not None else ""
fitness_level = customer.fitness_level if customer.fitness_level is not None else ""
data = "mauticform[email]=" + customer.email + \
"&mauticform[f_name]=" + customer.name + \
"&mauticform[firstname]=" + customer.firstname + \
"&mauticform[goal]=" + goal + \
"&mauticform[fitness_level]=" + fitness_level + \
"&mauticform[subscribed]=" + str(customer.date_add) + \
"&mauticform[database_id]=" + str(customer.customer_id) + \
"&mauticform[formId]=1" + \
"&mauticform[formName]=appsync"
print(data)
form_url = 'https://mautic.aitrainer.app/form/submit?formId=1'
response = requests.post(form_url, data=data.encode('utf-8'), headers=headers)
print(str(response.status_code))
if response.status_code == 200:
with connections["live"].cursor() as cursor:
cursor.execute("UPDATE customer SET synced_date = NOW() WHERE customer_id="
+ str(customer.customer_id))
#if index == 0:
# break
index = index + 1
logger.info("Syncronised customer count: " + str(index))
return True
def get_last_synced_date(self):
qs = Customer.objects.raw('SELECT customer_id, max(synced_date) as synced_date from customer')
for c in qs:
if c.synced_date is None:
return ""
synced_date = c.synced_date.strftime('%Y-%m-%d')
print(synced_date)
return synced_date
def sync_frequent_users(self):
print("SYNC FREQ USERS")
return True
@@ -0,0 +1,308 @@
"""Server Side FCM sample.
Firebase Cloud Messaging (FCM) can be used to send messages to clients on iOS,
Android and Web.
This sample uses FCM to send two types of messages to clients that are subscribed
to the `news` topic. One type of message is a simple notification message (display message).
The other is a notification message (display notification) with platform specific
customizations. For example, a badge is added to messages that are sent to iOS devices.
"""
import argparse
import json
import requests
import datetime
import os
from google.oauth2 import service_account
from firebase_admin import messaging, initialize_app
from aitrainer_backoffice.settings.prod import BASE_DIR
PROJECT_ID = 'aitrainer-af0ec'
BASE_URL = 'https://fcm.googleapis.com'
FCM_ENDPOINT = 'v1/projects/' + PROJECT_ID + '/messages:send'
FCM_URL = BASE_URL + '/' + FCM_ENDPOINT
SCOPES = ['https://www.googleapis.com/auth/firebase.messaging', 'https://www.googleapis.com/auth/cloud-platform', 'email']
ASSET_ROOT = os.path.join(BASE_DIR, "asset")
SERVER_KEY = 'AAAA18iNwog:APA91bFo_kDhK4Nd_zHAtyPj6D5CR_amV0aenNn9VPMMVz6j8mgyTCSr3J3IDD_U9duBe1AN35oAiWKp6LmDdJ5n2UQU6unfyUUmsFOSaDlEQZtYl6ZeIQ5XW52Fmkc29Xh62GZ4E-Ic'
# [START retrieve_access_token]
def _get_access_token():
"""Retrieve a valid access token that can be used to authorize requests.
:return: Access token.
"""
default_app = initialize_app()
access_token = default_app.credential.get_access_token()
return access_token.access_token
#return access_token_info.access_token
# [END retrieve_access_token]
def _send_fcm_message(fcm_message):
"""Send HTTP request to FCM with given message.
Args:
fcm_message: JSON object that will make up the body of the request.
"""
# [START use_access_token]
headers = {
'Authorization': 'Bearer ' + _get_access_token(),
'Content-Type': 'application/json; UTF-8',
}
# [END use_access_token]
resp = requests.post(FCM_URL, data=json.dumps(fcm_message), headers=headers)
return resp
'''
if resp.status_code == 200:
print('Message sent to Firebase for delivery, response:')
print(resp.text)
else:
print('Unable to send message to Firebase')
print(resp.text)
'''
def _build_common_message():
"""Construct common notifiation message.
Construct a JSON object that will be used to define the
common parts of a notification message that will be sent
to any app instance subscribed to the news topic.
"""
return {
'message': {
'topic': 'news',
'notification': {
'title': 'FCM Notification',
'body': 'Notification from FCM'
}
}
}
def _build_override_message():
"""Construct common notification message with overrides.
Constructs a JSON object that will be used to customize
the messages that are sent to iOS and Android devices.
"""
fcm_message = _build_common_message()
apns_override = {
'payload': {
'aps': {
'badge': 1
}
},
'headers': {
'apns-priority': '10'
}
}
android_override = {
'notification': {
'click_action': 'android.intent.action.MAIN'
}
}
fcm_message['message']['android'] = android_override
fcm_message['message']['apns'] = apns_override
return fcm_message
def send_to_token():
# [START send_to_token]
# This registration token comes from the client FCM SDKs.
registration_token = 'fFjCZmrHREpRvxZMIKhNSI:APA91bH7cfctHFHbKxtQ5XGRlL26jgLLzo3a1x4hlPfZYi9WxrauMkdIBmqnIQnyD8Jc3xEs0gAsgNYNMLDEgdrHV3bbH4gvFHYUrYzOHZFr-2aVCsYF9otT8_fmAV380egGf5HiCIYd'
# See documentation on defining a message payload.
message = messaging.Message(
data={
'score': '850',
'time': '2:45',
},
token=registration_token,
)
# Send a message to the device corresponding to the provided
# registration token.
response = messaging.send(message)
# Response is a message ID string.
print('Successfully sent message:', response)
# [END send_to_token]
def send_fcm_to_token():
# [START send_to_token]
# This registration token comes from the client FCM SDKs.
'''
headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + _get_access_token(),
}
# See documentation on defining a message payload.
message = messaging.Message(
data = _build_override_message(),
token= registration_token,
)
'''
registration_token = ['fFjCZmrHREpRvxZMIKhNSI:APA91bH7cfctHFHbKxtQ5XGRlL26jgLLzo3a1x4hlPfZYi9WxrauMkdIBmqnIQnyD8Jc3xEs0gAsgNYNMLDEgdrHV3bbH4gvFHYUrYzOHZFr-2aVCsYF9otT8_fmAV380egGf5HiCIYd',
'cOqNt8rzo074gbIkBSpCgW:APA91bEBuNi3iVzGKb4JhxqN2j80MoJbNptLHk2qsdeKBQz5grpHtrPPXvDqn5BJVVSaj1nwGPwgN7pi6FIApog_TTP3g1yobgmgpPN6udrYgzILlVPMvdGGFDSDh6gKlczhlTL9NEp0',
'eUrsvYw9ekx0sr_R8pGTD8:APA91bHJKl1D9gLBz7xi0gILb7ng576DDnCvNba7MHqRaFn9MeeCSVLhEU1yC10b1v0KrZ4pVYgUqxkSv2t-Rh0mXtHR7ABGQENuGDfqjokWPNamXhp99Fuq66o3jnlXxSzRKe_aSCtk']
message = messaging.MulticastMessage(
notification=messaging.Notification(
title='$GOOG up 1.43% on the day',
body='$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.',
),
android=messaging.AndroidConfig(
ttl=datetime.timedelta(seconds=3600),
priority='normal',
notification=messaging.AndroidNotification(
icon='stock_ticker_update',
color='#f45342'
),
),
apns=messaging.APNSConfig(
payload=messaging.APNSPayload(
aps=messaging.Aps(badge=42),
),
),
tokens= registration_token,
)
print(f'SEND FCM message {message}')
response = messaging.send_multicast(message)
#data = json.dumps(message)
#print(f'SEND FCM message {FCM_URL} - Header {headers} - body: {data}')
#response = requests.post(FCM_URL, headers = headers, data=data)
print(f'RESPONSE: {response}')
#response = _send_fcm_message(message)
# Response is a message ID string.
#print('Successfully sent message:', response)
# [END send_to_token]
def send_to_topic():
# [START send_to_topic]
# The topic name can be optionally prefixed with "/topics/".
topic = 'highScores'
# See documentation on defining a message payload.
message = messaging.Message(
data={
'score': '850',
'time': '2:45',
},
topic=topic,
)
# Send a message to the devices subscribed to the provided topic.
response = messaging.send(message)
# Response is a message ID string.
print('Successfully sent message:', response)
# [END send_to_topic]
def send_to_condition():
# [START send_to_condition]
# Define a condition which will send to devices which are subscribed
# to either the Google stock or the tech industry topics.
condition = "'stock-GOOG' in topics || 'industry-tech' in topics"
# See documentation on defining a message payload.
message = messaging.Message(
notification=messaging.Notification(
title='$GOOG up 1.43% on the day',
body='$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.',
),
condition=condition,
)
# Send a message to devices subscribed to the combination of topics
# specified by the provided condition.
response = messaging.send(message)
# Response is a message ID string.
print('Successfully sent message:', response)
# [END send_to_condition]
def send_dry_run():
message = messaging.Message(
data={
'score': '850',
'time': '2:45',
},
token='token',
)
# [START send_dry_run]
# Send a message in the dry run mode.
response = messaging.send(message, dry_run=True)
# Response is a message ID string.
print('Dry run successful:', response)
# [END send_dry_run]
def android_message():
# [START android_message]
message = messaging.Message(
android=messaging.AndroidConfig(
ttl=datetime.timedelta(seconds=3600),
priority='normal',
notification=messaging.AndroidNotification(
title='$GOOG up 1.43% on the day',
body='$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.',
icon='stock_ticker_update',
color='#f45342'
),
),
topic='industry-tech',
)
# [END android_message]
return message
def apns_message():
# [START apns_message]
message = messaging.Message(
apns=messaging.APNSConfig(
headers={'apns-priority': '10'},
payload=messaging.APNSPayload(
aps=messaging.Aps(
alert=messaging.ApsAlert(
title='$GOOG up 1.43% on the day',
body='$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.',
),
badge=42,
),
),
),
topic='industry-tech',
)
# [END apns_message]
return message
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--message')
args = parser.parse_args()
if args.message and args.message == 'common-message':
common_message = _build_common_message()
print('FCM request body for message using common notification object:')
print(json.dumps(common_message, indent=2))
_send_fcm_message(common_message)
elif args.message and args.message == 'override-message':
override_message = _build_override_message()
print('FCM request body for override message:')
print(json.dumps(override_message, indent=2))
_send_fcm_message(override_message)
else:
print('''Invalid command. Please use one of the following commands:
python messaging.py --message=common-message
python messaging.py --message=override-message''')
if __name__ == '__main__':
main()
@@ -0,0 +1,44 @@
import datetime
from .notification_hook import NotificationHook
from ..models import notification as notif
from ..models.notification import NotificationHistory
from .fcm import FCM
class Notification:
fcm = FCM()
def run(self):
notification_queryset = notif.Notification.objects.using('live').raw('SELECT * from notification WHERE active = 1')
for notification in notification_queryset:
if notification.schedule_date != None:
pass
elif notification.schedule_hook != None:
hook = NotificationHook()
try:
hook_function = notification.schedule_hook
hook_sql = notification.schedule_sql
if hook_sql == None:
customers = getattr(hook, hook_function)()
else:
customers = getattr(hook, hook_function)(hook_sql)
for customer in customers:
if customer.firebase_reg_token != None:
print(f'-- Notify Customer {customer.customer_id}')
rc= self.fcm.send_to_token(notification.message_title, notification.message_body, notification.image_url, customer.firebase_reg_token)
self.insert_history(notification=notification, customer=customer, rc=rc)
except Exception as ex:
print(f'Notification Hook {notification.schedule_hook} has no callback function: {ex}')
def insert_history(self, notification, customer, rc):
history = NotificationHistory()
history.pk = None
history.notification = notification
history.customer = customer
history.response = rc
history.notification_date = datetime.datetime.now()
history.save()
print(f'-- Notification History "{history}" has been saved')
@@ -0,0 +1,16 @@
from ..models.customer import Customer
import datetime
class NotificationHook:
def __init__(self) -> None:
pass
def NotificationSelectAdmins(self):
print(datetime.datetime.now(), " *** START automation NotificationSelectAdmins ")
qs = Customer.objects.raw('SELECT customer_id, firebase_reg_token from customer WHERE admin = 1')
return qs
def NotificationCommonSQL(self, sql):
print(datetime.datetime.now(), " *** START automation NotificationCommonSQL ")
qs = Customer.objects.raw(sql)
return qs