# Zendesk FAQ Keyword Search 把 `test1.py` (search_articles) 与 `test2.py` (list_all_sections_full) 重写为 FastAPI 服务: - 启动时加载所有 **FAQ Section IDs**(名字含 `faq` 且文章数 > 0)保存到内存 - 每天 **0:00** 自动刷新一次(可在 `.env` 改时间) - 暴露 `GET/POST /search` 接口,请求字段为 `query`,返回 Zendesk 接口的搜索结果 ## 目录结构 ``` app/ ├── main.py # FastAPI 入口、lifespan、健康检查、手动刷新 ├── config.py # 从 .env 读取 Zendesk 凭据 ├── schemas.py # 请求/响应 Pydantic 模型 ├── services/ │ ├── zendesk_client.py # 异步 list_all_faq_sections / search_articles │ └── cache.py # 内存缓存 + 每日 0 点定时刷新 └── routers/ └── search.py # /search 接口 ``` ## 安装 ```bash pip install -r requirements.txt cp .env.example .env # 编辑 .env 填入 ZENDESK_SUBDOMAIN / ZENDESK_EMAIL / ZENDESK_API_TOKEN ``` ## 运行 ```bash uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload ``` 启动日志中会看到: ``` 启动:首次加载 FAQ 缓存… ✅ FAQ Section id=... count=... name=... cat=... FAQ 缓存刷新完成:sec_ids=N 条,下一次刷新 2026-06-16T00:00:00 启动:定时刷新任务已运行 ``` ## 接口 ### 1. 搜索(GET) ```bash curl "http://localhost:8000/search?query=Can%20I%20Add%20a%20PoE%20Switch" ``` ### 2. 搜索(POST) ```bash curl -X POST http://localhost:8000/search \ -H "Content-Type: application/json" \ -d '{"query": "Can I Add a PoE Switch", "page": 1, "per_page": 25}' ``` 响应: ```json { "success": true, "query": "...", "count": 3, "page": 1, "per_page": 25, "next_page": null, "sec_ids_used": [48252627506585, 47684283137817, "..."], "results": [{"title": "...", "html_url": "...", "snippet": "..."}] } ``` ### 3. 缓存状态 ```bash curl http://localhost:8000/health/cache # {"sec_ids_count": 30, "last_updated_at": "2026-06-15T09:12:33", "next_refresh_at": "2026-06-16T00:00:00"} ``` ### 4. 手动刷新缓存 ```bash curl -X POST http://localhost:8000/admin/cache/refresh ``` ### 5. Swagger UI 打开 。 ## 配置项(.env) | 变量 | 默认 | 说明 | | --- | --- | --- | | `ZENDESK_SUBDOMAIN` | — | Zendesk 子域名,例:`zositechhelp` | | `ZENDESK_EMAIL` | — | Zendesk 账号邮箱 | | `ZENDESK_API_TOKEN` | — | API Token | | `DEFAULT_LOCALE` | `en-us` | 默认语言 | | `CACHE_REFRESH_HOUR` | `0` | 每日刷新小时(本地时区) | | `CACHE_REFRESH_MINUTE` | `0` | 每日刷新分钟 | | `HTTP_TIMEOUT` | `30` | httpx 超时秒数 | ## 与原脚本对照 | 原脚本 | 新位置 | | --- | --- | | `test2.list_all_sections_full` | `app/services/zendesk_client.list_all_faq_sections`(异步) | | `test2.get_article_count` | `app/services/zendesk_client._get_article_count`(私有) | | `test1.search_articles` | `app/services/zendesk_client.search_articles`(异步) | | `test1.faq_section_ids` 硬编码 | 内存缓存 `app/services/cache.faq_cache.sec_ids`(启动加载 + 每日 0 点刷新) | | `test1.QUERY` 硬编码 | HTTP 请求字段 `query` |