mirror of
https://github.com/rudy3333/eversync.git
synced 2025-07-01 16:46:02 +00:00
fcm notifs v1
This commit is contained in:
parent
a4427bb5e0
commit
2feca9394f
9 changed files with 157 additions and 6 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -96,4 +96,6 @@ files
|
|||
fly.toml
|
||||
fly-deploy.yml
|
||||
Dockerfile
|
||||
cookies.txt
|
||||
cookies.txt
|
||||
|
||||
fcm_secret.json
|
|
@ -29,6 +29,7 @@ BASE_DIR = Path(__file__).resolve().parent.parent
|
|||
|
||||
# SECURITY WARNING: keep the secret key used in production secret!
|
||||
SECRET_KEY = os.getenv('SECRET_KEY')
|
||||
FCM_SERVICE_ACCOUNT = str(BASE_DIR / "file.json")
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = True
|
||||
|
|
|
@ -3,6 +3,13 @@ from django.db import models
|
|||
# Create your models here.
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
class UserNotifs(models.Model):
|
||||
user = models.OneToOneField(User, on_delete=models.CASCADE)
|
||||
device_token = models.CharField(blank=True, null=True)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.user.username}'s notif token: {self.device_token[:8]}..."
|
||||
|
||||
class UserStorage(models.Model):
|
||||
user = models.OneToOneField(User, on_delete=models.CASCADE)
|
||||
storage_limit = models.BigIntegerField(default=5 * 1024 * 1024 * 1024) # 5 GB
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
from django.db.models.signals import post_save
|
||||
from django.dispatch import receiver
|
||||
from django.contrib.auth.models import User
|
||||
from .models import UserStorage
|
||||
from .models import UserStorage, UserNotifs
|
||||
|
||||
@receiver(post_save, sender=User)
|
||||
def create_user_storage(sender, instance, created, **kwargs):
|
||||
if created:
|
||||
UserStorage.objects.create(user=instance)
|
||||
UserStorage.objects.create(user=instance)
|
||||
UserNotifs.objects.create(user=instance)
|
|
@ -69,6 +69,8 @@ urlpatterns = [
|
|||
path('whiteboard/<int:whiteboard_id>/save-images/', views.save_images, name='save_images'),
|
||||
path('whiteboard/<int:whiteboard_id>/upload-image/', views.upload_image, name='upload_image'),
|
||||
path('whiteboard/<int:whiteboard_id>/delete-image/', views.delete_image, name='delete_image'),
|
||||
path('api/update_device_token/', views.update_device_token, name='update_device_token'),
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -35,7 +35,8 @@ from .forms import RegisterForm
|
|||
from django.core.files.storage import FileSystemStorage
|
||||
import uuid
|
||||
from django.conf import settings
|
||||
|
||||
from fcm import send_push_notification
|
||||
from .models import UserNotifs
|
||||
|
||||
def email_verified_required(view_func):
|
||||
@wraps(view_func)
|
||||
|
@ -584,6 +585,12 @@ def send_message(request):
|
|||
content = request.POST.get('content')
|
||||
receiver = User.objects.get(username=reciever_username)
|
||||
message = Message.objects.create(sender=request.user, receiver=receiver, content=content)
|
||||
if hasattr(receiver, 'device_token') and receiver.device_token:
|
||||
token = receiver.device_token
|
||||
title = f"New message from {request.user.username}"
|
||||
body = content[:100]
|
||||
send_push_notification(token, title, body)
|
||||
|
||||
return JsonResponse({"message": "sent", "message_id": message.id})
|
||||
else:
|
||||
return JsonResponse({"message": "error"})
|
||||
|
@ -968,4 +975,20 @@ def delete_image(request, whiteboard_id):
|
|||
except Exception as e:
|
||||
return JsonResponse({'error': str(e)}, status=500)
|
||||
|
||||
return JsonResponse({'error': 'Invalid request method'}, status=405)
|
||||
return JsonResponse({'error': 'Invalid request method'}, status=405)
|
||||
|
||||
|
||||
def update_device_token(request):
|
||||
try:
|
||||
data = json.loads(request.body)
|
||||
token = data.get('device_token', '').strip()
|
||||
if not token:
|
||||
return JsonResponse({"error": "No device_token provided"}, status=400)
|
||||
|
||||
user_notifs, created = UserNotifs.objects.get_or_create(user=request.user)
|
||||
user_notifs.device_token = token
|
||||
user_notifs.save()
|
||||
|
||||
return JsonResponse({"message": "Device token updated"})
|
||||
except Exception as e:
|
||||
return JsonResponse({"error": str(e)}, status=500)
|
33
fcm.py
Normal file
33
fcm.py
Normal file
|
@ -0,0 +1,33 @@
|
|||
import json
|
||||
import requests
|
||||
from google.oauth2 import service_account
|
||||
from django.conf import settings
|
||||
|
||||
def send_push_notification(token, title, body, data=None):
|
||||
creds = service_account.Credentials.from_service_account_file(
|
||||
settings.FCM_SERVICE_ACCOUNT,
|
||||
scopes=["https://www.googleapis.com/auth/firebase.messaging"]
|
||||
)
|
||||
|
||||
creds.refresh(requests.Request())
|
||||
|
||||
headers = {
|
||||
"Authorization": f"Bearer {creds.token}",
|
||||
"Content-Type": "application/json; UTF-8",
|
||||
}
|
||||
|
||||
url = f"https://fcm.googleapis.com/v1/projects/{creds.project_id}/messages:send"
|
||||
|
||||
message = {
|
||||
"message": {
|
||||
"token": token,
|
||||
"notification": {
|
||||
"title": title,
|
||||
"body": body,
|
||||
},
|
||||
"data": data or {}
|
||||
}
|
||||
}
|
||||
|
||||
response = requests.post(url, headers=headers, data=json.dumps(message))
|
||||
return response.json()
|
|
@ -22,4 +22,5 @@ icalendar
|
|||
sentry-sdk[django]
|
||||
yt-dlp
|
||||
sendgrid
|
||||
django-recaptcha
|
||||
django-recaptcha
|
||||
google-auth
|
|
@ -37,4 +37,85 @@
|
|||
|
||||
const replay = Sentry.getReplay();
|
||||
replay.start();
|
||||
</script>
|
||||
|
||||
<script src="https://www.gstatic.com/firebasejs/9.23.0/firebase-app-compat.js"></script>
|
||||
|
||||
<script src="https://www.gstatic.com/firebasejs/9.23.0/firebase-messaging-compat.js"></script>
|
||||
|
||||
<script>
|
||||
const firebaseConfig = {
|
||||
apiKey: "AIzaSyCR9FFFiNFt6ORYu7KJHv_fT-aD2fW7bIg",
|
||||
authDomain: "eversync333.firebaseapp.com",
|
||||
projectId: "eversync333",
|
||||
messagingSenderId: "546896423149",
|
||||
appId: "1:546896423149:web:c06d07957a7080965144e4",
|
||||
};
|
||||
|
||||
// Initialize Firebase app
|
||||
firebase.initializeApp(firebaseConfig);
|
||||
|
||||
// Get Firebase messaging instance
|
||||
const messaging = firebase.messaging();
|
||||
|
||||
// Request permission to send notifications and get FCM token
|
||||
function requestPermissionAndGetToken() {
|
||||
Notification.requestPermission().then((permission) => {
|
||||
if (permission === 'granted') {
|
||||
messaging.getToken({ vapidKey: 'BKJsJ3Bn5G9aMrF0pzN3cJsgQvclDPhSzpMcl3MS3lzgeXL4M1nuZrT1-7HLsnR4bq86SckhxTiyoISYQUZhuOY' }).then((currentToken) => {
|
||||
if (currentToken) {
|
||||
console.log('FCM token:', currentToken);
|
||||
sendTokenToBackend(currentToken);
|
||||
} else {
|
||||
console.log('No registration token available. Request permission to generate one.');
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.error('An error occurred while retrieving token. ', err);
|
||||
});
|
||||
} else {
|
||||
console.log('Notification permission denied.');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Send the token to your backend to save it
|
||||
function sendTokenToBackend(token) {
|
||||
fetch('/api/update_device_token/', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRFToken': getCookie('csrftoken'), // Django’s CSRF token
|
||||
},
|
||||
body: JSON.stringify({ device_token: token }),
|
||||
credentials: 'include', // send cookies for auth if needed
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => console.log('Token saved on backend:', data))
|
||||
.catch(console.error);
|
||||
}
|
||||
|
||||
// Helper to get the CSRF token cookie for Django
|
||||
function getCookie(name) {
|
||||
let cookieValue = null;
|
||||
if (document.cookie && document.cookie !== '') {
|
||||
const cookies = document.cookie.split(';');
|
||||
for (let cookie of cookies) {
|
||||
cookie = cookie.trim();
|
||||
if (cookie.startsWith(name + '=')) {
|
||||
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return cookieValue;
|
||||
}
|
||||
|
||||
// Call this on page load or after user logs in
|
||||
requestPermissionAndGetToken();
|
||||
|
||||
// Optional: listen for foreground messages
|
||||
messaging.onMessage((payload) => {
|
||||
console.log('Message received in foreground: ', payload);
|
||||
// You can show a custom notification or UI update here
|
||||
});
|
||||
</script>
|
Loading…
Add table
Add a link
Reference in a new issue