mirror of
https://github.com/Sea-Haven-Industries/afterhours-shift-manager.git
synced 2026-09-30 19:33:12 +00:00
Unhandled errors and timeout warnings go to Sentry when SENTRY_DSN is set; Slack and 3CX secrets are stripped before send.
76 lines
2.3 KiB
Python
76 lines
2.3 KiB
Python
"""Lambda handler — updates 3CX queue routing based on who's on shift.
|
|
|
|
Triggered by EventBridge at 8am ET daily and 5pm ET on weekends.
|
|
Also invoked directly by the Slack bot for same-day shift changes.
|
|
"""
|
|
|
|
import json
|
|
import logging
|
|
import os
|
|
from datetime import datetime
|
|
from zoneinfo import ZoneInfo
|
|
|
|
import shared.sentry_init # noqa: F401
|
|
from shared.ring_scheduler import update_queue_routing
|
|
from shared.schedule import (
|
|
FALLBACK_EXTENSION,
|
|
WEEKEND_DAYS,
|
|
ShiftSchedule,
|
|
determine_shift_type,
|
|
)
|
|
from shared.secrets import get_secret
|
|
|
|
logger = logging.getLogger()
|
|
logger.setLevel(logging.INFO)
|
|
|
|
EASTERN = ZoneInfo("America/New_York")
|
|
|
|
|
|
def handler(event, context):
|
|
now = datetime.now(EASTERN)
|
|
current_hour = now.hour
|
|
day_name = now.strftime("%A")
|
|
logger.info("Running queue scheduler at %s", now.isoformat())
|
|
|
|
force = event.get("force", False)
|
|
valid_hours = {8, 17} if day_name in WEEKEND_DAYS else {8}
|
|
if not force and current_hour not in valid_hours:
|
|
logger.info(
|
|
"ET hour is %d on %s — skipping (wrong DST rule fired)",
|
|
current_hour,
|
|
day_name,
|
|
)
|
|
return {"skipped": True}
|
|
|
|
shift_type = determine_shift_type(now)
|
|
|
|
if event.get("override_extension"):
|
|
extension = event["override_extension"]
|
|
else:
|
|
schedule = ShiftSchedule()
|
|
date_str = now.strftime("%Y-%m-%d")
|
|
ext, _name, source = schedule.resolve_shift(date_str, day_name, shift_type)
|
|
extension = ext if source != "available" else FALLBACK_EXTENSION
|
|
|
|
secret_prefix = os.environ["TCX_SECRET_PREFIX"]
|
|
try:
|
|
result = update_queue_routing(
|
|
extension=extension,
|
|
queue_number=os.environ["QUEUE_NUMBER"],
|
|
domain=get_secret(f"{secret_prefix}domain"),
|
|
client_id=get_secret(f"{secret_prefix}client-id"),
|
|
client_secret=get_secret(f"{secret_prefix}client-secret"),
|
|
)
|
|
except Exception:
|
|
logger.exception("Failed to update 3CX queue routing")
|
|
return {"error": True, "date": now.strftime("%Y-%m-%d"), "day": day_name}
|
|
|
|
result.update(
|
|
{
|
|
"date": now.strftime("%Y-%m-%d"),
|
|
"day": day_name,
|
|
"shift_type": shift_type,
|
|
}
|
|
)
|
|
logger.info("Result: %s", json.dumps(result))
|
|
return result
|