# External Integrations **Analysis Date:** 2026-05-07 ## APIs & External Services **AI & Language Models:** - Kimi (OpenAI-compatible) - LLM for multi-turn AI conversations - SDK: `openai` Python package (in `requirements.txt`) - Implementation: `aiapp/kimi.py` (lines 1-29) - Config: `KIMI_API_KEY`, `KIMI_BASE_URL` (set at `qy_lty/settings.py:349-350`, loaded from `.env`) - Purpose: Single/multi-turn chat with users via POST `/api/ai/chat/` and `/api/ai/multi-chat/` **Real-Time Communications (RTC):** - Volcengine (ByteDance) - RTC service for voice/video calls - SDK: Custom token generation in `common/VolcEngineAccessToken.py` (lines 1-204), HTTP API calls in `device_interaction/volcengine_api.py` - Config: `VOLCENGINE_ACCESS_KEY`, `VOLCENGINE_SECRET_KEY`, `VOLCENGINE_APP_ID`, `VOLCENGINE_APP_KEY` (at `qy_lty/settings.py:241-243`) - Purpose: Generate RTC tokens for device-to-device or device-to-app real-time communication - Endpoint: `POST /api/device/rtc-token/get_by_mac/?mac_address=...` (no auth required, returns RTC token for device's bound user) - Room structure: `room_id = f"room_{user_id}"` (shared with WebSocket group `device_{user_id}`) **Audio/Speech Services (Multi-Provider):** - Configured via `AUDIO_SERVICE_PROVIDER` setting (default: `'huoshan'`) at `qy_lty/settings.py:415` **Aliyun NLS (Natural Language Service):** - SDK: `aliyun-python-sdk-core` + custom integration - Implementation: `aiapp/audio/AliyunAudioService.py` - Config keys: `ALIYUN_NLS_ACCESS_KEY_ID`, `ALIYUN_NLS_ACCESS_KEY_SECRET`, `ALIYUN_NLS_APP_ID` (in `qy_lty/settings.py:419-421`) - Purpose: Speech synthesis (text→voice) and recognition (voice→text) - Storage: Audio uploaded to Aliyun OSS (see OSS section) **Tencent Audio:** - Implementation: `aiapp/audio/TencentAudioService.py` - Config keys: `AUDIO_SERVICE_TENCENT_API_KEY`, `AUDIO_SERVICE_TENCENT_API_SECRET` (at `qy_lty/settings.py:430-431`) - Purpose: Text-to-speech and speech-to-text via Tencent APIs **Volcengine/Huoshan (ByteDance):** - Implementation: `aiapp/audio/HuoshanAudioService.py`, `aiapp/audio/HuoshanAudioService_new.py` - Config keys: `AUDIO_SERVICE_HUOSHAN_APPID`, `AUDIO_SERVICE_HUOSHAN_ACCESS_TOKEN`, `AUDIO_SERVICE_HUOSHAN_CLUSTER`, `AUDIO_SERVICE_HUOSHAN_VOICE_TYPE`, `AUDIO_SERVICE_HUOSHAN_STORAGE_DIR`, `AUDIO_SERVICE_HUOSHAN_BASE_URL` (at `qy_lty/settings.py:434-439`) - Purpose: TTS (text→speech) and ASR (speech→text) with local storage fallback - Also includes nested Aliyun ASR config (lines 440-451) as fallback **Audio Service Factory:** - Entry point: `aiapp/audio/AudioService.py:get_audio_service()` (lines 8-19) - Base class: `aiapp/audio/BaseAudioService.py` (abstract interface at lines 1-35) - Used by: `aiapp/views.py` (ChatBotAPIView, MultiChatAPIView) and tests ## Data Storage **Databases:** - **PostgreSQL** (Primary) - Connection: `POSTGRESQL_DATABASE_*` env vars (configured at `qy_lty/settings.py:166-172`) - Client: psycopg2-binary - Contains: User models, AI conversations, device bindings, card data, achievement records, subscription info - **Redis** (Cache + Message Queue) - Connection: `REDIS_LOCATION`, `REDIS_PASSWORD` (configured at `qy_lty/settings.py:252-260`) - Client: django-redis - Purpose: Token storage (key format: `token:{token}` or `admin_token:{token}` with 30-day TTL, see `CLAUDE.md` line 122), channel layer for WebSocket, caching - Channel layer config: `CHANNEL_LAYERS.default.BACKEND = 'channels_redis.core.RedisChannelLayer'` (at `qy_lty/settings.py:504-511`) **File Storage:** - **Aliyun OSS (Object Storage Service)** - Production storage for audio, images, documents - SDK: `oss2` Python package (in `requirements.txt`) - Implementation: `common/oss.py` (OSSUploader class at lines 1-90) - Config: `AUDIO_SERVICE_CONFIG['aliyun']` with `oss_key_id`, `oss_key_secret`, `oss_bucket`, `oss_endpoint`, `oss_host` (at `qy_lty/settings.py:422-427`) - Used by: Audio service, image processing endpoints, media uploads - Path pattern: `{base_dir}/[permanent|temporary]/{YYYYMMDD}/{filename}` - Dev fallback: Local filesystem storage at `MEDIA_ROOT` (`qy_lty/settings.py:238`) **Caching:** - Redis (see above) - TTL for RTC tokens: `rtc_room:{user_id}:{task_id}` (see `CLAUDE.md` line 172) - Device last-seen cache: `device:last_seen:{mac}` with 5-min TTL (see `CLAUDE.md` line 230) ## Authentication & Identity **Auth Provider:** - Custom Redis-backed token authentication + django-allauth social auth **Custom Token Auth:** - Implementation: `userapp/authentication.RedisTokenAuthentication` (at `userapp/authentication.py:10-34`) - Storage: Redis with keys `token:{token}` (users) and `admin_token:{token}` (admins) - TTL: 30 days - Used for: API requests via `Authorization: Bearer {token}` header - Generated by: `userapp/utils.py:generate_token()` (referenced in `CLAUDE.md` line 122) **WeChat Social Auth:** - Provider: django-allauth with Weixin provider (configured at `qy_lty/settings.py:56`) - Backend: `allauth.account.auth_backends.AuthenticationBackend` (at `qy_lty/settings.py:324`) **WebSocket Auth:** - Custom middleware: `device_interaction/auth.TokenAuthMiddleware` (lines 1-50) - Reuses `RedisTokenAuthentication` logic with mock request adapter - Routes: `ws://domain/ws/device/` (Header auth) and `ws://domain/ws/device/token/{token}/` (URL auth) - Group model: Messages routed to `device_{user_id}` (same user controls device and app) **Device MAC Login:** - Endpoint: `POST /api/user/mac-login/` (referenced in `CLAUDE.md` line 125) - Returns: User-token for device's bound user (latest binding via `order_by('-bound_at').first()`) - Model: `UserDevice` relationship with `bound_at` ordering ## Monitoring & Observability **Error Tracking:** - No dedicated external error tracking (Sentry, etc.) detected **Logs:** - **Aliyun Log Service** - Production logging integration - SDK: `aliyun-log-python-sdk` (in `requirements.txt`) - Implementation: `common/aliyun_logging.py` (AliyunLogHandler at lines 16-36, setup_logging() at lines 32-36) - Config: `ALIYUN_LOG_PROJECT`, `ALIYUN_LOG_STORE`, `ALIYUN_LOG_ENDPOINT`, `ALIYUN_LOG_ACCESS_KEY_ID`, `ALIYUN_LOG_ACCESS_KEY_SECRET` (env vars, loaded at lines 7-11) - Logging config: `qy_lty/settings.py:372-411` configures handlers for `django`, `django.request`, `aiapp`, `common`, `userapp` loggers - Log levels: INFO for production, DEBUG for console in dev ## CI/CD & Deployment **Hosting:** - Docker containers (self-managed or cloud-hosted) - Image base: Python 3.8 via docker.m.daocloud.io (China mirror) **CI Pipeline:** - No dedicated CI/CD service detected in code (GitHub Actions, GitLab CI, etc. config not present) **Deployment:** - Docker Compose for local/staging (docker-compose.yml:1-33) - Production via Docker Compose or Kubernetes (see Dockerfile for structure) - Port exposure: 12012 (maps to ASGI 8000) ## Environment Configuration **Required env vars (from settings.py and CLAUDE.md):** - `SECRET_KEY` - Django secret - `DEBUG` - Debug mode - `POSTGRESQL_DATABASE_NAME`, `POSTGRESQL_DATABASE_USER`, `POSTGRESQL_DATABASE_PASSWORD`, `POSTGRESQL_DATABASE_HOST`, `POSTGRESQL_DATABASE_PORT` - `REDIS_LOCATION`, `REDIS_PASSWORD` - `KIMI_API_KEY`, `KIMI_BASE_URL` (default: https://api.moonshot.cn/v1) - `ALIYUN_SMS_ACCESS_KEY_ID`, `ALIYUN_SMS_ACCESS_KEY_SECRET`, `ALIYUN_SMS_SIGN_NAME`, `ALIYUN_SMS_TEMPLATE_CODE` - `ALIYUN_NLS_ACCESS_KEY_ID`, `ALIYUN_NLS_ACCESS_KEY_SECRET`, `ALIYUN_NLS_APP_ID` - `ALIYUN_OSS_ACCESS_KEY_ID`, `ALIYUN_OSS_ACCESS_KEY_SECRET`, `ALIYUN_OSS_BUCKET`, `ALIYUN_OSS_ENDPOINT`, `ALIYUN_OSS_HOST`, `ALIYUN_OSS_AUDIO_BASE_DIR` - `ALIYUN_VI_ACCESS_KEY_ID`, `ALIYUN_VI_ACCESS_KEY_SECRET`, `ALIYUN_VI_ENDPOINT`, `ALIYUN_VI_REGION` - `ALIYUN_LOG_PROJECT`, `ALIYUN_LOG_STORE`, `ALIYUN_LOG_ENDPOINT`, `ALIYUN_LOG_ACCESS_KEY_ID`, `ALIYUN_LOG_ACCESS_KEY_SECRET` - `VOLCENGINE_ACCESS_KEY`, `VOLCENGINE_SECRET_KEY`, `VOLCENGINE_APP_ID`, `VOLCENGINE_APP_KEY` - `AUDIO_SERVICE_PROVIDER` (values: 'aliyun', 'tencent', 'huoshan'; default: 'huoshan') - `AUDIO_SERVICE_HUOSHAN_APPID`, `AUDIO_SERVICE_HUOSHAN_ACCESS_TOKEN`, `AUDIO_SERVICE_HUOSHAN_CLUSTER`, `AUDIO_SERVICE_HUOSHAN_VOICE_TYPE`, `AUDIO_SERVICE_HUOSHAN_STORAGE_DIR`, `AUDIO_SERVICE_HUOSHAN_BASE_URL` - `AUDIO_SERVICE_TENCENT_API_KEY`, `AUDIO_SERVICE_TENCENT_API_SECRET` (if provider='tencent') **Secrets location:** - `.env` file (git-ignored, copy from `.env.bak` template during setup per `CLAUDE.md` line 44) ## Webhooks & Callbacks **Incoming:** - WebSocket device messages routed to `device_{user_id}` group (see `CLAUDE.md` line 118) - Volcengine RTC conversation callbacks: `conversation_status`, `conversation_subtitle` message types forwarded via WebSocket (see `CLAUDE.md` line 167) - Device heartbeat: `device:last_seen:{mac}` refreshed on message receipt (see `CLAUDE.md` line 230) **Outgoing:** - No outbound webhooks detected (integrations are request/response based) ## API Documentation **Documentation Endpoints:** - Swagger UI: `http://localhost:8000/swagger/` - ReDoc: `http://localhost:8000/redoc/` - Generated by: drf-yasg (configured at `qy_lty/settings.py:513-549`) **Main API Routes:** - `/api/user/` - User auth & management (MAC login, token generation) - `/api/ai/` - AI chat (single-turn, multi-turn, voice synthesis/recognition) - `/api/device/` - Device interaction, RTC tokens, binding status - `/api/card/` - Card system (batch generation, QR codes, usage tracking) - `/api/achievement/` - Achievement tracking - `/api/v1/admin/` - Admin operations - `/ws/device/` - WebSocket for real-time device communication --- *Integration audit: 2026-05-07*