habulaj commited on
Commit
9faf9b1
·
verified ·
1 Parent(s): b3dfad2

Update routes/sendnotifications.py

Browse files
Files changed (1) hide show
  1. routes/sendnotifications.py +74 -54
routes/sendnotifications.py CHANGED
@@ -36,6 +36,7 @@ FCM_PROJECT_ID = "closetcoach-2d50b"
36
  class NotificationRequest(BaseModel):
37
  keyword: str
38
  target_user_id: str
 
39
 
40
  def short_collapse_key(follower_id: str, target_user_id: str) -> str:
41
  raw = f"follow:{follower_id}:{target_user_id}"
@@ -60,6 +61,27 @@ async def verify_user_token(user_token: str) -> str:
60
 
61
  return user_id
62
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  async def fetch_supabase(table: str, select: str, filters: dict, headers=SUPABASE_ROLE_HEADERS):
64
  filter_query = '&'.join([f'{k}=eq.{v}' for k, v in filters.items()])
65
  url = f"{SUPABASE_URL}/rest/v1/{table}?select={select}&{filter_query}"
@@ -130,72 +152,70 @@ async def send_notification(
130
  follower_id = await verify_user_token(user_token)
131
  target_user_id = data.target_user_id
132
 
133
- if data.keyword != "follow":
134
  raise HTTPException(status_code=400, detail="Unsupported keyword")
135
 
136
- async with aiohttp.ClientSession() as session:
137
- # Busca usuário alvo
138
- target_user_resp = await session.get(
139
- f"{SUPABASE_URL}/rest/v1/User?select=name,token_fcm&id=eq.{target_user_id}",
140
- headers=SUPABASE_ROLE_HEADERS
141
- )
142
- if target_user_resp.status != 200:
143
- raise HTTPException(status_code=500, detail="Failed to fetch target user")
144
- target_users = await target_user_resp.json()
145
- if not target_users or not target_users[0].get("token_fcm"):
146
- raise HTTPException(status_code=404, detail="Target user or FCM token not found")
147
- target_user = target_users[0]
148
-
149
- # Verifica se follow existe
150
- follow_resp = await session.get(
151
- f"{SUPABASE_URL}/rest/v1/followers?select=id&follower_id=eq.{follower_id}&following_id=eq.{target_user_id}",
152
- headers=SUPABASE_ROLE_HEADERS
153
- )
154
- if follow_resp.status != 200:
155
- raise HTTPException(status_code=500, detail="Failed to verify follow relationship")
156
- follow_exists = len(await follow_resp.json()) > 0
157
  if not follow_exists:
158
  raise HTTPException(status_code=403, detail="Follow relationship does not exist")
159
 
160
- # Busca dados do follower
161
- follower_resp = await session.get(
162
- f"{SUPABASE_URL}/rest/v1/User?select=name&id=eq.{follower_id}",
163
- headers=SUPABASE_ROLE_HEADERS
164
- )
165
- if follower_resp.status != 200:
166
- raise HTTPException(status_code=500, detail="Failed to fetch follower user")
167
- followers = await follower_resp.json()
168
- if not followers or not followers[0].get("name"):
169
- raise HTTPException(status_code=404, detail="Follower user not found")
170
- follower_name = format_name(followers[0]["name"])
171
-
172
- # Monta notificação
173
- title = "🎉 New Follower!"
174
- body = f"{follower_name} started following you."
175
 
176
  collapse_id = short_collapse_key(follower_id, target_user_id)
177
 
178
- payload = {
179
- "message": {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
180
  "notification": {
181
- "title": title,
182
- "body": body,
183
- },
184
- "token": target_user["token_fcm"],
185
- "android": {
186
- "collapse_key": collapse_id,
187
- "notification": {
188
- "tag": collapse_id # 🔥 ESSENCIAL para evitar duplicata visual
189
- }
190
- },
191
- "apns": {
192
- "headers": {
193
- "apns-collapse-id": collapse_id
194
- }
195
  }
196
  }
197
  }
198
 
 
 
 
 
 
 
 
199
  access_token = get_access_token()
200
  headers = {
201
  "Authorization": f"Bearer {access_token}",
@@ -210,4 +230,4 @@ async def send_notification(
210
  raise HTTPException(status_code=resp.status, detail=f"FCM error: {resp_text}")
211
  fcm_response = await resp.json()
212
 
213
- return {"detail": "Follow notification sent successfully", "fcm_response": fcm_response}
 
36
  class NotificationRequest(BaseModel):
37
  keyword: str
38
  target_user_id: str
39
+ reference: str = ""
40
 
41
  def short_collapse_key(follower_id: str, target_user_id: str) -> str:
42
  raw = f"follow:{follower_id}:{target_user_id}"
 
61
 
62
  return user_id
63
 
64
+ async def get_post_info(feed_id: str):
65
+ # Busca o feed
66
+ feeds = await fetch_supabase("Feeds", "description,portfolios,user_id", {"id": feed_id})
67
+ if not feeds:
68
+ raise HTTPException(status_code=404, detail="Post not found")
69
+
70
+ feed = feeds[0]
71
+ description = feed.get("description", "")
72
+ portfolio_ids = eval(feed.get("portfolios", "[]"))
73
+
74
+ image_url = None
75
+ if portfolio_ids:
76
+ portfolio_data = await fetch_supabase("Portfolio", "image_url", {"id": portfolio_ids[0]})
77
+ if portfolio_data:
78
+ image_url = portfolio_data[0].get("image_url")
79
+
80
+ return {
81
+ "description": description,
82
+ "image_url": image_url
83
+ }
84
+
85
  async def fetch_supabase(table: str, select: str, filters: dict, headers=SUPABASE_ROLE_HEADERS):
86
  filter_query = '&'.join([f'{k}=eq.{v}' for k, v in filters.items()])
87
  url = f"{SUPABASE_URL}/rest/v1/{table}?select={select}&{filter_query}"
 
152
  follower_id = await verify_user_token(user_token)
153
  target_user_id = data.target_user_id
154
 
155
+ if data.keyword not in ("follow", "like"):
156
  raise HTTPException(status_code=400, detail="Unsupported keyword")
157
 
158
+ # Verifica se relação de follow existe
159
+ if data.keyword == "follow":
160
+ follow_exists = await check_follow_exists(follower_id, target_user_id)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
  if not follow_exists:
162
  raise HTTPException(status_code=403, detail="Follow relationship does not exist")
163
 
164
+ # Busca FCM e nome do usuário de destino
165
+ target_user = await get_user_info(target_user_id)
166
+ if not target_user or not target_user.get("token_fcm"):
167
+ raise HTTPException(status_code=404, detail="Target user or FCM token not found")
168
+
169
+ # Busca nome do autor da ação
170
+ actor_info = await get_user_info(follower_id)
171
+ if not actor_info or not actor_info.get("name"):
172
+ raise HTTPException(status_code=404, detail="User not found")
173
+ actor_name = format_name(actor_info["name"])
 
 
 
 
 
174
 
175
  collapse_id = short_collapse_key(follower_id, target_user_id)
176
 
177
+ # Monta conteúdo da notificação
178
+ if data.keyword == "follow":
179
+ title = "🎉 New Follower!"
180
+ body = f"{actor_name} started following you."
181
+ image_url = None
182
+ elif data.keyword == "like":
183
+ # Pega dados do post
184
+ post_info = await get_post_info(data.reference)
185
+ title = "❤️ New Like!"
186
+ desc = post_info["description"]
187
+ body = f"{actor_name} liked your post" + (f": \"{desc}\"" if desc else ".")
188
+ image_url = post_info["image_url"]
189
+ else:
190
+ raise HTTPException(status_code=400, detail="Unsupported keyword")
191
+
192
+ # Monta payload
193
+ message = {
194
+ "notification": {
195
+ "title": title,
196
+ "body": body,
197
+ },
198
+ "token": target_user["token_fcm"],
199
+ "android": {
200
+ "collapse_key": collapse_id,
201
  "notification": {
202
+ "tag": collapse_id
203
+ }
204
+ },
205
+ "apns": {
206
+ "headers": {
207
+ "apns-collapse-id": collapse_id
 
 
 
 
 
 
 
 
208
  }
209
  }
210
  }
211
 
212
+ if image_url:
213
+ message["notification"]["image"] = image_url
214
+ message["android"]["notification"]["image"] = image_url
215
+
216
+ payload = {"message": message}
217
+
218
+ # Envia via FCM
219
  access_token = get_access_token()
220
  headers = {
221
  "Authorization": f"Bearer {access_token}",
 
230
  raise HTTPException(status_code=resp.status, detail=f"FCM error: {resp_text}")
231
  fcm_response = await resp.json()
232
 
233
+ return {"detail": "Notification sent successfully", "fcm_response": fcm_response}