mirror of
https://github.com/dograh-hq/dograh.git
synced 2026-06-07 07:55:16 +02:00
* chore: remove old files * feat: ari outbound dialing * feat: add websocket configuration for ARI * feat: handling inbound calls * delete ext channel from redis on stasis end * fix: add lock in workflow run update, refactor _handle_stasis_start * chore: update submodule --------- Co-authored-by: Sabiha Khan <sabihak89@gmail.com>
149 lines
5 KiB
Python
149 lines
5 KiB
Python
"""
|
|
Factory for creating telephony providers.
|
|
Handles configuration loading from environment (OSS) or database (SaaS).
|
|
The providers themselves don't know or care where config comes from.
|
|
"""
|
|
|
|
from typing import Any, Dict, List, Type
|
|
|
|
from loguru import logger
|
|
|
|
from api.db import db_client
|
|
from api.enums import OrganizationConfigurationKey
|
|
from api.services.telephony.base import TelephonyProvider
|
|
from api.services.telephony.providers.ari_provider import ARIProvider
|
|
from api.services.telephony.providers.cloudonix_provider import CloudonixProvider
|
|
from api.services.telephony.providers.twilio_provider import TwilioProvider
|
|
from api.services.telephony.providers.vobiz_provider import VobizProvider
|
|
from api.services.telephony.providers.vonage_provider import VonageProvider
|
|
|
|
|
|
async def load_telephony_config(organization_id: int) -> Dict[str, Any]:
|
|
"""
|
|
Load telephony configuration from database.
|
|
|
|
Args:
|
|
organization_id: Organization ID for database config
|
|
|
|
Returns:
|
|
Configuration dictionary with provider type and credentials
|
|
|
|
Raises:
|
|
ValueError: If no configuration found for the organization
|
|
"""
|
|
if not organization_id:
|
|
raise ValueError("Organization ID is required to load telephony configuration")
|
|
|
|
logger.debug(f"Loading telephony config from database for org {organization_id}")
|
|
|
|
config = await db_client.get_configuration(
|
|
organization_id,
|
|
OrganizationConfigurationKey.TELEPHONY_CONFIGURATION.value,
|
|
)
|
|
|
|
if config and config.value:
|
|
# Simple single-provider format
|
|
provider = config.value.get("provider", "twilio")
|
|
|
|
if provider == "twilio":
|
|
return {
|
|
"provider": "twilio",
|
|
"account_sid": config.value.get("account_sid"),
|
|
"auth_token": config.value.get("auth_token"),
|
|
"from_numbers": config.value.get("from_numbers", []),
|
|
}
|
|
elif provider == "vonage":
|
|
return {
|
|
"provider": "vonage",
|
|
"application_id": config.value.get("application_id"),
|
|
"private_key": config.value.get("private_key"),
|
|
"api_key": config.value.get("api_key"),
|
|
"api_secret": config.value.get("api_secret"),
|
|
"from_numbers": config.value.get("from_numbers", []),
|
|
}
|
|
elif provider == "vobiz":
|
|
return {
|
|
"provider": "vobiz",
|
|
"auth_id": config.value.get("auth_id"),
|
|
"auth_token": config.value.get("auth_token"),
|
|
"from_numbers": config.value.get("from_numbers", []),
|
|
}
|
|
elif provider == "cloudonix":
|
|
return {
|
|
"provider": "cloudonix",
|
|
"bearer_token": config.value.get("bearer_token"),
|
|
"api_key": config.value.get("api_key"), # For x-cx-apikey validation
|
|
"domain_id": config.value.get("domain_id"),
|
|
"from_numbers": config.value.get("from_numbers", []),
|
|
}
|
|
elif provider == "ari":
|
|
return {
|
|
"provider": "ari",
|
|
"ari_endpoint": config.value.get("ari_endpoint"),
|
|
"app_name": config.value.get("app_name"),
|
|
"app_password": config.value.get("app_password"),
|
|
"inbound_workflow_id": config.value.get("inbound_workflow_id"),
|
|
"from_numbers": config.value.get("from_numbers", []),
|
|
}
|
|
else:
|
|
raise ValueError(f"Unknown provider in config: {provider}")
|
|
|
|
raise ValueError(
|
|
f"No telephony configuration found for organization {organization_id}"
|
|
)
|
|
|
|
|
|
async def get_telephony_provider(organization_id: int) -> TelephonyProvider:
|
|
"""
|
|
Factory function to create telephony providers.
|
|
|
|
Args:
|
|
organization_id: Organization ID (required)
|
|
|
|
Returns:
|
|
Configured telephony provider instance
|
|
|
|
Raises:
|
|
ValueError: If provider type is unknown or configuration is invalid
|
|
"""
|
|
# Load configuration
|
|
config = await load_telephony_config(organization_id)
|
|
|
|
provider_type = config.get("provider", "twilio")
|
|
logger.info(f"Creating {provider_type} telephony provider")
|
|
|
|
# Create provider instance with configuration
|
|
if provider_type == "twilio":
|
|
return TwilioProvider(config)
|
|
|
|
elif provider_type == "vonage":
|
|
return VonageProvider(config)
|
|
|
|
elif provider_type == "vobiz":
|
|
return VobizProvider(config)
|
|
|
|
elif provider_type == "cloudonix":
|
|
return CloudonixProvider(config)
|
|
|
|
elif provider_type == "ari":
|
|
return ARIProvider(config)
|
|
|
|
else:
|
|
raise ValueError(f"Unknown telephony provider: {provider_type}")
|
|
|
|
|
|
async def get_all_telephony_providers() -> List[Type[TelephonyProvider]]:
|
|
"""
|
|
Get all available telephony provider classes for webhook detection.
|
|
|
|
|
|
Returns:
|
|
List of provider classes that can be used for webhook detection
|
|
"""
|
|
return [
|
|
ARIProvider,
|
|
CloudonixProvider,
|
|
TwilioProvider,
|
|
VobizProvider,
|
|
VonageProvider,
|
|
]
|