ethiotech4848 commited on
Commit
d7d48ab
·
verified ·
1 Parent(s): a4cca85

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +31 -32
app.py CHANGED
@@ -21,9 +21,9 @@ client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
21
  client.base_url = os.getenv("OPENAI_API_BASE", "https://api.openai.com/v1")
22
 
23
  # Chatwoot config
24
- CHATWOOT_BASE_URL = os.getenv("CHATWOOT_BASE_URL") # e.g., https://app.chatwoot.com
25
- CHATWOOT_API_KEY = os.getenv("CHATWOOT_API_KEY") # API Access Token of bot
26
- CHATWOOT_ACCOUNT_ID = os.getenv("CHATWOOT_ACCOUNT_ID") # Account ID (integer)
27
 
28
  # Global set to track conversations where AI should stop replying
29
  stop_reply_conversations = set()
@@ -37,44 +37,45 @@ async def ask(request: Request):
37
  account_id = payload.get("account", {}).get("id")
38
  sender_id = payload.get("sender", {}).get("id")
39
  conversation_id = payload.get("conversation", {}).get("id")
40
- sender_role = payload.get("sender", {}).get("role", "").lower() # e.g. "agent", "contact", "bot"
41
  message_content = payload.get("content", "").strip()
42
 
 
 
 
 
 
43
  # Only respond to incoming messages
44
  if message_type != "incoming":
45
  print("⚠️ Ignoring non-incoming messages")
46
  return {"status": "ignored"}
47
 
48
- # Ignore messages from bot itself to prevent loops
49
  if sender_id == account_id:
50
  print("⚠️ Ignoring message from bot itself")
51
  return {"status": "ignored"}
52
 
53
- # If human agent sends a message, stop AI replies for this conversation
54
  if sender_role == "agent":
55
- # If agent sends command to resume bot replies
56
  if message_content.lower() == "/botresume":
57
- if conversation_id in stop_reply_conversations:
58
- stop_reply_conversations.remove(conversation_id)
59
- print(f"ℹ️ Bot resumed for conversation {conversation_id} by human agent command.")
60
- await send_chatwoot_message(conversation_id, "Bot resumed and will reply to users now.")
61
- return {"status": "human takeover - bot resume command"}
62
-
63
- # Otherwise blacklist conversation to stop AI replies
64
- stop_reply_conversations.add(conversation_id)
65
- print(f"⚠️ Human agent message detected. Conversation {conversation_id} blacklisted for AI replies.")
66
- return {"status": "human takeover activated"}
67
 
68
- # If conversation is blacklisted, ignore user messages
69
  if conversation_id in stop_reply_conversations:
70
- print(f"⚠️ Conversation {conversation_id} is blacklisted, no AI reply sent.")
71
- return {"status": "ignored due to human takeover"}
72
 
73
- if not message_content or not conversation_id or not CHATWOOT_ACCOUNT_ID:
74
- print("❌ Missing message content, conversation ID, or account ID")
75
  return {"status": "invalid payload"}
76
 
77
- # Prepare OpenAI messages
78
  messages = [
79
  {"role": "system", "content": system_prompt},
80
  {"role": "user", "content": message_content},
@@ -93,14 +94,12 @@ async def ask(request: Request):
93
  print("❌ OpenAI Error:", e)
94
  answer = "Sorry, I'm having trouble answering right now."
95
 
96
- fallback_msg = "I'm not sure about that. Let me connect you with a human agent."
97
- if answer == fallback_msg:
98
  stop_reply_conversations.add(conversation_id)
99
- print(f"⚠️ Added conversation {conversation_id} to stop reply blacklist due to fallback answer.")
100
 
101
- # Send AI reply back to Chatwoot
102
  await send_chatwoot_message(conversation_id, answer)
103
-
104
  return {"status": "ok"}
105
 
106
 
@@ -114,12 +113,12 @@ async def send_chatwoot_message(conversation_id: str, content: str):
114
  }
115
  try:
116
  async with httpx.AsyncClient() as http:
117
- chatwoot_url = f"{CHATWOOT_BASE_URL}/api/v1/accounts/{CHATWOOT_ACCOUNT_ID}/conversations/{conversation_id}/messages"
118
- print("📤 Sending to Chatwoot:", chatwoot_url)
119
- print("📦 Payload to Chatwoot:", json.dumps(message_payload, indent=2))
120
 
121
  resp = await http.post(
122
- chatwoot_url,
123
  headers={
124
  "Content-Type": "application/json",
125
  "api_access_token": CHATWOOT_API_KEY,
 
21
  client.base_url = os.getenv("OPENAI_API_BASE", "https://api.openai.com/v1")
22
 
23
  # Chatwoot config
24
+ CHATWOOT_BASE_URL = os.getenv("CHATWOOT_BASE_URL")
25
+ CHATWOOT_API_KEY = os.getenv("CHATWOOT_API_KEY")
26
+ CHATWOOT_ACCOUNT_ID = int(os.getenv("CHATWOOT_ACCOUNT_ID", "123911")) # Defaulting to 123911
27
 
28
  # Global set to track conversations where AI should stop replying
29
  stop_reply_conversations = set()
 
37
  account_id = payload.get("account", {}).get("id")
38
  sender_id = payload.get("sender", {}).get("id")
39
  conversation_id = payload.get("conversation", {}).get("id")
40
+ sender_role = payload.get("sender", {}).get("role", "").lower()
41
  message_content = payload.get("content", "").strip()
42
 
43
+ # Stop if message is not from allowed account ID
44
+ if account_id != CHATWOOT_ACCOUNT_ID:
45
+ print(f"❌ Ignoring message from account ID {account_id} (only {CHATWOOT_ACCOUNT_ID} is allowed)")
46
+ return {"status": "ignored: invalid account"}
47
+
48
  # Only respond to incoming messages
49
  if message_type != "incoming":
50
  print("⚠️ Ignoring non-incoming messages")
51
  return {"status": "ignored"}
52
 
53
+ # Ignore messages from bot itself
54
  if sender_id == account_id:
55
  print("⚠️ Ignoring message from bot itself")
56
  return {"status": "ignored"}
57
 
58
+ # Human agent message: disable AI for this conversation
59
  if sender_role == "agent":
 
60
  if message_content.lower() == "/botresume":
61
+ stop_reply_conversations.discard(conversation_id)
62
+ print(f"ℹ️ Bot resumed for conversation {conversation_id}")
63
+ await send_chatwoot_message(conversation_id, "Bot resumed and will reply to users now.")
64
+ return {"status": "bot resumed"}
65
+ else:
66
+ stop_reply_conversations.add(conversation_id)
67
+ print(f"🚫 Human agent takeover. AI disabled for conversation {conversation_id}")
68
+ return {"status": "human takeover"}
 
 
69
 
 
70
  if conversation_id in stop_reply_conversations:
71
+ print(f"🚫 Conversation {conversation_id} blacklisted. No AI reply.")
72
+ return {"status": "ignored: blacklisted"}
73
 
74
+ if not message_content or not conversation_id:
75
+ print("❌ Missing essential data")
76
  return {"status": "invalid payload"}
77
 
78
+ # Prepare and send to OpenAI
79
  messages = [
80
  {"role": "system", "content": system_prompt},
81
  {"role": "user", "content": message_content},
 
94
  print("❌ OpenAI Error:", e)
95
  answer = "Sorry, I'm having trouble answering right now."
96
 
97
+ fallback = "I'm not sure about that. Let me connect you with a human agent."
98
+ if answer == fallback:
99
  stop_reply_conversations.add(conversation_id)
100
+ print(f"🚫 Fallback triggered. Conversation {conversation_id} blacklisted.")
101
 
 
102
  await send_chatwoot_message(conversation_id, answer)
 
103
  return {"status": "ok"}
104
 
105
 
 
113
  }
114
  try:
115
  async with httpx.AsyncClient() as http:
116
+ url = f"{CHATWOOT_BASE_URL}/api/v1/accounts/{CHATWOOT_ACCOUNT_ID}/conversations/{conversation_id}/messages"
117
+ print("📤 Sending to Chatwoot:", url)
118
+ print("📦 Payload:", json.dumps(message_payload, indent=2))
119
 
120
  resp = await http.post(
121
+ url,
122
  headers={
123
  "Content-Type": "application/json",
124
  "api_access_token": CHATWOOT_API_KEY,