send SMS
Build, push image, and notify Watchtower / build-image (push) Successful in 44s
Build, push image, and notify Watchtower / notify (push) Successful in 12s

This commit is contained in:
2026-08-17 15:19:35 +02:00
parent 5ae2dc1023
commit 3db52f1cad
2 changed files with 97 additions and 17 deletions
+58
View File
@@ -0,0 +1,58 @@
import os
import logging
from twilio.rest import Client
logger = logging.getLogger(__name__)
def send_alert_sms(to_phone: str, room_title: str, room_link: str = None, client_email: str = None) -> bool:
"""
Sends an SMS alert using Twilio notifying the client of an issue and support room creation.
"""
account_sid = os.environ.get("TWILIO_SID")
auth_token = os.environ.get("TWILIO_ACCOUNT_SECRET")
from_phone = os.environ.get("TWILIO_PHONE_NUMBER") # Requires your Twilio sender phone number
if not account_sid or not auth_token or not from_phone:
logger.error("Twilio environment variables (TWILIO_SID, TWILIO_ACCOUNT_SECRET, TWILIO_PHONE_NUMBER) missing.")
return False
if not to_phone:
logger.warning("No recipient phone number provided for SMS.")
return False
# --- PRINT LINK/INFO BEFORE SENDING ---
print("\n" + "="*50)
print(f"[Twilio] Preparing SMS for: {to_phone}")
print(f"[Twilio] Room Title: {room_title}")
if room_link:
print(f"[Twilio] Room Link: {room_link}")
else:
print(f"[Twilio] Link: Invitation email sent to {client_email or 'client inbox'}")
print("="*50 + "\n")
# --- BUILD SMS CONTENT ---
body = (
f"Alert: A technical issue occurred with your equipment/microwave. "
f"A support chat room '{room_title}' has been created to assist you.\n\n"
)
if room_link:
body += f"Join chat room: {room_link}\n"
if client_email:
body += f"An invitation link has also been sent to your email ({client_email})."
else:
body += "An invitation link has been sent to your inbox."
try:
client = Client(account_sid, auth_token)
message = client.messages.create(
body=body,
from_=from_phone,
to=to_phone
)
logger.info(f"SMS sent successfully to {to_phone}. Message SID: {message.sid}")
return True
except Exception as e:
logger.exception(f"Failed to send SMS via Twilio to {to_phone}: {e}")
return False
+39 -17
View File
@@ -13,6 +13,7 @@ from APIs.webex import WebexManager
from microwaveCookPlanner import MicrowaveCookPlanner
import safety_checker
import pymongo
from APIs.twilio import send_alert_sms
sys.path.insert(0, '..')
try:
@@ -43,6 +44,7 @@ WEBEX_CLIENT_SECRET = os.getenv("WEBEX_CLIENT_SECRET", "YOUR_WEBEX_CLIENT_SECRET
WEBEX_REDIRECT_URI = os.getenv("WEBEX_REDIRECT_URI", "https://smartwave.matthiasg.dev/oauth/callback")
WEBEX_TEAM_ID = os.getenv("WEBEX_TEAM_ID", "YOUR_WEBEX_TEAM_ID")
WEBEX_NINLUC_ID = os.getenv("WEBEX_NINLUC_ID", "YOUR_WEBEX_NINLUC_ID")
SAVEUP_TWILIO_API_TOKEN = os.getenv("SAVEUP_TWILIO_API_TOKEN", False)
# Ensure the camera image storage directory exists when the app starts
CAMERA_IMAGE_DIR = "storage/dishPhotos"
@@ -176,14 +178,12 @@ async def cooking_params():
def alert():
data = request.get_json() or {}
# 1. Inject a UTC timestamp so we can easily query the 3-minute window
# 1. Inject UTC timestamp
data["created_at"] = datetime.now(timezone.utc)
saved_alert = alert_collection.insert_one(data)
# Extract orchestrator_id from the incoming alert
orchestrator_id = data.get("orchestrator_id")
# Safely extract alert info (prevents errors if "alert" is missing)
alert_info = data.get("alert", {})
alert_type = alert_info.get("type", "Unknown")
alert_message = alert_info.get("message", "No message provided")
@@ -191,6 +191,7 @@ def alert():
# --- GET CLIENT METADATA ---
client_name = f"Unknown Client (Orchestrator {orchestrator_id})" if orchestrator_id else "Unknown Client"
client_email = None
client_phone = None
if orchestrator_id:
client_doc = client_collection.find_one({
@@ -204,25 +205,28 @@ def alert():
if client_doc:
client_name = client_doc.get("client_name", client_name)
client_email = client_doc.get("contact_info", {}).get("email")
contact_info = client_doc.get("contact_info", {})
client_email = contact_info.get("email")
client_phone = contact_info.get("phone") # Extract phone number for Twilio
# --- WEBEX ROOM LOGIC ---
webex_room_id = None
room_title = f"Support - {client_name}"
room_link = None
webex_status = "skipped"
# 2. Check if a room was created for this orchestrator in the last 3 minutes
three_minutes_ago = datetime.now(timezone.utc) - timedelta(minutes=3)
recent_alert = alert_collection.find_one({
"orchestrator_id": orchestrator_id,
"webex_room_id": {"$exists": True, "$ne": None},
"created_at": {"$gte": three_minutes_ago},
"_id": {"$ne": saved_alert.inserted_id} # Exclude the alert we just inserted
"_id": {"$ne": saved_alert.inserted_id}
}, sort=[("created_at", pymongo.DESCENDING)])
if recent_alert:
# A room was created recently -> Reuse it and just send a message
webex_room_id = recent_alert["webex_room_id"]
room_title = recent_alert.get("webex_room_title", room_title)
try:
webex_manager.send_alert_info_message(
room_id=webex_room_id,
@@ -236,40 +240,58 @@ def alert():
webex_status = f"message_failed: {str(e)}"
else:
# No recent room -> Create a new one
try:
# Assuming your modified create_support_room returns a dict with {"id": ...}
room_details = webex_manager.create_support_room(
client_name,
client_email,
alert_type,
alert_message,
str(saved_alert.inserted_id) # Cast ObjectId to string for JSON serialization
str(saved_alert.inserted_id)
)
# Extract ID based on whether your function returns a dict or just the ID string
webex_room_id = room_details["id"] if isinstance(room_details, dict) else room_details
if isinstance(room_details, dict):
webex_room_id = room_details.get("id")
room_title = room_details.get("title", room_title)
# Set room_link if your webex_manager returns meetingLink or custom URL
room_link = room_details.get("meetingLink") or f"webexteams://im?space={webex_room_id}"
else:
webex_room_id = room_details
room_link = f"webexteams://im?space={webex_room_id}"
webex_status = "created_new_room"
except Exception as e:
current_app.logger.exception("Failed to create Webex support room")
webex_status = f"creation_failed: {str(e)}"
# 3. Update the alert document with the Webex Room ID (whether new or reused)
# Update document with room details
if webex_room_id:
alert_collection.update_one(
{"_id": saved_alert.inserted_id},
{"$set": {"webex_room_id": webex_room_id}}
{"$set": {"webex_room_id": webex_room_id, "webex_room_title": room_title}}
)
# --- SEND SMS WITH DETAILS ---
# TODO: Add SMS logic here
# --- SEND SMS ---
sms_sent = False
if client_phone and not SAVEUP_TWILIO_API_TOKEN:
sms_sent = send_alert_sms(
to_phone=client_phone,
room_title=room_title,
room_link=room_link,
client_email=client_email
)
alert_collection.update_one(
{"_id": saved_alert.inserted_id},
{"$set": {"sms_sent": sms_sent}}
)
return jsonify({
"status": "success",
"message": "Alert saved",
"webex_room_id": webex_room_id,
"webex_status": webex_status
"webex_status": webex_status,
"sms_sent": sms_sent
}), 200