CORVO-AI commited on
Commit
bdc56d4
·
verified ·
1 Parent(s): 43e5fec

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +322 -68
app.py CHANGED
@@ -9,7 +9,7 @@ app = Flask(__name__)
9
  GLOBAL_WORKSPACE_ID = None
10
  GLOBAL_BOT_ID = None
11
 
12
- # Empty cookie value (to be filled by the user)
13
  AUTH_COOKIE = "pscd=try.botpress.com; _hjSessionUser_2931810=eyJpZCI6ImQ2MGMzYjhkLTlkMjQtNTA0OS1hMzlmLWEzNmI0NzA0NzUxNCIsImNyZWF0ZWQiOjE3MzU3MTg0MDcwNTAsImV4aXN0aW5nIjp0cnVlfQ==; hubspotutk=75739411a4d011b2164c4f3d944ecb94; intercom-device-id-bjzkw2xf=afd0a36b-b229-44e3-828e-60483c80c10c; _hjSessionUser_3339867=eyJpZCI6IjU4ODlmMTY4LWRkNGEtNTJhZS1hZTUzLWZlYWQwM2ZmMTVjNyIsImNyZWF0ZWQiOjE3MzU3MTg1ODM4MDgsImV4aXN0aW5nIjp0cnVlfQ==; __hstc=59821234.75739411a4d011b2164c4f3d944ecb94.1735718442141.1746194848836.1746538539919.88; mp_1195923e954ce61d822842b5832047cd_mixpanel=%7B%22distinct_id%22%3A%20%22d403ad7b-ea73-4d29-b977-5fd95afd585c%22%2C%22%24device_id%22%3A%20%22d403ad7b-ea73-4d29-b977-5fd95afd585c%22%2C%22%24initial_referrer%22%3A%20%22https%3A%2F%2Fapp.botpress.cloud%2F%22%2C%22%24initial_referring_domain%22%3A%20%22app.botpress.cloud%22%2C%22__mps%22%3A%20%7B%7D%2C%22__mpso%22%3A%20%7B%22%24initial_referrer%22%3A%20%22https%3A%2F%2Fapp.botpress.cloud%2F%22%2C%22%24initial_referring_domain%22%3A%20%22app.botpress.cloud%22%7D%2C%22__mpus%22%3A%20%7B%7D%2C%22__mpa%22%3A%20%7B%7D%2C%22__mpu%22%3A%20%7B%7D%2C%22__mpr%22%3A%20%5B%5D%2C%22__mpap%22%3A%20%5B%5D%2C%22%24user_id%22%3A%20%22d403ad7b-ea73-4d29-b977-5fd95afd585c%22%7D; intercom-session-bjzkw2xf=TTdnZGNWUC9xNXMreE80NXhRZFNZS0pyUEdsbkJRc2JMcXdGZmcveVRPYkxZTmVnVnhqMUhJTWlDcEpVcWljeDZVYVVSblN4YnV5S0xBdWxDd2swQjZiaUZTeWl5M1psRmtoUWJwUU9FSFE9LS1Bay9zNldJTmVhUFdwMFNReFRmcXB3PT0=--68abc5394d7aab99748f3e451637cab5d9152a4c; _ga=GA1.2.1726154447.1735718383; _gid=GA1.2.1619749406.1746821934; _gat_UA-226900660-1=1; _gat_UA-226900660-2=1; _ga_W6YT9YSNLH=GS2.2.s1746821948$o89$g0$t1746821948$j0$l0$h0; _ga_CYSS87Q508=GS2.2.s1746821949$o89$g0$t1746821949$j0$l0$h0; _hjSession_2931810=eyJpZCI6IjA1YTlkMzY3LWNiZWEtNGQ3OC04YzNiLTEzNTFjNjkxYzViZSIsImMiOjE3NDY4MjE5NTU2NjYsInMiOjAsInIiOjAsInNiIjowLCJzciI6MCwic2UiOjAsImZzIjowLCJzcCI6MH0=; _ga_PCC6TBWJY6=GS2.1.s1746821926$o120$g1$t1746821960$j0$l0$h0; _ga_HKHSWES9V9=GS2.1.s1746821929$o120$g1$t1746821960$j29$l0$h193244206; csrf_token_bd9ac21c34b9f0915e733c3e5305d737d0722c1168be7376b889426b5ec2a298=pIDxu4npODUGEpo7JHVQrKZ4GFaa3U+3BpgxaV5hcVw=; ory_kratos_session=MTc0NjgyMjAyOHxfUmdMaVlTQXVfSmxlT1lJSGpyU2FhbjVUTHg0R0ZsQWgtVm00M3pHcXZwVG9yNW1qRDJheUFGaFZvNmFEUVdBOThQR014RjJJbmhUMmhIV1I1ME5UVHZkTDNpMUMtQlRjZ1ZTbE55M19Pb2dHTF9vQlJoSGlBQnRRWUp0M1ZUdnVvcENLeVhOTllWNk1zMk11bFVPOWFrTzJMTTdxMmVteUozVVRDMWE5TVIxbDgzU3dUY2VQaDBRWDN4bDJUVm8yUkZQa19sb09GbzlFZHF2MDFQcVR6bVVWVVpDLXVoQ1lXMEh2LV9Sd2VNZXM1cjM4TGZPVTJqdW5xNTBETTBDYkppU0xNU2xicUk3Z2EyMnFkVmdyQT09fEYiv7pXcfXVnpIFi4JLGgDObQAchyJCoAwGDSkFkoX7; ajs_user_id=d403ad7b-ea73-4d29-b977-5fd95afd585c; ajs_anonymous_id=cda6139d-cb82-4906-bfac-adaea115b097"
14
 
15
 
@@ -177,64 +177,195 @@ def delete_workspace(workspace_id):
177
 
178
 
179
  # -------------------------------------------------------------------
180
- # Flask Endpoint
181
  # -------------------------------------------------------------------
182
- @app.route("/chat", methods=["POST"])
183
- def chat_endpoint():
184
  """
185
- Expects JSON with:
186
- {
187
- "audio_url": "string" (required)
 
 
 
 
 
 
188
  }
189
- Returns JSON with:
190
- {
191
- "assistant_response": "string" (transcription result)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
192
  }
193
- """
194
- global GLOBAL_WORKSPACE_ID, GLOBAL_BOT_ID
195
 
196
- # Parse JSON from request
197
- data = request.get_json(force=True)
198
- audio_url = data.get("audio_url", "")
199
 
200
- if not audio_url:
201
- return jsonify({"assistant_response": "Error: audio_url is required"}), 400
202
 
203
- # If we don't yet have a workspace or bot, create them
204
- if not GLOBAL_WORKSPACE_ID or not GLOBAL_BOT_ID:
205
- print("No existing IDs found. Creating new workspace and bot...")
206
- GLOBAL_WORKSPACE_ID = create_workspace()
207
- if GLOBAL_WORKSPACE_ID:
208
- GLOBAL_BOT_ID = create_bot(GLOBAL_WORKSPACE_ID)
209
 
210
- # If creation failed
211
- if not GLOBAL_WORKSPACE_ID or not GLOBAL_BOT_ID:
212
- return jsonify({"assistant_response": "I'm currently unavailable. Please try again later."}), 500
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
213
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
214
  # Prepare the headers
215
  headers = {
216
  "User-Agent": "Mozilla/5.0",
217
- "x-bot-id": GLOBAL_BOT_ID,
218
  "Content-Type": "application/json",
219
  "Cookie": AUTH_COOKIE
220
  }
221
 
222
- # Use the transcription payload
 
 
 
 
223
  payload = {
224
  "type": "openai:transcribeAudio",
225
  "input": {
226
- "fileUrl": audio_url,
227
- "language": "",
228
- "prompt": "get all text from this Audio",
229
- "temperature": 0
230
  }
231
  }
232
 
233
- print(f"Processing audio transcription request with URL: {audio_url}")
234
-
235
  botpress_url = "https://api.botpress.cloud/v1/chat/actions"
236
  max_retries = 3
237
- timeout = 120 # Increased timeout for long messages
238
 
239
  # Flag to track if we need to create new IDs
240
  need_new_ids = False
@@ -242,20 +373,24 @@ def chat_endpoint():
242
  # Attempt to send the request
243
  for attempt in range(max_retries):
244
  try:
245
- print(f"Attempt {attempt+1}: Sending request to Botpress API with bot_id={GLOBAL_BOT_ID}, workspace_id={GLOBAL_WORKSPACE_ID}")
 
 
 
246
  response = requests.post(botpress_url, json=payload, headers=headers, timeout=timeout)
247
 
248
  # If successful (200)
249
  if response.status_code == 200:
250
  data = response.json()
251
 
252
- # For audio transcription, extract the full text from all segments
253
  segments = data.get('output', {}).get('segments', [])
254
- full_transcript = " ".join([segment.get('text', '').strip() for segment in segments])
 
255
  print(f"Successfully received transcription from Botpress API")
256
- return jsonify({"assistant_response": full_transcript})
257
 
258
- # Handle 403 error (authentication/authorization issue)
259
  elif response.status_code in [403, 404]:
260
  print(f"Received {response.status_code} error. Need to create new IDs.")
261
  need_new_ids = True
@@ -264,7 +399,7 @@ def chat_endpoint():
264
  # Handle network errors or timeouts (just retry)
265
  elif response.status_code in [443, 408, 502, 503, 504]:
266
  print(f"Received error {response.status_code}. Retrying...")
267
- time.sleep(3) # Wait before retrying
268
  continue
269
 
270
  # Any other error status code
@@ -274,72 +409,191 @@ def chat_endpoint():
274
  time.sleep(2)
275
  continue
276
  else:
277
- return jsonify({"assistant_response": f"Unable to get a response (Error {response.status_code})."})
278
 
279
  except requests.exceptions.Timeout:
280
- print(f"Request timed out. Retrying...")
281
  if attempt < max_retries - 1:
282
- time.sleep(2)
283
  continue
284
  else:
285
- return jsonify({"assistant_response": "The request is taking too long to process. Please try again."})
286
 
287
  except Exception as e:
288
- print(f"Error during request: {str(e)}")
289
  if attempt < max_retries - 1:
290
- time.sleep(2)
291
  continue
292
  else:
293
- return jsonify({"assistant_response": f"Unable to process the request: {str(e)}"})
294
 
295
  # If we need new IDs, create them and try again
296
  if need_new_ids:
297
- print("Creating new workspace and bot IDs...")
298
 
299
  # First, try to clean up old resources
300
- if GLOBAL_BOT_ID and GLOBAL_WORKSPACE_ID:
301
- delete_bot(GLOBAL_BOT_ID, GLOBAL_WORKSPACE_ID)
302
- delete_workspace(GLOBAL_WORKSPACE_ID)
303
 
304
  # Create new resources
305
  new_workspace_id = create_workspace()
306
  if not new_workspace_id:
307
- return jsonify({"assistant_response": "Failed to create a new workspace. Please try again later."})
308
 
309
  new_bot_id = create_bot(new_workspace_id)
310
  if not new_bot_id:
311
- return jsonify({"assistant_response": "Failed to create a new bot. Please try again later."})
312
-
313
- # Update global IDs
314
- GLOBAL_BOT_ID = new_bot_id
315
- GLOBAL_WORKSPACE_ID = new_workspace_id
316
 
317
  # Update headers with new bot ID
318
  headers["x-bot-id"] = new_bot_id
319
 
320
  # Try one more time with the new IDs
321
  try:
322
- print(f"Retrying with new bot_id={new_bot_id}, workspace_id={new_workspace_id}")
323
  retry_response = requests.post(botpress_url, json=payload, headers=headers, timeout=timeout)
324
 
325
  if retry_response.status_code == 200:
326
  data = retry_response.json()
327
-
328
- # For audio transcription, extract the full text from all segments
329
  segments = data.get('output', {}).get('segments', [])
330
- full_transcript = " ".join([segment.get('text', '').strip() for segment in segments])
331
  print(f"Successfully received transcription with new IDs")
332
- return jsonify({"assistant_response": full_transcript})
333
  else:
334
- print(f"Failed with new IDs: {retry_response.status_code}, {retry_response.text}")
335
- return jsonify({"assistant_response": "Unable to get a response with new credentials."})
336
 
337
  except Exception as e:
338
- print(f"Error with new IDs: {str(e)}")
339
- return jsonify({"assistant_response": f"Unable to get a response with new credentials: {str(e)}"})
340
 
341
  # Should not reach here due to the handling in the loop
342
- return jsonify({"assistant_response": "Unable to process the request."})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
343
 
344
 
345
  # -------------------------------------------------------------------
 
9
  GLOBAL_WORKSPACE_ID = None
10
  GLOBAL_BOT_ID = None
11
 
12
+ # Empty cookie value
13
  AUTH_COOKIE = "pscd=try.botpress.com; _hjSessionUser_2931810=eyJpZCI6ImQ2MGMzYjhkLTlkMjQtNTA0OS1hMzlmLWEzNmI0NzA0NzUxNCIsImNyZWF0ZWQiOjE3MzU3MTg0MDcwNTAsImV4aXN0aW5nIjp0cnVlfQ==; hubspotutk=75739411a4d011b2164c4f3d944ecb94; intercom-device-id-bjzkw2xf=afd0a36b-b229-44e3-828e-60483c80c10c; _hjSessionUser_3339867=eyJpZCI6IjU4ODlmMTY4LWRkNGEtNTJhZS1hZTUzLWZlYWQwM2ZmMTVjNyIsImNyZWF0ZWQiOjE3MzU3MTg1ODM4MDgsImV4aXN0aW5nIjp0cnVlfQ==; __hstc=59821234.75739411a4d011b2164c4f3d944ecb94.1735718442141.1746194848836.1746538539919.88; mp_1195923e954ce61d822842b5832047cd_mixpanel=%7B%22distinct_id%22%3A%20%22d403ad7b-ea73-4d29-b977-5fd95afd585c%22%2C%22%24device_id%22%3A%20%22d403ad7b-ea73-4d29-b977-5fd95afd585c%22%2C%22%24initial_referrer%22%3A%20%22https%3A%2F%2Fapp.botpress.cloud%2F%22%2C%22%24initial_referring_domain%22%3A%20%22app.botpress.cloud%22%2C%22__mps%22%3A%20%7B%7D%2C%22__mpso%22%3A%20%7B%22%24initial_referrer%22%3A%20%22https%3A%2F%2Fapp.botpress.cloud%2F%22%2C%22%24initial_referring_domain%22%3A%20%22app.botpress.cloud%22%7D%2C%22__mpus%22%3A%20%7B%7D%2C%22__mpa%22%3A%20%7B%7D%2C%22__mpu%22%3A%20%7B%7D%2C%22__mpr%22%3A%20%5B%5D%2C%22__mpap%22%3A%20%5B%5D%2C%22%24user_id%22%3A%20%22d403ad7b-ea73-4d29-b977-5fd95afd585c%22%7D; intercom-session-bjzkw2xf=TTdnZGNWUC9xNXMreE80NXhRZFNZS0pyUEdsbkJRc2JMcXdGZmcveVRPYkxZTmVnVnhqMUhJTWlDcEpVcWljeDZVYVVSblN4YnV5S0xBdWxDd2swQjZiaUZTeWl5M1psRmtoUWJwUU9FSFE9LS1Bay9zNldJTmVhUFdwMFNReFRmcXB3PT0=--68abc5394d7aab99748f3e451637cab5d9152a4c; _ga=GA1.2.1726154447.1735718383; _gid=GA1.2.1619749406.1746821934; _gat_UA-226900660-1=1; _gat_UA-226900660-2=1; _ga_W6YT9YSNLH=GS2.2.s1746821948$o89$g0$t1746821948$j0$l0$h0; _ga_CYSS87Q508=GS2.2.s1746821949$o89$g0$t1746821949$j0$l0$h0; _hjSession_2931810=eyJpZCI6IjA1YTlkMzY3LWNiZWEtNGQ3OC04YzNiLTEzNTFjNjkxYzViZSIsImMiOjE3NDY4MjE5NTU2NjYsInMiOjAsInIiOjAsInNiIjowLCJzciI6MCwic2UiOjAsImZzIjowLCJzcCI6MH0=; _ga_PCC6TBWJY6=GS2.1.s1746821926$o120$g1$t1746821960$j0$l0$h0; _ga_HKHSWES9V9=GS2.1.s1746821929$o120$g1$t1746821960$j29$l0$h193244206; csrf_token_bd9ac21c34b9f0915e733c3e5305d737d0722c1168be7376b889426b5ec2a298=pIDxu4npODUGEpo7JHVQrKZ4GFaa3U+3BpgxaV5hcVw=; ory_kratos_session=MTc0NjgyMjAyOHxfUmdMaVlTQXVfSmxlT1lJSGpyU2FhbjVUTHg0R0ZsQWgtVm00M3pHcXZwVG9yNW1qRDJheUFGaFZvNmFEUVdBOThQR014RjJJbmhUMmhIV1I1ME5UVHZkTDNpMUMtQlRjZ1ZTbE55M19Pb2dHTF9vQlJoSGlBQnRRWUp0M1ZUdnVvcENLeVhOTllWNk1zMk11bFVPOWFrTzJMTTdxMmVteUozVVRDMWE5TVIxbDgzU3dUY2VQaDBRWDN4bDJUVm8yUkZQa19sb09GbzlFZHF2MDFQcVR6bVVWVVpDLXVoQ1lXMEh2LV9Sd2VNZXM1cjM4TGZPVTJqdW5xNTBETTBDYkppU0xNU2xicUk3Z2EyMnFkVmdyQT09fEYiv7pXcfXVnpIFi4JLGgDObQAchyJCoAwGDSkFkoX7; ajs_user_id=d403ad7b-ea73-4d29-b977-5fd95afd585c; ajs_anonymous_id=cda6139d-cb82-4906-bfac-adaea115b097"
14
 
15
 
 
177
 
178
 
179
  # -------------------------------------------------------------------
180
+ # Main function that calls the Botpress API endpoint
181
  # -------------------------------------------------------------------
182
+ def chat_with_assistant(user_input, chat_history, bot_id, workspace_id):
 
183
  """
184
+ Sends the user input and chat history to the Botpress API endpoint,
185
+ returns the assistant's response and (possibly updated) bot/workspace IDs.
186
+ """
187
+ # Prepare the headers
188
+ headers = {
189
+ "User-Agent": "Mozilla/5.0",
190
+ "x-bot-id": bot_id,
191
+ "Content-Type": "application/json",
192
+ "Cookie": AUTH_COOKIE
193
  }
194
+
195
+ # Process chat history into the format expected by the API
196
+ messages = []
197
+ system_prompt = ""
198
+ for msg in chat_history:
199
+ if msg["role"] == "system":
200
+ system_prompt = msg["content"]
201
+ else:
202
+ messages.append({
203
+ "role": msg["role"],
204
+ "content": msg["content"],
205
+ "type": "text"
206
+ })
207
+
208
+ # Add the latest user input if not already in chat history
209
+ if user_input and (not messages or messages[-1]["role"] != "user" or messages[-1]["content"] != user_input):
210
+ messages.append({
211
+ "role": "user",
212
+ "content": user_input,
213
+ "type": "text"
214
+ })
215
+
216
+ # Prepare the payload for the API
217
+ payload = {
218
+ "type": "openai:generateContent",
219
+ "input": {
220
+ "model": {
221
+ "id": "gpt-4.1-2025-04-14"
222
+ },
223
+ "systemPrompt": system_prompt,
224
+ "messages": messages,
225
+ "temperature": 0.9,
226
+ "topP": 0.95,
227
+ "debug": False,
228
+ }
229
  }
 
 
230
 
231
+ botpress_url = "https://api.botpress.cloud/v1/chat/actions"
232
+ max_retries = 3
233
+ timeout = 120 # Increased timeout for long messages
234
 
235
+ # Flag to track if we need to create new IDs
236
+ need_new_ids = False
237
 
238
+ # Attempt to send the request
239
+ for attempt in range(max_retries):
240
+ try:
241
+ print(f"Attempt {attempt+1}: Sending request to Botpress API with bot_id={bot_id}, workspace_id={workspace_id}")
242
+ response = requests.post(botpress_url, json=payload, headers=headers, timeout=timeout)
 
243
 
244
+ # If successful (200)
245
+ if response.status_code == 200:
246
+ data = response.json()
247
+ assistant_content = data.get('output', {}).get('choices', [{}])[0].get('content', '')
248
+ print(f"Successfully received response from Botpress API")
249
+ return assistant_content, bot_id, workspace_id
250
+
251
+ # Handle 403 error (authentication/authorization issue)
252
+ elif response.status_code == 403:
253
+ print(f"Received 403 error. Need to create new IDs.")
254
+ need_new_ids = True
255
+ break
256
+
257
+ elif response.status_code == 404:
258
+ print(f"Received 404 error. Need to create new IDs.")
259
+ need_new_ids = True
260
+ break
261
+
262
+ # Handle network errors or timeouts (just retry)
263
+ elif response.status_code in [443, 408, 502, 503, 504]:
264
+ print(f"Received error {response.status_code}. Retrying...")
265
+ time.sleep(3) # Wait before retrying
266
+ continue
267
+
268
+ # Any other error status code
269
+ else:
270
+ print(f"Received unexpected error: {response.status_code}, {response.text}")
271
+ if attempt < max_retries - 1:
272
+ time.sleep(2)
273
+ continue
274
+ else:
275
+ return f"Unable to get a response from the assistant (Error {response.status_code}).", bot_id, workspace_id
276
+
277
+ except requests.exceptions.Timeout:
278
+ print(f"Request timed out. Retrying...")
279
+ if attempt < max_retries - 1:
280
+ time.sleep(2)
281
+ continue
282
+ else:
283
+ return "The assistant is taking too long to respond. Please try again with a shorter message.", bot_id, workspace_id
284
+
285
+ except Exception as e:
286
+ print(f"Error during request: {str(e)}")
287
+ if attempt < max_retries - 1:
288
+ time.sleep(2)
289
+ continue
290
+ else:
291
+ return f"Unable to get a response from the assistant: {str(e)}", bot_id, workspace_id
292
+
293
+ # If we need new IDs, create them and try again
294
+ if need_new_ids:
295
+ print("Creating new workspace and bot IDs...")
296
+
297
+ # First, try to clean up old resources
298
+ if bot_id and workspace_id:
299
+ delete_bot(bot_id, workspace_id)
300
+ delete_workspace(workspace_id)
301
+
302
+ # Create new resources
303
+ new_workspace_id = create_workspace()
304
+ if not new_workspace_id:
305
+ return "Failed to create a new workspace. Please try again later.", bot_id, workspace_id
306
+
307
+ new_bot_id = create_bot(new_workspace_id)
308
+ if not new_bot_id:
309
+ return "Failed to create a new bot. Please try again later.", new_workspace_id, workspace_id
310
+
311
+ # Update headers with new bot ID
312
+ headers["x-bot-id"] = new_bot_id
313
 
314
+ # Try one more time with the new IDs
315
+ try:
316
+ print(f"Retrying with new bot_id={new_bot_id}, workspace_id={new_workspace_id}")
317
+ retry_response = requests.post(botpress_url, json=payload, headers=headers, timeout=timeout)
318
+
319
+ if retry_response.status_code == 200:
320
+ data = retry_response.json()
321
+ assistant_content = data.get('output', {}).get('choices', [{}])[0].get('content', '')
322
+ print(f"Successfully received response with new IDs")
323
+ return assistant_content, new_bot_id, new_workspace_id
324
+ else:
325
+ print(f"Failed with new IDs: {retry_response.status_code}, {retry_response.text}")
326
+ return f"Unable to get a response from the assistant with new credentials.", new_bot_id, new_workspace_id
327
+
328
+ except Exception as e:
329
+ print(f"Error with new IDs: {str(e)}")
330
+ return f"Unable to get a response from the assistant with new credentials: {str(e)}", new_bot_id, new_workspace_id
331
+
332
+ # Should not reach here due to the handling in the loop
333
+ return "Unable to get a response from the assistant.", bot_id, workspace_id
334
+
335
+
336
+ # -------------------------------------------------------------------
337
+ # Function to transcribe audio using the same API and error handling approach
338
+ # -------------------------------------------------------------------
339
+ def transcribe_audio(file_url, language="", prompt="get all text from this Audio", temperature=0, bot_id=None, workspace_id=None):
340
+ """
341
+ Sends an audio file URL to the Botpress API for transcription
342
+ Uses the same bot/workspace management as the chat function
343
+ """
344
  # Prepare the headers
345
  headers = {
346
  "User-Agent": "Mozilla/5.0",
 
347
  "Content-Type": "application/json",
348
  "Cookie": AUTH_COOKIE
349
  }
350
 
351
+ # Add bot ID to headers if available
352
+ if bot_id:
353
+ headers["x-bot-id"] = bot_id
354
+
355
+ # Prepare the payload for audio transcription
356
  payload = {
357
  "type": "openai:transcribeAudio",
358
  "input": {
359
+ "fileUrl": file_url,
360
+ "language": language,
361
+ "prompt": prompt,
362
+ "temperature": temperature
363
  }
364
  }
365
 
 
 
366
  botpress_url = "https://api.botpress.cloud/v1/chat/actions"
367
  max_retries = 3
368
+ timeout = 180 # Longer timeout for audio processing
369
 
370
  # Flag to track if we need to create new IDs
371
  need_new_ids = False
 
373
  # Attempt to send the request
374
  for attempt in range(max_retries):
375
  try:
376
+ print(f"Attempt {attempt+1}: Sending transcription request to Botpress API")
377
+ if bot_id:
378
+ print(f"Using bot_id={bot_id}, workspace_id={workspace_id}")
379
+
380
  response = requests.post(botpress_url, json=payload, headers=headers, timeout=timeout)
381
 
382
  # If successful (200)
383
  if response.status_code == 200:
384
  data = response.json()
385
 
386
+ # Extract the transcription text from all segments
387
  segments = data.get('output', {}).get('segments', [])
388
+ transcription = " ".join([segment.get('text', '').strip() for segment in segments])
389
+
390
  print(f"Successfully received transcription from Botpress API")
391
+ return transcription, data, bot_id, workspace_id
392
 
393
+ # Handle 403/404 errors (authentication/authorization issue)
394
  elif response.status_code in [403, 404]:
395
  print(f"Received {response.status_code} error. Need to create new IDs.")
396
  need_new_ids = True
 
399
  # Handle network errors or timeouts (just retry)
400
  elif response.status_code in [443, 408, 502, 503, 504]:
401
  print(f"Received error {response.status_code}. Retrying...")
402
+ time.sleep(3)
403
  continue
404
 
405
  # Any other error status code
 
409
  time.sleep(2)
410
  continue
411
  else:
412
+ return f"Unable to transcribe audio (Error {response.status_code}).", None, bot_id, workspace_id
413
 
414
  except requests.exceptions.Timeout:
415
+ print(f"Transcription request timed out. Retrying...")
416
  if attempt < max_retries - 1:
417
+ time.sleep(3)
418
  continue
419
  else:
420
+ return "The transcription is taking too long. Please try with a shorter audio file.", None, bot_id, workspace_id
421
 
422
  except Exception as e:
423
+ print(f"Error during transcription request: {str(e)}")
424
  if attempt < max_retries - 1:
425
+ time.sleep(3)
426
  continue
427
  else:
428
+ return f"Unable to transcribe audio: {str(e)}", None, bot_id, workspace_id
429
 
430
  # If we need new IDs, create them and try again
431
  if need_new_ids:
432
+ print("Creating new workspace and bot IDs for transcription...")
433
 
434
  # First, try to clean up old resources
435
+ if bot_id and workspace_id:
436
+ delete_bot(bot_id, workspace_id)
437
+ delete_workspace(workspace_id)
438
 
439
  # Create new resources
440
  new_workspace_id = create_workspace()
441
  if not new_workspace_id:
442
+ return "Failed to create a new workspace for transcription. Please try again later.", None, bot_id, workspace_id
443
 
444
  new_bot_id = create_bot(new_workspace_id)
445
  if not new_bot_id:
446
+ return "Failed to create a new bot for transcription. Please try again later.", None, new_workspace_id, workspace_id
 
 
 
 
447
 
448
  # Update headers with new bot ID
449
  headers["x-bot-id"] = new_bot_id
450
 
451
  # Try one more time with the new IDs
452
  try:
453
+ print(f"Retrying transcription with new bot_id={new_bot_id}, workspace_id={new_workspace_id}")
454
  retry_response = requests.post(botpress_url, json=payload, headers=headers, timeout=timeout)
455
 
456
  if retry_response.status_code == 200:
457
  data = retry_response.json()
 
 
458
  segments = data.get('output', {}).get('segments', [])
459
+ transcription = " ".join([segment.get('text', '').strip() for segment in segments])
460
  print(f"Successfully received transcription with new IDs")
461
+ return transcription, data, new_bot_id, new_workspace_id
462
  else:
463
+ print(f"Transcription failed with new IDs: {retry_response.status_code}, {retry_response.text}")
464
+ return f"Unable to transcribe audio with new credentials.", None, new_bot_id, new_workspace_id
465
 
466
  except Exception as e:
467
+ print(f"Error with new IDs during transcription: {str(e)}")
468
+ return f"Unable to transcribe audio with new credentials: {str(e)}", None, new_bot_id, new_workspace_id
469
 
470
  # Should not reach here due to the handling in the loop
471
+ return "Unable to transcribe audio.", None, bot_id, workspace_id
472
+
473
+
474
+ # -------------------------------------------------------------------
475
+ # Flask Endpoints
476
+ # -------------------------------------------------------------------
477
+ @app.route("/chat", methods=["POST"])
478
+ def chat_endpoint():
479
+ """
480
+ Expects JSON with:
481
+ {
482
+ "user_input": "string",
483
+ "chat_history": [
484
+ {"role": "system", "content": "..."},
485
+ {"role": "user", "content": "..."},
486
+ ...
487
+ ]
488
+ }
489
+ Returns JSON with:
490
+ {
491
+ "assistant_response": "string"
492
+ }
493
+ """
494
+ global GLOBAL_WORKSPACE_ID, GLOBAL_BOT_ID
495
+
496
+ # Parse JSON from request
497
+ data = request.get_json(force=True)
498
+ user_input = data.get("user_input", "")
499
+ chat_history = data.get("chat_history", [])
500
+
501
+ # If we don't yet have a workspace or bot, create them
502
+ if not GLOBAL_WORKSPACE_ID or not GLOBAL_BOT_ID:
503
+ print("No existing IDs found. Creating new workspace and bot...")
504
+ GLOBAL_WORKSPACE_ID = create_workspace()
505
+ if GLOBAL_WORKSPACE_ID:
506
+ GLOBAL_BOT_ID = create_bot(GLOBAL_WORKSPACE_ID)
507
+
508
+ # If creation failed
509
+ if not GLOBAL_WORKSPACE_ID or not GLOBAL_BOT_ID:
510
+ return jsonify({"assistant_response": "I'm currently unavailable. Please try again later."}), 500
511
+
512
+ # Call our function that interacts with Botpress API
513
+ print(f"Sending chat request with existing bot_id={GLOBAL_BOT_ID}, workspace_id={GLOBAL_WORKSPACE_ID}")
514
+ assistant_response, updated_bot_id, updated_workspace_id = chat_with_assistant(
515
+ user_input,
516
+ chat_history,
517
+ GLOBAL_BOT_ID,
518
+ GLOBAL_WORKSPACE_ID
519
+ )
520
+
521
+ # Update global IDs if they changed
522
+ if updated_bot_id != GLOBAL_BOT_ID or updated_workspace_id != GLOBAL_WORKSPACE_ID:
523
+ print(f"Updating global IDs: bot_id={updated_bot_id}, workspace_id={updated_workspace_id}")
524
+ GLOBAL_BOT_ID = updated_bot_id
525
+ GLOBAL_WORKSPACE_ID = updated_workspace_id
526
+
527
+ return jsonify({"assistant_response": assistant_response})
528
+
529
+
530
+ @app.route("/transcribe", methods=["POST"])
531
+ def transcribe_endpoint():
532
+ """
533
+ Expects JSON with:
534
+ {
535
+ "file_url": "string",
536
+ "language": "string" (optional),
537
+ "prompt": "string" (optional),
538
+ "temperature": float (optional),
539
+ "include_full_response": boolean (optional)
540
+ }
541
+ Returns JSON with:
542
+ {
543
+ "transcription": "string",
544
+ "full_response": {} (optional)
545
+ }
546
+ """
547
+ global GLOBAL_WORKSPACE_ID, GLOBAL_BOT_ID
548
+
549
+ # Parse JSON from request
550
+ data = request.get_json(force=True)
551
+ file_url = data.get("file_url", "")
552
+ language = data.get("language", "")
553
+ prompt = data.get("prompt", "get all text from this Audio")
554
+ temperature = data.get("temperature", 0)
555
+ include_full_response = data.get("include_full_response", False)
556
+
557
+ # Validate input
558
+ if not file_url:
559
+ return jsonify({"error": "Missing file_url parameter"}), 400
560
+
561
+ # If we don't yet have a workspace or bot, create them
562
+ if not GLOBAL_WORKSPACE_ID or not GLOBAL_BOT_ID:
563
+ print("No existing IDs found for transcription. Creating new workspace and bot...")
564
+ GLOBAL_WORKSPACE_ID = create_workspace()
565
+ if GLOBAL_WORKSPACE_ID:
566
+ GLOBAL_BOT_ID = create_bot(GLOBAL_WORKSPACE_ID)
567
+
568
+ # If creation failed
569
+ if not GLOBAL_WORKSPACE_ID or not GLOBAL_BOT_ID:
570
+ return jsonify({"transcription": "Transcription service is currently unavailable. Please try again later."}), 500
571
+
572
+ # Call our function that interacts with Botpress API for transcription
573
+ print(f"Sending transcription request with existing bot_id={GLOBAL_BOT_ID}, workspace_id={GLOBAL_WORKSPACE_ID}")
574
+ transcription, full_data, updated_bot_id, updated_workspace_id = transcribe_audio(
575
+ file_url,
576
+ language,
577
+ prompt,
578
+ temperature,
579
+ GLOBAL_BOT_ID,
580
+ GLOBAL_WORKSPACE_ID
581
+ )
582
+
583
+ # Update global IDs if they changed
584
+ if updated_bot_id != GLOBAL_BOT_ID or updated_workspace_id != GLOBAL_WORKSPACE_ID:
585
+ print(f"Updating global IDs after transcription: bot_id={updated_bot_id}, workspace_id={updated_workspace_id}")
586
+ GLOBAL_BOT_ID = updated_bot_id
587
+ GLOBAL_WORKSPACE_ID = updated_workspace_id
588
+
589
+ # Prepare the response
590
+ response = {"transcription": transcription}
591
+
592
+ # Include full response data if requested
593
+ if include_full_response and full_data:
594
+ response["full_response"] = full_data
595
+
596
+ return jsonify(response)
597
 
598
 
599
  # -------------------------------------------------------------------