randomisedbackend2 / twillio_gemini_api.py
akiko19191's picture
Upload folder using huggingface_hub
72eef4f verified
# app.py
import os
import requests # To download the audio file from Twilio's URL
from flask import Flask, request
from dotenv import load_dotenv
# Use the new top-level import and types
from google import genai
from google.genai import types
from twilio.twiml.messaging_response import MessagingResponse
# --- Define Calculator Functions for the Model to Use ---
# The SDK uses the function signature (name, parameters) and docstring
# to tell the model how and when to use these tools.
def add(a: float, b: float):
"""
Adds two numbers together.
Args:
a: The first number.
b: The second number.
"""
print(f"Tool Call: add(a={a}, b={b})")
return a + b
def subtract(a: float, b: float):
"""
Subtracts the second number from the first.
Args:
a: The number to subtract from.
b: The number to subtract.
"""
print(f"Tool Call: subtract(a={a}, b={b})")
return a - b
def multiply(a: float, b: float):
"""
Multiplies two numbers.
Args:
a: The first number.
b: The second number.
"""
print(f"Tool Call: multiply(a={a}, b={b})")
return a * b
def divide(a: float, b: float):
"""
Divides the first number by the second.
Args:
a: The numerator.
b: The denominator.
"""
print(f"Tool Call: divide(a={a}, b={b})")
if b == 0:
return "Error: Cannot divide by zero."
return a / b
# A list of all the functions the model can call
calculator_tools = [add, subtract, multiply, divide]
# --- Initialize Flask App and APIs ---
# Load environment variables from .env file
load_dotenv(r"C:\Users\Vaibhav Arora\Documents\MyExperimentsandCodes\APPS_WEBSITES\CANADA_WHOLESALE_PROJECT\GITHUB_REPOS\mvp-vue\wholesale-grocery-app\AIAPPS\.env")
app = Flask(__name__)
# Configure the Gemini API and initialize the client
try:
client = genai.Client(api_key=os.environ.get("GEMINI_API_KEY"))
print("Gemini client and calculator tools initialized successfully.")
except Exception as e:
print(f"Error initializing Gemini client: {e}")
client = None
# --- Define the Webhook Endpoint ---
@app.route("/sms", methods=['POST'])
def sms_reply():
"""Respond to incoming text or audio messages, using calculator functions if needed."""
twilio_resp = MessagingResponse()
if not client:
twilio_resp.message("The AI client is not configured correctly. Please check the server logs.")
return str(twilio_resp)
# Prepare the contents list for the Gemini API call
contents = []
# Check if the incoming message contains media
num_media = int(request.values.get('NumMedia', 0))
if num_media > 0:
media_url = request.values.get('MediaUrl0')
mime_type = request.values.get('MediaContentType0')
# Process only if the media is audio
if 'audio' in mime_type:
print(f"Received audio message. URL: {media_url}, MIME Type: {mime_type}")
# Download the audio file from the Twilio URL
audio_response = requests.get(media_url)
if audio_response.status_code == 200:
audio_bytes = audio_response.content
audio_part = types.Part.from_bytes(data=audio_bytes, mime_type=mime_type)
prompt = "Please transcribe this audio. If it contains a calculation or a question, please answer it."
contents = [prompt, audio_part]
else:
error_message = "Sorry, I couldn't download the audio file to process it. Please try again."
twilio_resp.message(error_message)
return str(twilio_resp)
else:
# Handle non-audio media like images or videos
twilio_resp.message("Sorry, I can only process text and audio messages.")
return str(twilio_resp)
else:
# Fallback to text message processing
incoming_msg = request.values.get('Body', '').strip()
print(f"Received text message: '{incoming_msg}'")
if not incoming_msg:
twilio_resp.message("Please send a text or audio message to get a response.")
return str(twilio_resp)
contents = [incoming_msg]
if not contents:
twilio_resp.message("Could not determine content to process. Please send a message.")
return str(twilio_resp)
try:
print("Sending content to Gemini with calculator tools...")
# Configure the request to use our calculator functions
config = types.GenerateContentConfig(tools=calculator_tools)
# The SDK handles the multi-turn process for function calling automatically
gemini_response = client.models.generate_content(
model="gemini-2.5-flash",
contents=contents, # This will contain either text or [prompt, audio_part]
config=config,
)
# This is the final text answer after any function calls have been resolved.
ai_answer = gemini_response.text
print(f"Gemini final response: '{ai_answer}'")
# Add the Gemini response to the TwiML message
twilio_resp.message(ai_answer)
except Exception as e:
print(f"An error occurred with the Gemini API: {e}")
# Send a user-friendly error message
error_message = "Sorry, I'm having trouble connecting to my brain right now. Please try again later."
twilio_resp.message(error_message)
return str(twilio_resp)
# --- Run the Flask App ---
if __name__ == "__main__":
app.run(debug=True, port=5000)