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

Update routes/sendnotifications.py

Browse files
Files changed (1) hide show
  1. routes/sendnotifications.py +42 -46
routes/sendnotifications.py CHANGED
@@ -1,14 +1,24 @@
 
 
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'
@@ -26,42 +36,33 @@ def get_access_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]
@@ -80,41 +81,39 @@ def build_notification_payload(title: str, body: str, token: str) -> dict:
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."
@@ -124,9 +123,6 @@ async def send_notification(data: NotificationRequest):
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"}
 
1
+ import os
2
+ import aiohttp
3
  from fastapi import APIRouter, HTTPException
4
  from pydantic import BaseModel
 
5
  from google.oauth2 import service_account
6
  from google.auth.transport.requests import Request
7
 
8
  router = APIRouter()
9
 
10
+ # Supabase config (pegando das variáveis de ambiente)
11
+ SUPABASE_URL = "https://ussxqnifefkgkaumjann.supabase.co" # Ajuste pro seu projeto
12
+ SUPABASE_ROLE_KEY = os.getenv("SUPA_SERVICE_KEY")
13
+ if not SUPABASE_ROLE_KEY:
14
+ raise ValueError("❌ SUPA_SERVICE_KEY not set in environment!")
15
+
16
+ SUPABASE_ROLE_HEADERS = {
17
+ "apikey": SUPABASE_ROLE_KEY,
18
+ "Authorization": f"Bearer {SUPABASE_ROLE_KEY}",
19
+ "Content-Type": "application/json",
20
+ "Prefer": "return=representation"
21
+ }
22
 
23
  # Firebase config
24
  SERVICE_ACCOUNT_FILE = './closetcoach-2d50b-firebase-adminsdk-fbsvc-7fcccb1.json'
 
36
 
37
  class NotificationRequest(BaseModel):
38
  keyword: str
39
+ initiator_id: str
40
+ target_user_id: str
41
 
42
+ async def fetch_supabase(table: str, select: str, filters: dict):
43
+ # Monta query params
44
+ filter_query = '&'.join([f'{k}=eq.{v}' for k, v in filters.items()])
 
 
 
 
 
45
  url = f"{SUPABASE_URL}/rest/v1/{table}?select={select}&{filter_query}"
46
 
47
+ async with aiohttp.ClientSession() as session:
48
+ async with session.get(url, headers=SUPABASE_ROLE_HEADERS) as resp:
49
+ if resp.status != 200:
50
+ detail = await resp.text()
51
+ raise HTTPException(status_code=500, detail=f"Erro Supabase: {detail}")
52
+ return await resp.json()
53
+
54
+ async def check_follow_exists(follower_id: str, following_id: str) -> bool:
55
+ result = await fetch_supabase("followers", "id", {"follower_id": follower_id, "following_id": following_id})
56
+ return len(result) > 0
57
 
58
  def format_name(full_name: str) -> str:
59
  parts = full_name.strip().split()
60
  if len(parts) == 1:
61
  return parts[0]
62
+ return f"{parts[0]} {parts[1][0].upper()}."
 
 
 
 
 
 
 
 
 
 
63
 
64
  async def get_user_info(user_id: str):
65
+ users = await fetch_supabase("User", "name,token_fcm", {"id": user_id})
66
  if not users:
67
  return None
68
  return users[0]
 
81
  async def send_fcm_notification(payload: dict):
82
  access_token = get_access_token()
83
  headers = {
84
+ "Authorization": f"Bearer {access_token}",
85
+ "Content-Type": "application/json"
86
  }
87
  url = f"https://fcm.googleapis.com/v1/projects/{FCM_PROJECT_ID}/messages:send"
88
+
89
+ async with aiohttp.ClientSession() as session:
90
+ async with session.post(url, headers=headers, json=payload) as resp:
91
+ resp_text = await resp.text()
92
+ if resp.status != 200:
93
+ raise HTTPException(status_code=resp.status, detail=f"FCM error: {resp_text}")
94
+ return await resp.json()
95
 
96
  @router.post("/send-notification")
97
  async def send_notification(data: NotificationRequest):
98
  keyword = data.keyword.lower()
99
 
 
100
  initiator = await get_user_info(data.initiator_id)
101
  if not initiator:
102
  raise HTTPException(status_code=404, detail="Initiator user not found")
103
 
 
104
  target = await get_user_info(data.target_user_id)
105
  if not target or not target.get("token_fcm"):
106
  raise HTTPException(status_code=404, detail="Target user or token not found")
107
 
 
108
  if keyword == "follow":
 
109
  if not await check_follow_exists(data.initiator_id, data.target_user_id):
110
  raise HTTPException(status_code=403, detail="Follow relationship not found")
111
 
 
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
  liker_name = format_name(initiator["name"])
118
  title = "Nova curtida!"
119
  body = f"{liker_name} curtiu sua publicação."
 
123
 
124
  payload = build_notification_payload(title, body, target["token_fcm"])
125
 
126
+ result = await send_fcm_notification(payload)
 
 
 
127
 
128
+ return {"detail": "Notification sent successfully", "fcm_response": result}