habulaj commited on
Commit
1c189d0
·
verified ·
1 Parent(s): f2f184b

Update routes/sendnotifications.py

Browse files
Files changed (1) hide show
  1. routes/sendnotifications.py +107 -31
routes/sendnotifications.py CHANGED
@@ -1,16 +1,18 @@
1
- from fastapi import APIRouter
 
2
  import httpx
3
- import json
4
  from google.oauth2 import service_account
5
  from google.auth.transport.requests import Request
6
 
7
  router = APIRouter()
8
 
9
- # Caminho para o arquivo da conta de serviço correta
10
- SERVICE_ACCOUNT_FILE = './closetcoach-2d50b-firebase-adminsdk-fbsvc-7fcccbacb1.json'
 
11
 
12
- # Token de teste (fixo por enquanto)
13
- TEST_DEVICE_TOKEN = 'cnL5SYv0RF-VHoVo8JoAvv:APA91bGeOzUhAicTfoboPXI1immeb4ueR_vBL5Pf1Kky5cltKfvw76EBnh7VDhviyvRn4qhV5IjfZieQKJXe-_kYxi0ZJOJJBrfXdeIwVsLQ-0bi2ElNwds'
 
14
 
15
  def get_access_token():
16
  credentials = service_account.Credentials.from_service_account_file(
@@ -22,35 +24,109 @@ def get_access_token():
22
  scoped_credentials.refresh(Request())
23
  return scoped_credentials.token
24
 
25
- @router.get("/send-test-notification")
26
- async def send_test_notification():
27
- try:
28
- access_token = get_access_token()
29
 
30
- headers = {
31
- 'Authorization': f'Bearer {access_token}',
32
- 'Content-Type': 'application/json',
33
- }
 
 
 
 
 
34
 
35
- payload = {
36
- "message": {
37
- "notification": {
38
- "title": "Teste ClosetCoach",
39
- "body": "Esta é uma notificação de teste 🚀",
40
- },
41
- "token": TEST_DEVICE_TOKEN
42
- }
43
- }
44
 
45
- url = "https://fcm.googleapis.com/v1/projects/closetcoach-2d50b/messages:send"
 
 
 
 
 
 
46
 
47
- async with httpx.AsyncClient() as client:
48
- response = await client.post(url, headers=headers, json=payload)
 
 
 
 
 
49
 
50
- return {
51
- "status_code": response.status_code,
52
- "response": response.json()
 
 
 
 
 
 
 
 
 
 
 
53
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
 
55
- except Exception as e:
56
- return {"error": str(e)}
 
1
+ from fastapi import APIRouter, HTTPException
2
+ from pydantic import BaseModel
3
  import httpx
 
4
  from google.oauth2 import service_account
5
  from google.auth.transport.requests import Request
6
 
7
  router = APIRouter()
8
 
9
+ # Configurações Supabase
10
+ SUPABASE_URL = "https://your-project.supabase.co"
11
+ SUPABASE_API_KEY = "your-supabase-anon-or-service-role-key"
12
 
13
+ # Firebase config
14
+ SERVICE_ACCOUNT_FILE = './closetcoach-2d50b-firebase-adminsdk-fbsvc-7fcccb1.json'
15
+ FCM_PROJECT_ID = "closetcoach-2d50b"
16
 
17
  def get_access_token():
18
  credentials = service_account.Credentials.from_service_account_file(
 
24
  scoped_credentials.refresh(Request())
25
  return scoped_credentials.token
26
 
27
+ class NotificationRequest(BaseModel):
28
+ keyword: str
29
+ initiator_id: str # quem iniciou a ação (ex: quem seguiu)
30
+ target_user_id: str # quem recebe a notificação
31
 
32
+ async def supabase_select(table: str, select: str, filters: dict):
33
+ headers = {
34
+ "apikey": SUPABASE_API_KEY,
35
+ "Authorization": f"Bearer {SUPABASE_API_KEY}",
36
+ "Content-Type": "application/json",
37
+ "Accept": "application/json",
38
+ }
39
+ filter_query = '&'.join([f'{key}=eq.{value}' for key, value in filters.items()])
40
+ url = f"{SUPABASE_URL}/rest/v1/{table}?select={select}&{filter_query}"
41
 
42
+ async with httpx.AsyncClient() as client:
43
+ response = await client.get(url, headers=headers)
44
+ response.raise_for_status()
45
+ return response.json()
 
 
 
 
 
46
 
47
+ def format_name(full_name: str) -> str:
48
+ parts = full_name.strip().split()
49
+ if len(parts) == 1:
50
+ return parts[0]
51
+ first_name = parts[0]
52
+ second_initial = parts[1][0].upper() if len(parts) > 1 else ''
53
+ return f"{first_name} {second_initial}."
54
 
55
+ async def check_follow_exists(follower_id: str, following_id: str) -> bool:
56
+ filters = {
57
+ "follower_id": follower_id,
58
+ "following_id": following_id
59
+ }
60
+ result = await supabase_select("followers", "id", filters)
61
+ return len(result) > 0
62
 
63
+ async def get_user_info(user_id: str):
64
+ users = await supabase_select("User", "name,token_fcm", {"id": user_id})
65
+ if not users:
66
+ return None
67
+ return users[0]
68
+
69
+ def build_notification_payload(title: str, body: str, token: str) -> dict:
70
+ return {
71
+ "message": {
72
+ "notification": {
73
+ "title": title,
74
+ "body": body,
75
+ },
76
+ "token": token
77
  }
78
+ }
79
+
80
+ async def send_fcm_notification(payload: dict):
81
+ access_token = get_access_token()
82
+ headers = {
83
+ 'Authorization': f'Bearer {access_token}',
84
+ 'Content-Type': 'application/json',
85
+ }
86
+ url = f"https://fcm.googleapis.com/v1/projects/{FCM_PROJECT_ID}/messages:send"
87
+ async with httpx.AsyncClient() as client:
88
+ response = await client.post(url, headers=headers, json=payload)
89
+ return response
90
+
91
+ @router.post("/send-notification")
92
+ async def send_notification(data: NotificationRequest):
93
+ keyword = data.keyword.lower()
94
+
95
+ # Pega info do initiator (ex: quem fez a ação)
96
+ initiator = await get_user_info(data.initiator_id)
97
+ if not initiator:
98
+ raise HTTPException(status_code=404, detail="Initiator user not found")
99
+
100
+ # Pega info do target (quem vai receber notificação)
101
+ target = await get_user_info(data.target_user_id)
102
+ if not target or not target.get("token_fcm"):
103
+ raise HTTPException(status_code=404, detail="Target user or token not found")
104
+
105
+ # Aqui definimos regras para cada keyword
106
+ if keyword == "follow":
107
+ # Verifica se realmente está seguindo
108
+ if not await check_follow_exists(data.initiator_id, data.target_user_id):
109
+ raise HTTPException(status_code=403, detail="Follow relationship not found")
110
+
111
+ # Monta mensagem
112
+ follower_name = format_name(initiator["name"])
113
+ title = "Novo seguidor!"
114
+ body = f"{follower_name} começou a seguir você."
115
+
116
+ elif keyword == "like":
117
+ # Exemplo: notificação de like
118
+ liker_name = format_name(initiator["name"])
119
+ title = "Nova curtida!"
120
+ body = f"{liker_name} curtiu sua publicação."
121
+
122
+ else:
123
+ raise HTTPException(status_code=400, detail="Keyword não suportada")
124
+
125
+ payload = build_notification_payload(title, body, target["token_fcm"])
126
+
127
+ response = await send_fcm_notification(payload)
128
+
129
+ if response.status_code != 200:
130
+ raise HTTPException(status_code=response.status_code, detail=response.text)
131
 
132
+ return {"detail": "Notification sent successfully"}