rairo commited on
Commit
19391c7
·
verified ·
1 Parent(s): 15e6bf4

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +64 -63
main.py CHANGED
@@ -956,17 +956,17 @@ import math
956
 
957
 
958
  # Fixed server code
 
959
  AGENT_ID = os.getenv("AGENT_ID", "agent_01jy1vv1hqe2b9x0yyp6ayrdxj")
960
  ELEVENLABS_API_KEY = os.getenv("ELEVENLABS_API_KEY")
961
 
962
  @app.route('/api/projects/<project_id>/initiate-call', methods=['POST'])
963
  def initiate_call(project_id):
964
  """
965
- Securely fetches a signed URL from ElevenLabs for the client-side SDK.
966
  """
967
  logger.info(f"[INITIATE] Received request for project: {project_id}")
968
 
969
- # Your real authentication logic should be active
970
  uid = verify_token(request.headers.get('Authorization'))
971
  if not uid:
972
  return jsonify({'error': 'Unauthorized'}), 401
@@ -975,87 +975,94 @@ def initiate_call(project_id):
975
  logger.error("[INITIATE] ELEVENLABS_API_KEY is not set on the server.")
976
  return jsonify({'error': 'Server configuration error.'}), 500
977
 
978
- # ✅ CRITICAL FIX: Since your agent is PUBLIC, you have two options:
979
-
980
- # OPTION 1: Use signed URL (recommended for production)
981
- url = f"https://api.elevenlabs.io/v1/convai/conversation/get-signed-url?agent_id={AGENT_ID}"
982
- headers = {"xi-api-key": ELEVENLABS_API_KEY}
 
983
 
984
  try:
985
- response = requests.get(url, headers=headers, timeout=15)
986
- response.raise_for_status()
987
-
988
- data = response.json()
989
- signed_url = data.get("signed_url")
990
-
991
- if not signed_url:
992
- logger.error("[INITIATE] ElevenLabs response missing 'signed_url'.")
993
- return jsonify({'error': 'Failed to retrieve session URL from provider.'}), 502
994
-
995
- logger.info("[INITIATE] Successfully retrieved signed URL.")
996
- return jsonify({"signed_url": signed_url}), 200
 
 
 
 
 
 
 
 
997
 
998
  except requests.exceptions.RequestException as e:
999
  logger.error(f"[INITIATE] Error calling ElevenLabs API: {e}")
1000
- return jsonify({'error': 'Could not connect to AI service provider.'}), 504
1001
-
1002
- # Alternative for public agents (simpler but less secure):
1003
- @app.route('/api/projects/<project_id>/initiate-call-simple', methods=['POST'])
1004
- def initiate_call_simple(project_id):
1005
- """
1006
- For public agents, you can also return the agent ID directly.
1007
- Less secure but simpler for testing.
1008
- """
1009
- logger.info(f"[INITIATE-SIMPLE] Received request for project: {project_id}")
1010
-
1011
- uid = verify_token(request.headers.get('Authorization'))
1012
- if not uid:
1013
- return jsonify({'error': 'Unauthorized'}), 401
1014
 
1015
- # For public agents, you can return the agent ID directly
1016
- return jsonify({"agent_id": AGENT_ID}), 200
1017
-
1018
- # Debug endpoint to test your setup
1019
  @app.route('/api/debug/test-agent', methods=['GET'])
1020
  def test_agent():
1021
- """Debug endpoint to test if agent exists and is accessible"""
1022
  if not ELEVENLABS_API_KEY:
1023
  return jsonify({'error': 'API key not set'}), 500
1024
 
1025
- # Test 1: Check if agent exists
1026
- agent_url = f"https://api.elevenlabs.io/v1/convai/agents/{AGENT_ID}"
1027
- headers = {"xi-api-key": ELEVENLABS_API_KEY}
 
1028
 
1029
  try:
 
 
 
 
1030
  agent_response = requests.get(agent_url, headers=headers, timeout=10)
 
 
 
 
1031
 
1032
- # Test 2: Try to get signed URL
1033
- signed_url_endpoint = f"https://api.elevenlabs.io/v1/convai/conversation/get-signed-url?agent_id={AGENT_ID}"
1034
- signed_response = requests.get(signed_url_endpoint, headers=headers, timeout=10)
 
 
 
 
1035
 
1036
- return jsonify({
1037
- 'agent_id': AGENT_ID,
1038
- 'agent_exists': {
1039
- 'status_code': agent_response.status_code,
1040
- 'response': agent_response.json() if agent_response.status_code == 200 else agent_response.text
1041
- },
1042
- 'signed_url_test': {
1043
- 'status_code': signed_response.status_code,
1044
- 'response': signed_response.json() if signed_response.status_code == 200 else signed_response.text
 
1045
  }
1046
- })
 
 
1047
  except Exception as e:
1048
  return jsonify({'error': str(e), 'agent_id': AGENT_ID})
1049
 
1050
  @app.route('/api/projects/<project_id>/log-call-usage', methods=['POST'])
1051
  def log_call_usage(project_id):
1052
  """
1053
- Calculates and deducts credits from a user's account in Firebase
1054
- after a call is completed. This is the production-ready version.
1055
  """
1056
  logger.info(f"[LOGGING] Received usage log for project: {project_id}")
1057
 
1058
- # Step 1: Authenticate the user and get their unique ID
1059
  uid = verify_token(request.headers.get('Authorization'))
1060
  if not uid:
1061
  return jsonify({'error': 'Unauthorized'}), 401
@@ -1066,14 +1073,12 @@ def log_call_usage(project_id):
1066
  if duration_seconds is None or not isinstance(duration_seconds, (int, float)):
1067
  return jsonify({'error': 'Invalid duration provided.'}), 400
1068
 
1069
- # Step 2: Calculate credit cost (3 credits per minute, always rounded up)
1070
  minutes = math.ceil(duration_seconds / 60)
1071
  cost = minutes * 3
1072
 
1073
  logger.info(f"[LOGGING] User '{uid}' call duration: {duration_seconds:.2f}s, rounded to {minutes} minute(s). Cost: {cost} credits.")
1074
 
1075
  try:
1076
- # Step 3: Perform the database transaction
1077
  user_ref = db_ref.child(f'users/{uid}')
1078
  user_data = user_ref.get()
1079
 
@@ -1082,16 +1087,12 @@ def log_call_usage(project_id):
1082
  return jsonify({'error': 'User not found.'}), 404
1083
 
1084
  current_credits = user_data.get('credits', 0)
1085
-
1086
- # Calculate the new balance, ensuring it doesn't go below zero.
1087
  new_credits = max(0, current_credits - cost)
1088
 
1089
- # Update the user's credit balance in Firebase
1090
  user_ref.update({'credits': new_credits})
1091
 
1092
  logger.info(f"[LOGGING] Successfully updated credits for user '{uid}'. Old: {current_credits}, New: {new_credits}")
1093
 
1094
- # Step 4: Return the successful response with the actual new balance
1095
  return jsonify({
1096
  "status": "success",
1097
  "creditsDeducted": cost,
 
956
 
957
 
958
  # Fixed server code
959
+
960
  AGENT_ID = os.getenv("AGENT_ID", "agent_01jy1vv1hqe2b9x0yyp6ayrdxj")
961
  ELEVENLABS_API_KEY = os.getenv("ELEVENLABS_API_KEY")
962
 
963
  @app.route('/api/projects/<project_id>/initiate-call', methods=['POST'])
964
  def initiate_call(project_id):
965
  """
966
+ Fixed version - handles the API endpoint issues shown in your debug
967
  """
968
  logger.info(f"[INITIATE] Received request for project: {project_id}")
969
 
 
970
  uid = verify_token(request.headers.get('Authorization'))
971
  if not uid:
972
  return jsonify({'error': 'Unauthorized'}), 401
 
975
  logger.error("[INITIATE] ELEVENLABS_API_KEY is not set on the server.")
976
  return jsonify({'error': 'Server configuration error.'}), 500
977
 
978
+ # ✅ FIX: Use the correct API endpoint structure
979
+ # The debug shows your agent exists, but the signed URL endpoint is different
980
+ headers = {
981
+ "xi-api-key": ELEVENLABS_API_KEY,
982
+ "Content-Type": "application/json"
983
+ }
984
 
985
  try:
986
+ # Method 1: Try the newer endpoint format
987
+ url = "https://api.elevenlabs.io/v1/convai/conversation"
988
+ payload = {"agent_id": AGENT_ID}
989
+
990
+ response = requests.post(url, headers=headers, json=payload, timeout=15)
991
+
992
+ if response.status_code == 200:
993
+ data = response.json()
994
+ conversation_id = data.get("conversation_id")
995
+ if conversation_id:
996
+ # Return the WebSocket URL format
997
+ ws_url = f"wss://api.elevenlabs.io/v1/convai/conversation/{conversation_id}"
998
+ logger.info("[INITIATE] Successfully created conversation session.")
999
+ return jsonify({"signed_url": ws_url}), 200
1000
+
1001
+ # Method 2: Try direct agent connection (fallback)
1002
+ logger.info("[INITIATE] Conversation creation failed, trying direct agent approach")
1003
+
1004
+ # For public agents, return agent ID directly - SDK will handle it
1005
+ return jsonify({"agent_id": AGENT_ID}), 200
1006
 
1007
  except requests.exceptions.RequestException as e:
1008
  logger.error(f"[INITIATE] Error calling ElevenLabs API: {e}")
1009
+ # Return agent ID as fallback
1010
+ return jsonify({"agent_id": AGENT_ID}), 200
 
 
 
 
 
 
 
 
 
 
 
 
1011
 
 
 
 
 
1012
  @app.route('/api/debug/test-agent', methods=['GET'])
1013
  def test_agent():
1014
+ """Fixed debug endpoint"""
1015
  if not ELEVENLABS_API_KEY:
1016
  return jsonify({'error': 'API key not set'}), 500
1017
 
1018
+ headers = {
1019
+ "xi-api-key": ELEVENLABS_API_KEY,
1020
+ "Content-Type": "application/json"
1021
+ }
1022
 
1023
  try:
1024
+ results = {'agent_id': AGENT_ID, 'tests': {}}
1025
+
1026
+ # Test 1: Check agent exists (this works per your debug)
1027
+ agent_url = f"https://api.elevenlabs.io/v1/convai/agents/{AGENT_ID}"
1028
  agent_response = requests.get(agent_url, headers=headers, timeout=10)
1029
+ results['tests']['agent_check'] = {
1030
+ 'status': agent_response.status_code,
1031
+ 'exists': agent_response.status_code == 200
1032
+ }
1033
 
1034
+ # Test 2: Try conversation creation
1035
+ conv_url = "https://api.elevenlabs.io/v1/convai/conversation"
1036
+ conv_response = requests.post(conv_url, headers=headers, json={"agent_id": AGENT_ID}, timeout=10)
1037
+ results['tests']['conversation_create'] = {
1038
+ 'status': conv_response.status_code,
1039
+ 'response': conv_response.json() if conv_response.status_code == 200 else conv_response.text[:200]
1040
+ }
1041
 
1042
+ # Test 3: List available agents to confirm access
1043
+ list_url = "https://api.elevenlabs.io/v1/convai/agents"
1044
+ list_response = requests.get(list_url, headers=headers, timeout=10)
1045
+ if list_response.status_code == 200:
1046
+ agents = list_response.json().get('agents', [])
1047
+ agent_ids = [a.get('agent_id') for a in agents]
1048
+ results['tests']['agent_list'] = {
1049
+ 'total_agents': len(agents),
1050
+ 'your_agent_found': AGENT_ID in agent_ids,
1051
+ 'first_few_agents': agent_ids[:3]
1052
  }
1053
+
1054
+ return jsonify(results)
1055
+
1056
  except Exception as e:
1057
  return jsonify({'error': str(e), 'agent_id': AGENT_ID})
1058
 
1059
  @app.route('/api/projects/<project_id>/log-call-usage', methods=['POST'])
1060
  def log_call_usage(project_id):
1061
  """
1062
+ No changes needed here - your original was fine
 
1063
  """
1064
  logger.info(f"[LOGGING] Received usage log for project: {project_id}")
1065
 
 
1066
  uid = verify_token(request.headers.get('Authorization'))
1067
  if not uid:
1068
  return jsonify({'error': 'Unauthorized'}), 401
 
1073
  if duration_seconds is None or not isinstance(duration_seconds, (int, float)):
1074
  return jsonify({'error': 'Invalid duration provided.'}), 400
1075
 
 
1076
  minutes = math.ceil(duration_seconds / 60)
1077
  cost = minutes * 3
1078
 
1079
  logger.info(f"[LOGGING] User '{uid}' call duration: {duration_seconds:.2f}s, rounded to {minutes} minute(s). Cost: {cost} credits.")
1080
 
1081
  try:
 
1082
  user_ref = db_ref.child(f'users/{uid}')
1083
  user_data = user_ref.get()
1084
 
 
1087
  return jsonify({'error': 'User not found.'}), 404
1088
 
1089
  current_credits = user_data.get('credits', 0)
 
 
1090
  new_credits = max(0, current_credits - cost)
1091
 
 
1092
  user_ref.update({'credits': new_credits})
1093
 
1094
  logger.info(f"[LOGGING] Successfully updated credits for user '{uid}'. Old: {current_credits}, New: {new_credits}")
1095
 
 
1096
  return jsonify({
1097
  "status": "success",
1098
  "creditsDeducted": cost,