180 lines
9.5 KiB
Markdown
180 lines
9.5 KiB
Markdown
# 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*
|