habulaj commited on
Commit
c22959c
·
verified ·
1 Parent(s): 64e6c4c

Update routes/support.py

Browse files
Files changed (1) hide show
  1. routes/support.py +97 -56
routes/support.py CHANGED
@@ -143,94 +143,135 @@ async def respond_ticket(
143
  payload: TicketResponseRequest,
144
  user_token: str = Header(None, alias="User-key")
145
  ):
146
- # 1. Verifica o token do remetente (quem está respondendo)
147
  support_id = await verify_user_token(user_token)
148
  created_at = datetime.utcnow().isoformat()
149
 
150
- # 2. Busca o ticket
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151
  async with aiohttp.ClientSession() as session:
152
  async with session.get(
153
  f"{SUPABASE_URL}/rest/v1/Tickets?id=eq.{payload.ticket_id}",
154
  headers=SUPABASE_ROLE_HEADERS
155
  ) as ticket_resp:
156
  if ticket_resp.status != 200:
157
- raise HTTPException(status_code=404, detail="Ticket não encontrado")
158
 
159
  ticket_data = await ticket_resp.json()
160
  if not ticket_data:
161
- raise HTTPException(status_code=404, detail="Ticket não existe")
162
 
163
  ticket = ticket_data[0]
164
  user_id = ticket["user_id"]
165
 
166
- # 3. Pega o e-mail e o nome do usuário (do cliente) e do atendente (quem está respondendo)
167
  async with aiohttp.ClientSession() as session:
168
  async with session.get(
169
  f"{SUPABASE_URL}/rest/v1/User?id=eq.{user_id}",
170
  headers=SUPABASE_ROLE_HEADERS
171
  ) as user_resp:
172
  if user_resp.status != 200:
173
- raise HTTPException(status_code=404, detail="Usuário não encontrado")
174
 
175
  user_data = await user_resp.json()
176
  if not user_data:
177
- raise HTTPException(status_code=404, detail="Usuário não existe")
178
 
179
  user_email = user_data[0]["email"]
180
- user_name = user_data[0].get("name", "User").strip()
181
- first_name = user_name.split(" ")[0] if user_name else "User"
182
 
183
- # Pega o nome do atendente
184
- async with aiohttp.ClientSession() as session:
185
- async with session.get(
186
- f"{SUPABASE_URL}/rest/v1/User?id=eq.{support_id}",
187
- headers=SUPABASE_ROLE_HEADERS
188
- ) as support_resp:
189
- if support_resp.status != 200:
190
- raise HTTPException(status_code=404, detail="Atendente não encontrado")
191
-
192
- support_data = await support_resp.json()
193
- if not support_data:
194
- raise HTTPException(status_code=404, detail="Atendente não existe")
195
-
196
- support_name = support_data[0].get("name", "Support Team")
197
-
198
- # 4. Envia o e-mail com HTML personalizado (estilo clean, sem bordas)
199
  access_token = await get_gmail_access_token()
200
- subject = f"Customer Support Case {payload.ticket_id}".encode('utf-8').decode('utf-8') # Garantir encoding correto
201
 
202
- email_html = f"""\
203
  <!DOCTYPE html>
204
  <html lang="en">
205
- <head>
206
  <meta charset="UTF-8" />
207
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
208
- <title>{subject}</title>
209
- </head>
210
- <body style="margin:0;padding:0;background-color:#f5f5f5;">
211
- <table width="100%" cellpadding="0" cellspacing="0" border="0" bgcolor="#f5f5f5">
212
- <tr>
213
- <td align="center" style="padding:30px 10px;">
214
- <table width="600" cellpadding="0" cellspacing="0" border="0" style="background:#ffffff;padding: 20px; font-family: Arial, sans-serif;">
215
  <tr>
216
- <td align="right" style="padding-bottom: 10px;">
217
- <img src="https://storage.googleapis.com/flutterflow-io-6f20.appspot.com/projects/saa-s-cloud-file-management-dashboard-u57zo5/assets/5l30gd1xml6i/Frame_1.png" width="26" height="14" alt="Logo" />
218
- </td>
219
- </tr>
220
- <tr>
221
- <td style="font-size: 16px; line-height: 1.6; color: #333;">
222
- <p>Hi {first_name},</p>
223
-
224
- <p>{payload.content}</p>
225
-
226
- <p>Best regards,<br>{support_name}<br>Support Team</p>
227
- </td>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
228
  </tr>
229
- </table>
230
- </td>
231
- </tr>
232
  </table>
233
- </body>
234
  </html>
235
  """
236
 
@@ -255,10 +296,10 @@ Content-Type: text/html; charset="UTF-8"
255
  ) as gmail_resp:
256
  if gmail_resp.status != 200:
257
  error_detail = await gmail_resp.text()
258
- raise HTTPException(status_code=500, detail=f"Erro ao enviar e-mail: {error_detail}")
259
  gmail_data = await gmail_resp.json()
260
 
261
- # 5. Salva resposta em messages_tickets
262
  message_payload = {
263
  "user": support_id,
264
  "content": payload.content,
@@ -274,10 +315,10 @@ Content-Type: text/html; charset="UTF-8"
274
  ) as msg_resp:
275
  if msg_resp.status != 201:
276
  error_detail = await msg_resp.text()
277
- raise HTTPException(status_code=500, detail=f"Erro ao registrar resposta: {error_detail}")
278
 
279
  return {
280
- "status": "Resposta enviada com sucesso",
281
  "ticket_id": payload.ticket_id,
282
  "email_to": user_email,
283
  "message_id": gmail_data.get("id")
 
143
  payload: TicketResponseRequest,
144
  user_token: str = Header(None, alias="User-key")
145
  ):
146
+ # 1. Verify support agent token
147
  support_id = await verify_user_token(user_token)
148
  created_at = datetime.utcnow().isoformat()
149
 
150
+ # Get support agent name
151
+ async with aiohttp.ClientSession() as session:
152
+ async with session.get(
153
+ f"{SUPABASE_URL}/rest/v1/User?id=eq.{support_id}",
154
+ headers=SUPABASE_ROLE_HEADERS
155
+ ) as support_user_resp:
156
+ if support_user_resp.status != 200:
157
+ raise HTTPException(status_code=404, detail="Support agent not found")
158
+
159
+ support_user_data = await support_user_resp.json()
160
+ if not support_user_data:
161
+ raise HTTPException(status_code=404, detail="Support agent does not exist")
162
+
163
+ support_name = support_user_data[0].get("name", "Support Team").strip()
164
+
165
+ # 2. Retrieve ticket
166
  async with aiohttp.ClientSession() as session:
167
  async with session.get(
168
  f"{SUPABASE_URL}/rest/v1/Tickets?id=eq.{payload.ticket_id}",
169
  headers=SUPABASE_ROLE_HEADERS
170
  ) as ticket_resp:
171
  if ticket_resp.status != 200:
172
+ raise HTTPException(status_code=404, detail="Ticket not found")
173
 
174
  ticket_data = await ticket_resp.json()
175
  if not ticket_data:
176
+ raise HTTPException(status_code=404, detail="Ticket does not exist")
177
 
178
  ticket = ticket_data[0]
179
  user_id = ticket["user_id"]
180
 
181
+ # 3. Get user email and name
182
  async with aiohttp.ClientSession() as session:
183
  async with session.get(
184
  f"{SUPABASE_URL}/rest/v1/User?id=eq.{user_id}",
185
  headers=SUPABASE_ROLE_HEADERS
186
  ) as user_resp:
187
  if user_resp.status != 200:
188
+ raise HTTPException(status_code=404, detail="User not found")
189
 
190
  user_data = await user_resp.json()
191
  if not user_data:
192
+ raise HTTPException(status_code=404, detail="User does not exist")
193
 
194
  user_email = user_data[0]["email"]
195
+ user_name = user_data[0].get("name", "user").strip()
196
+ first_name = user_name.split(" ")[0] if user_name else "user"
197
 
198
+ # 4. Send email with updated HTML template (Apple style)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
199
  access_token = await get_gmail_access_token()
200
+ subject = f"Customer Support - Case {payload.ticket_id}" # Fixed dash character
201
 
202
+ email_html = f"""
203
  <!DOCTYPE html>
204
  <html lang="en">
205
+ <head>
206
  <meta charset="UTF-8" />
207
+ </head>
208
+ <body style="margin:0;padding:0;background-color:#f5f5f5;">
209
+ <table width="700" border="0" cellspacing="0" cellpadding="0" align="center" style="margin:0 auto">
210
+ <tbody>
 
 
 
 
211
  <tr>
212
+ <td width="100%">
213
+ <table width="100%" border="0" cellspacing="0" cellpadding="0" align="left" style="margin:0 auto;border:1px solid #d2d2d2;border-radius:5px">
214
+ <tbody>
215
+ <tr>
216
+ <td bgcolor="#ffffff" width="100%" height="21" style="border-top-left-radius:5px;border-top-right-radius:5px"></td>
217
+ </tr>
218
+ <tr>
219
+ <td align="right" bgcolor="#ffffff" style="padding:0 19px 0 21px">
220
+ <table width="100%" border="0" cellspacing="0" cellpadding="0">
221
+ <tbody>
222
+ <tr>
223
+ <td bgcolor="#ffffff" align="right" height="27" style="display:block">
224
+ <img src="https://storage.googleapis.com/flutterflow-io-6f20.appspot.com/projects/saa-s-cloud-file-management-dashboard-u57zo5/assets/5l30gd1xml6i/Frame_1.png" width="22" height="26" border="0" alt="" />
225
+ </td>
226
+ </tr>
227
+ </tbody>
228
+ </table>
229
+ </td>
230
+ </tr>
231
+ <tr>
232
+ <td bgcolor="#ffffff" style="padding:20px 50px 40px;border-bottom-right-radius:5px;border-bottom-left-radius:5px">
233
+ <table>
234
+ <tbody>
235
+ <tr>
236
+ <td bgcolor="#ffffff" style="border-bottom-right-radius:5px;border-bottom-left-radius:5px">
237
+ <table width="100%" border="0" cellspacing="0" cellpadding="0" align="center">
238
+ <tbody>
239
+ <tr>
240
+ <td width="100%" valign="top">
241
+ <table width="100%" border="0" cellspacing="0" cellpadding="0" style="table-layout:fixed">
242
+ <tbody>
243
+ <tr>
244
+ <td style="padding:7px 0 19px;margin:0;font-family:Helvetica Neue,Helvetica,Arial,Verdana,sans-serif;color:#797979;font-size:14px;line-height:1.6em;word-wrap:break-word">
245
+ <p style="color:rgba(0,0,0,0.85);margin:0.0px 0.0px 0.0px 0.0px">Hello {first_name},</p>
246
+ <p style="min-height:16.0px;color:rgba(0,0,0,0.85);margin:0.0px 0.0px 0.0px 0.0px"><br></p>
247
+ {payload.content}
248
+ <p style="min-height:16.0px;color:rgba(0,0,0,0.85);margin:0.0px 0.0px 0.0px 0.0px"><br></p>
249
+ <p style="color:rgba(0,0,0,0.85);margin:0.0px 0.0px 0.0px 0.0px">If you have additional questions related to this request, please refer to case number {payload.ticket_id}.</p>
250
+ <p style="min-height:16.0px;color:rgba(0,0,0,0.85);margin:0.0px 0.0px 0.0px 0.0px"><br></p>
251
+ <p style="color:rgba(0,0,0,0.85);margin:0.0px 0.0px 0.0px 0.0px">Best regards,</p>
252
+ <p style="color:rgba(0,0,0,0.85);min-height:16.0px;margin:0.0px 0.0px 0.0px 0.0px"><br></p>
253
+ <p style="color:rgba(0,0,0,0.85);margin:0.0px 0.0px 0.0px 0.0px">{support_name}<br>Customer Support</p>
254
+ </td>
255
+ </tr>
256
+ </tbody>
257
+ </table>
258
+ </td>
259
+ </tr>
260
+ </tbody>
261
+ </table>
262
+ </td>
263
+ </tr>
264
+ </tbody>
265
+ </table>
266
+ </td>
267
+ </tr>
268
+ </tbody>
269
+ </table>
270
+ </td>
271
  </tr>
272
+ </tbody>
 
 
273
  </table>
274
+ </body>
275
  </html>
276
  """
277
 
 
296
  ) as gmail_resp:
297
  if gmail_resp.status != 200:
298
  error_detail = await gmail_resp.text()
299
+ raise HTTPException(status_code=500, detail=f"Error sending email: {error_detail}")
300
  gmail_data = await gmail_resp.json()
301
 
302
+ # 5. Save response in messages_tickets
303
  message_payload = {
304
  "user": support_id,
305
  "content": payload.content,
 
315
  ) as msg_resp:
316
  if msg_resp.status != 201:
317
  error_detail = await msg_resp.text()
318
+ raise HTTPException(status_code=500, detail=f"Error recording response: {error_detail}")
319
 
320
  return {
321
+ "status": "response sent successfully",
322
  "ticket_id": payload.ticket_id,
323
  "email_to": user_email,
324
  "message_id": gmail_data.get("id")