Ogghey commited on
Commit
9d56b27
ยท
verified ยท
1 Parent(s): 57cd8cf

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +85 -17
app.py CHANGED
@@ -37,8 +37,9 @@ SUPABASE_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJ
37
  model = SentenceTransformer("sentence-transformers/paraphrase-MiniLM-L3-v2")
38
 
39
  # ๐Ÿ” Ambil FAQ berdasarkan UID
40
- def get_faq_from_supabase(uid):
41
- url = f"{SUPABASE_URL}/rest/v1/faq_texts?uid=eq.{uid}"
 
42
  headers = {
43
  "apikey": SUPABASE_KEY,
44
  "Authorization": f"Bearer {SUPABASE_KEY}",
@@ -47,10 +48,9 @@ def get_faq_from_supabase(uid):
47
  try:
48
  r = requests.get(url, headers=headers)
49
  r.raise_for_status()
50
- data = r.json()
51
- return [{"q": d["question"], "a": d["answer"]} for d in data]
52
  except Exception as e:
53
- print("โŒ Supabase error:", e)
54
  return []
55
 
56
  # ๐Ÿ”ฎ Endpoint prediksi jawaban dari pertanyaan user
@@ -58,26 +58,94 @@ def get_faq_from_supabase(uid):
58
  @limiter.limit("5/minute")
59
  async def predict(request: Request):
60
  body = await request.json()
61
- uid, question = body.get("data", [None, None])
62
 
63
- if not uid or not question:
64
- return {"data": ["UID atau pertanyaan tidak valid."]}
65
 
66
- faqs = get_faq_from_supabase(uid)
 
67
  if not faqs:
68
- return {"data": ["FAQ tidak ditemukan untuk UID ini."]}
69
 
70
- questions = [f["q"] for f in faqs]
71
- answers = [f["a"] for f in faqs]
 
72
 
73
- embeddings = model.encode(questions, convert_to_tensor=True)
74
- query_embedding = model.encode(question, convert_to_tensor=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
 
76
- similarity = util.pytorch_cos_sim(query_embedding, embeddings)
77
- best_idx = torch.argmax(similarity).item()
 
 
 
 
 
 
 
 
 
 
 
 
78
 
79
- return {"data": [answers[best_idx]]}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
 
 
 
 
 
 
 
 
 
81
  # ๐Ÿงน Hapus satu pesan berdasarkan ID
82
  @app.post("/delete_chat")
83
  async def delete_chat(request: Request):
 
37
  model = SentenceTransformer("sentence-transformers/paraphrase-MiniLM-L3-v2")
38
 
39
  # ๐Ÿ” Ambil FAQ berdasarkan UID
40
+ def get_faq_from_supabase(admin_id):
41
+ """Ambil FAQ khusus untuk admin tertentu"""
42
+ url = f"{SUPABASE_URL}/rest/v1/faq_items?admin_id=eq.{admin_id}"
43
  headers = {
44
  "apikey": SUPABASE_KEY,
45
  "Authorization": f"Bearer {SUPABASE_KEY}",
 
48
  try:
49
  r = requests.get(url, headers=headers)
50
  r.raise_for_status()
51
+ return r.json()
 
52
  except Exception as e:
53
+ print(f"โŒ Error mengambil FAQ untuk admin {admin_id}:", e)
54
  return []
55
 
56
  # ๐Ÿ”ฎ Endpoint prediksi jawaban dari pertanyaan user
 
58
  @limiter.limit("5/minute")
59
  async def predict(request: Request):
60
  body = await request.json()
61
+ admin_id, question = body.get("data", [None, None]) # admin_id dari UID di link
62
 
63
+ if not admin_id or not question:
64
+ return {"data": ["Admin ID atau pertanyaan tidak valid."]}
65
 
66
+ # Ambil FAQ khusus admin ini saja
67
+ faqs = get_faq_from_supabase(admin_id)
68
  if not faqs:
69
+ return {"data": ["Maaf, belum ada FAQ yang tersedia."]}
70
 
71
+ # Proses pencarian jawaban
72
+ questions = [f["question"] for f in faqs]
73
+ answers = [f["answer"] for f in faqs]
74
 
75
+ try:
76
+ embeddings = model.encode(questions, convert_to_tensor=True)
77
+ query_embedding = model.encode(question, convert_to_tensor=True)
78
+ similarity = util.pytorch_cos_sim(query_embedding, embeddings)
79
+ best_idx = torch.argmax(similarity).item()
80
+
81
+ # Threshold similarity (minimal 0.5)
82
+ if similarity[0][best_idx] < 0.5:
83
+ return {"data": ["Maaf, saya tidak mengerti pertanyaan Anda."]}
84
+
85
+ return {"data": [answers[best_idx]]}
86
+ except Exception as e:
87
+ print("โŒ Error processing question:", e)
88
+ return {"data": ["Terjadi kesalahan saat memproses pertanyaan."]}
89
+
90
+ # Save chat
91
+ @app.post("/save_chat")
92
+ async def save_chat(request: Request):
93
+ body = await request.json()
94
+ admin_id = body.get("admin_id")
95
+ session_id = body.get("session_id")
96
+ is_bot = body.get("is_bot", False)
97
+ is_admin = body.get("is_admin", False)
98
+ message = body.get("message")
99
+
100
+ if not all([admin_id, session_id, message]):
101
+ return JSONResponse({"error": "Data tidak lengkap"}, status_code=400)
102
 
103
+ url = f"{SUPABASE_URL}/rest/v1/chat_logs"
104
+ headers = {
105
+ "apikey": SUPABASE_KEY,
106
+ "Authorization": f"Bearer {SUPABASE_KEY}",
107
+ "Content-Type": "application/json",
108
+ "Prefer": "return=representation"
109
+ }
110
+ payload = {
111
+ "admin_id": admin_id,
112
+ "session_id": session_id,
113
+ "is_bot": is_bot,
114
+ "is_admin": is_admin,
115
+ "message": message
116
+ }
117
 
118
+ try:
119
+ r = requests.post(url, json=payload, headers=headers)
120
+ r.raise_for_status()
121
+ return {"message": "Pesan berhasil disimpan", "id": r.json()[0]["id"]}
122
+ except Exception as e:
123
+ print("โŒ Gagal menyimpan pesan:", e)
124
+ return JSONResponse({"error": "Gagal menyimpan pesan"}, status_code=500)
125
+
126
+ # Chat history
127
+ @app.get("/chat_history")
128
+ async def get_chat_history(request: Request, admin_id: str, session_id: str):
129
+ """Ambil history chat spesifik untuk sesi ini"""
130
+ url = f"{SUPABASE_URL}/rest/v1/chat_logs"
131
+ params = {
132
+ "admin_id": f"eq.{admin_id}",
133
+ "or": f"(session_id.eq.{session_id},is_bot.eq.true)",
134
+ "order": "created_at.asc"
135
+ }
136
+ headers = {
137
+ "apikey": SUPABASE_KEY,
138
+ "Authorization": f"Bearer {SUPABASE_KEY}"
139
+ }
140
 
141
+ try:
142
+ r = requests.get(url, params=params, headers=headers)
143
+ r.raise_for_status()
144
+ return r.json()
145
+ except Exception as e:
146
+ print(f"โŒ Error mengambil history untuk {session_id}:", e)
147
+ return JSONResponse({"error": "Gagal mengambil history"}, status_code=500)
148
+
149
  # ๐Ÿงน Hapus satu pesan berdasarkan ID
150
  @app.post("/delete_chat")
151
  async def delete_chat(request: Request):