Update routes/support.py
Browse files- routes/support.py +73 -7
routes/support.py
CHANGED
@@ -1,9 +1,12 @@
|
|
1 |
import os
|
2 |
import logging
|
3 |
import aiohttp
|
4 |
-
|
|
|
|
|
5 |
from pydantic import BaseModel
|
6 |
from datetime import datetime
|
|
|
7 |
|
8 |
router = APIRouter()
|
9 |
|
@@ -25,11 +28,11 @@ SUPABASE_ROLE_HEADERS = {
|
|
25 |
"apikey": SUPABASE_ROLE_KEY,
|
26 |
"Authorization": f"Bearer {SUPABASE_ROLE_KEY}",
|
27 |
"Content-Type": "application/json",
|
28 |
-
"Prefer": "return=representation"
|
29 |
}
|
30 |
|
31 |
|
32 |
-
# 🛡️
|
33 |
async def verify_user_token(user_token: str) -> str:
|
34 |
headers = {
|
35 |
"Authorization": f"Bearer {user_token}",
|
@@ -50,7 +53,7 @@ async def verify_user_token(user_token: str) -> str:
|
|
50 |
return user_id
|
51 |
|
52 |
|
53 |
-
# 📨 Modelo da requisição
|
54 |
class CreateTicketRequest(BaseModel):
|
55 |
message: str
|
56 |
|
@@ -63,7 +66,6 @@ async def create_ticket(
|
|
63 |
user_id = await verify_user_token(user_token)
|
64 |
created_at = datetime.utcnow().isoformat()
|
65 |
|
66 |
-
# 1. Cria o ticket com ROLE KEY (bypassa RLS)
|
67 |
ticket_payload = {
|
68 |
"user_id": user_id,
|
69 |
"support_id": None,
|
@@ -84,7 +86,6 @@ async def create_ticket(
|
|
84 |
ticket_data = await ticket_resp.json()
|
85 |
ticket_id = ticket_data[0]["id"]
|
86 |
|
87 |
-
# 2. Cria a mensagem inicial (também com ROLE KEY)
|
88 |
message_payload = {
|
89 |
"user": user_id,
|
90 |
"content": body.message,
|
@@ -103,4 +104,69 @@ async def create_ticket(
|
|
103 |
error_detail = await message_resp.text()
|
104 |
raise HTTPException(status_code=500, detail=f"Erro ao criar mensagem: {error_detail}")
|
105 |
|
106 |
-
return {"ticket_id": ticket_id}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import os
|
2 |
import logging
|
3 |
import aiohttp
|
4 |
+
import base64
|
5 |
+
|
6 |
+
from fastapi import APIRouter, HTTPException, Header, Body
|
7 |
from pydantic import BaseModel
|
8 |
from datetime import datetime
|
9 |
+
from typing import Optional
|
10 |
|
11 |
router = APIRouter()
|
12 |
|
|
|
28 |
"apikey": SUPABASE_ROLE_KEY,
|
29 |
"Authorization": f"Bearer {SUPABASE_ROLE_KEY}",
|
30 |
"Content-Type": "application/json",
|
31 |
+
"Prefer": "return=representation"
|
32 |
}
|
33 |
|
34 |
|
35 |
+
# 🛡️ Verificação de token de usuário (sem admin check)
|
36 |
async def verify_user_token(user_token: str) -> str:
|
37 |
headers = {
|
38 |
"Authorization": f"Bearer {user_token}",
|
|
|
53 |
return user_id
|
54 |
|
55 |
|
56 |
+
# 📨 Modelo da requisição de ticket
|
57 |
class CreateTicketRequest(BaseModel):
|
58 |
message: str
|
59 |
|
|
|
66 |
user_id = await verify_user_token(user_token)
|
67 |
created_at = datetime.utcnow().isoformat()
|
68 |
|
|
|
69 |
ticket_payload = {
|
70 |
"user_id": user_id,
|
71 |
"support_id": None,
|
|
|
86 |
ticket_data = await ticket_resp.json()
|
87 |
ticket_id = ticket_data[0]["id"]
|
88 |
|
|
|
89 |
message_payload = {
|
90 |
"user": user_id,
|
91 |
"content": body.message,
|
|
|
104 |
error_detail = await message_resp.text()
|
105 |
raise HTTPException(status_code=500, detail=f"Erro ao criar mensagem: {error_detail}")
|
106 |
|
107 |
+
return {"ticket_id": ticket_id}
|
108 |
+
|
109 |
+
|
110 |
+
# 📧 Envio de e-mails com Gmail API
|
111 |
+
GMAIL_CLIENT_ID = "784687789817-3genmmvps11ip3a6fkbkkd8dm3bstgdc.apps.googleusercontent.com"
|
112 |
+
GMAIL_CLIENT_SECRET = "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"
|
113 |
+
GMAIL_REFRESH_TOKEN = "1//04ZOO_chVwlYiCgYIARAAGAQSNwF-L9IrhQO1ij79thk-DTjiMudl_XQshuU5CDTDYtt8rrOTMbz_rL8ECGjNfEN9da6W-mnjhZA"
|
114 |
+
|
115 |
+
class SendEmailRequest(BaseModel):
|
116 |
+
to: str
|
117 |
+
subject: str
|
118 |
+
body: str
|
119 |
+
sender_name: Optional[str] = "Ameddes"
|
120 |
+
sender_email: Optional[str] = "[email protected]"
|
121 |
+
|
122 |
+
|
123 |
+
async def get_gmail_access_token() -> str:
|
124 |
+
url = "https://oauth2.googleapis.com/token"
|
125 |
+
data = {
|
126 |
+
"client_id": GMAIL_CLIENT_ID,
|
127 |
+
"client_secret": GMAIL_CLIENT_SECRET,
|
128 |
+
"refresh_token": GMAIL_REFRESH_TOKEN,
|
129 |
+
"grant_type": "refresh_token"
|
130 |
+
}
|
131 |
+
|
132 |
+
async with aiohttp.ClientSession() as session:
|
133 |
+
async with session.post(url, data=data) as response:
|
134 |
+
if response.status != 200:
|
135 |
+
raise HTTPException(status_code=500, detail="Erro ao obter access_token do Gmail")
|
136 |
+
token_data = await response.json()
|
137 |
+
return token_data["access_token"]
|
138 |
+
|
139 |
+
|
140 |
+
def encode_message(raw_message: str) -> str:
|
141 |
+
return base64.urlsafe_b64encode(raw_message.encode("utf-8")).decode("utf-8").replace("=", "")
|
142 |
+
|
143 |
+
|
144 |
+
@router.post("/send-email")
|
145 |
+
async def send_email(payload: SendEmailRequest = Body(...)):
|
146 |
+
access_token = await get_gmail_access_token()
|
147 |
+
|
148 |
+
raw_message = f"""To: {payload.to}
|
149 |
+
From: "{payload.sender_name}" <{payload.sender_email}>
|
150 |
+
Subject: {payload.subject}
|
151 |
+
Content-Type: text/html; charset="UTF-8"
|
152 |
+
|
153 |
+
{payload.body}
|
154 |
+
"""
|
155 |
+
|
156 |
+
encoded_message = encode_message(raw_message)
|
157 |
+
|
158 |
+
async with aiohttp.ClientSession() as session:
|
159 |
+
async with session.post(
|
160 |
+
"https://gmail.googleapis.com/gmail/v1/users/me/messages/send",
|
161 |
+
headers={
|
162 |
+
"Authorization": f"Bearer {access_token}",
|
163 |
+
"Content-Type": "application/json"
|
164 |
+
},
|
165 |
+
json={"raw": encoded_message}
|
166 |
+
) as resp:
|
167 |
+
if resp.status != 200:
|
168 |
+
error_detail = await resp.text()
|
169 |
+
raise HTTPException(status_code=resp.status, detail=f"Erro ao enviar e-mail: {error_detail}")
|
170 |
+
response_data = await resp.json()
|
171 |
+
|
172 |
+
return {"status": "email sent", "message_id": response_data.get("id")}
|