parent
7224fb8eeb
commit
9b2bd5ec50
@ -0,0 +1,6 @@ |
||||
-----BEGIN PRIVATE KEY----- |
||||
MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgtQe/9xXcsNYYOHhs |
||||
4EeJIo2qpoCZ/lLdkMnttM3jMF6gCgYIKoZIzj0DAQehRANCAAQU5IruCl0xw3xX |
||||
4WJVMZGyFINAA6nTj13nvD5P3fNzYFepgYVBy+ZBFvWrGHi75VnojiRR6v3e+z2K |
||||
0DinoPJF |
||||
-----END PRIVATE KEY----- |
||||
@ -0,0 +1,28 @@ |
||||
# Generated by Django 4.2.11 on 2024-07-12 10:01 |
||||
|
||||
from django.conf import settings |
||||
from django.db import migrations, models |
||||
import django.db.models.deletion |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('tournaments', '0074_customuser_device_id'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AlterField( |
||||
model_name='club', |
||||
name='creator', |
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL), |
||||
), |
||||
migrations.CreateModel( |
||||
name='DeviceToken', |
||||
fields=[ |
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||
('value', models.BinaryField()), |
||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), |
||||
], |
||||
), |
||||
] |
||||
@ -0,0 +1,18 @@ |
||||
# Generated by Django 4.2.11 on 2024-07-12 16:45 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('tournaments', '0075_alter_club_creator_devicetoken'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AlterField( |
||||
model_name='devicetoken', |
||||
name='value', |
||||
field=models.CharField(max_length=240), |
||||
), |
||||
] |
||||
@ -0,0 +1,18 @@ |
||||
# Generated by Django 4.2.11 on 2024-07-14 12:12 |
||||
|
||||
from django.db import migrations, models |
||||
|
||||
|
||||
class Migration(migrations.Migration): |
||||
|
||||
dependencies = [ |
||||
('tournaments', '0076_alter_devicetoken_value'), |
||||
] |
||||
|
||||
operations = [ |
||||
migrations.AlterField( |
||||
model_name='devicetoken', |
||||
name='value', |
||||
field=models.TextField(), |
||||
), |
||||
] |
||||
@ -0,0 +1,10 @@ |
||||
from django.db import models |
||||
from . import CustomUser |
||||
import uuid |
||||
|
||||
class DeviceToken(models.Model): |
||||
user = models.ForeignKey(CustomUser, on_delete=models.CASCADE) |
||||
value = models.TextField() |
||||
|
||||
def __str__(self): |
||||
return f"{self.value}" |
||||
@ -0,0 +1,74 @@ |
||||
import http.client |
||||
import json |
||||
import jwt |
||||
import time |
||||
from hyper import HTTP20Connection |
||||
|
||||
# APPLE WARNING: Reuse a connection as long as possible. |
||||
# In most cases, you can reuse a connection for many hours to days. |
||||
# If your connection is mostly idle, you may send a HTTP2 PING frame after an hour of inactivity. |
||||
# Reusing a connection often results in less bandwidth and CPU consumption. |
||||
# https://developer.apple.com/documentation/usernotifications/sending-notification-requests-to-apns |
||||
|
||||
def generate_jwt(key_path, key_id, team_id): |
||||
with open(key_path, 'r') as key_file: |
||||
key = key_file.read() |
||||
|
||||
headers = { |
||||
"alg": "ES256", |
||||
"kid": key_id |
||||
} |
||||
|
||||
payload = { |
||||
"iss": team_id, |
||||
"iat": time.time() |
||||
} |
||||
|
||||
token = jwt.encode(payload, key, algorithm="ES256", headers=headers) |
||||
return token |
||||
|
||||
|
||||
key_path = 'AuthKey_DHJRAU6BCZ.p8' |
||||
key_id = 'DHJRAU6BCZ' |
||||
team_id = 'BQ3Y44M3Q6' |
||||
bundle_id = 'app.padelclub' |
||||
# device_token = 'user_device_token' |
||||
message = 'Hello, World!' |
||||
|
||||
def send_push_notification(device_token, message): |
||||
jwt_token = generate_jwt(key_path, key_id, team_id) |
||||
|
||||
# APNs endpoint (use 'api.push.apple.com' for production) |
||||
host = 'api.sandbox.push.apple.com' |
||||
|
||||
payload = { |
||||
"aps": { |
||||
"alert": message, |
||||
"sound": "default" |
||||
} |
||||
} |
||||
|
||||
payload_json = json.dumps(payload) |
||||
|
||||
# Create the HTTP connection |
||||
connection = HTTP20Connection(host, port=443) |
||||
|
||||
# Set the headers |
||||
headers = { |
||||
"apns-topic": bundle_id, |
||||
"authorization": f"bearer {jwt_token}", |
||||
"content-type": "application/json" |
||||
} |
||||
|
||||
# Send the notification |
||||
connection.request( |
||||
"POST", |
||||
f"/3/device/{device_token}", |
||||
body=payload_json, |
||||
headers=headers |
||||
) |
||||
|
||||
response = connection.get_response() |
||||
response_data = response.read() |
||||
|
||||
print(response.status, response.reason, response_data) |
||||
Loading…
Reference in new issue