A01(抖音 40.6.0)实测: · 冷启动后按固定 sleep(1.2s) 找账号列表行 → 列表还没渲染 → 判成"本机没登这个号" → **漏发且不报错**; 现在两处都轮询到 deadline:等面板出目标行、等回读变成目标名。 · 实测选择器(写进 doc/research/U2_ELEMENT_SELECTORS.md §七 与 .env.example): 昵称 `resourceId=com.ss.android.ugc.aweme:id/tk+`、切换入口 `descriptionContains=切换账号`、 切号按名字点行 `textContains=<名字>`(行 TextView 不可点但 u2 按中心坐标点,行容器接住)、 「我」页签 `descriptionContains=我`(desc 是「我,按钮」)。 · 并记下"为什么不要用 (…b7w)[N]":序号型会随列表行数/顺序错位 → 点错号 = 发到别人号上。 · 冷启动切号 17.2s 成功、热态 12.9s;A01 最终已切回原账号。
147 lines
7.6 KiB
Bash
147 lines
7.6 KiB
Bash
# ==============================================================================
|
||
# auto_control 环境变量示例
|
||
# - 复制为项目根目录的 .env 再按需修改(.env 已被 .gitignore 排除,不会进 git)
|
||
# - 加载方式:config.py 逐行解析后用 os.environ.setdefault 注入
|
||
# → 因此"真实环境变量"优先于 .env(容器/CI 里用 env 覆盖更方便)
|
||
# - 标【必须】的项务必设置;其余留空即用代码默认值
|
||
# - 完整说明见 doc/DEVELOPMENT.md §4 配置速查、doc/DEPLOY.md §2.2
|
||
# ==============================================================================
|
||
|
||
# ==================== 数据库 ====================
|
||
# 平台用 MySQL(正式用法)。DEPLOY_ENV 声明"这份配置连的是哪个环境的库",
|
||
# 并与库名一一绑定,启动时会互相校验,不符直接拒绝启动:
|
||
# DEPLOY_ENV=dev → 期望库名 auto_control_dev(本地开发,可随意折腾)
|
||
# DEPLOY_ENV=prod → 期望库名 auto_control (正式数据)
|
||
# 首次连接的库会被打上环境标签(app_meta.deployment_env);标签与 DEPLOY_ENV
|
||
# 不符时拒绝启动——这是防止「开发配置连到生产库」的最后一道闸。
|
||
DEPLOY_ENV=dev
|
||
DB_HOST=
|
||
DB_PORT=3306
|
||
DB_USER=
|
||
DB_PASSWORD=
|
||
DB_NAME=auto_control_dev
|
||
# 排序规则用 _bin(逐码点比较,等价 SQLite 的大小写敏感语义),别改成 _general_ci
|
||
DB_CHARSET=utf8mb4
|
||
DB_COLLATION=utf8mb4_bin
|
||
|
||
# 完整连接串:优先级最高,用于脚本临时指向别的库(一般不用配)
|
||
# DATABASE_URL=mysql+pymysql://user:pass@host:3306/auto_control_dev?charset=utf8mb4
|
||
|
||
# 逃生阀(默认关,仅在明确知道后果时打开)
|
||
# DB_ALLOW_ENV_MISMATCH=1 环境与库名/库标签不符时仍启动(危险)
|
||
# DB_ALLOW_SQLITE_FALLBACK=1 生产环境 DB_HOST 为空时允许回退 SQLite(回滚用)
|
||
# DB_ALLOW_ENV_MISMATCH=0
|
||
# DB_ALLOW_SQLITE_FALLBACK=0
|
||
|
||
|
||
# ==================== Web 服务 ====================
|
||
# 会话密钥【必须,生产务必固定】:不配则每次启动随机生成,重启后登录态失效。
|
||
# 生成:python -c "import secrets; print(secrets.token_hex(32))"
|
||
WEB_SECRET_KEY=请填写随机密钥
|
||
|
||
# 监听地址与端口是 config.py 里的常量(不进 .env):WEB_HOST=0.0.0.0、WEB_PORT=18050
|
||
# 需要修改直接改 config.py(18050 是为了避开 Windows 动态端口段)
|
||
|
||
|
||
# ==================== 设备与 adb ====================
|
||
# USB 设备(serial 无冒号)所在的部署机 —— 平台经它的 adb server 驱动这些设备。
|
||
# 默认 100.100.10.1:5037(220 的 Tailscale IP + adb 容器端口,host 网络模式)。
|
||
# USB_ADB_HOST=100.100.10.1
|
||
# USB_ADB_PORT=5037
|
||
|
||
# 设备自动发现(扫描网段找开放 5555 的设备)。
|
||
# 扫描网段在「工具 → 设备池管理」界面里配置(存数据库 app_meta),此处只管端口与周期。
|
||
# DISCOVERY_PORT=5555
|
||
# DISCOVERY_INTERVAL=60
|
||
|
||
# 把本机的 adb 客户端指向远程 adb server(注意:这三个键由 adb/adbutils 自己读取,
|
||
# 不是本项目代码读的;两个变量名都要设,adb 实际认 ADDRESS,部分库读 HOST)。
|
||
# 用途:让本机 adb 直接看到 220 侧插着的 USB 设备。
|
||
# ANDROID_ADB_SERVER_ADDRESS=192.168.20.220
|
||
# ANDROID_ADB_SERVER_HOST=192.168.20.220
|
||
# ANDROID_ADB_SERVER_PORT=5037
|
||
|
||
|
||
# ==================== Tailscale 管理(工具 → Tailscale 管理) ====================
|
||
# API key:Tailscale 后台 → Settings → API Access Tokens 生成
|
||
TAILSCALE_API_KEY=请填写Tailscale_API_key
|
||
|
||
# tailnet 名/ID(一般填登录邮箱,如 [email protected])
|
||
# [email protected]
|
||
|
||
|
||
# ==================== MCP Server(外部 AI 接入,:8033) ====================
|
||
# 注意:mcp_server 只读进程环境变量,**不读本文件**!
|
||
# 容器场景由 scripts/start.sh 用下面这些变量拉起进程;
|
||
# 本机手动启动请直接在命令行前加环境变量(见 doc/MCP.md §2)。
|
||
#
|
||
# MCP_ENABLED=1 # 仅 start.sh 消费:=0 则不自动拉起 MCP
|
||
# MCP_ALLOW_WRITE=1 # 写操作总开关(0=只读;start.sh 内强制为 1)
|
||
# MCP_PLATFORM_URL=http://127.0.0.1:18050
|
||
# MCP_PLATFORM_USER=admin
|
||
# MCP_PLATFORM_PASS=请填写平台admin密码 # 【改过 admin 密码必须同步,否则 MCP 登录失败】
|
||
# MCP_ALLOWED_SERIALS= # 设备白名单(逗号分隔);空=不限制(语义缺口见 backlog)
|
||
# MCP_HTTP_HOST=0.0.0.0
|
||
# MCP_HTTP_PORT=8033
|
||
# MCP_SCREENSHOT_WIDTH=540 # 返回给模型的截图宽度
|
||
# MCP_JPEG_QUALITY=70
|
||
# MCP_AUDIT_FILE=/tmp/mcp_audit.log
|
||
# MCP_PLATFORM_TIMEOUT=30
|
||
|
||
|
||
# ==================== AI Agent(mcp_agent,命令行/独立运行时用) ====================
|
||
# 注意:同样只读进程环境变量、不读本文件。
|
||
# Web 的「AI 控制台」配置走数据库(app_meta 的 agent_* 键),与本组变量互不影响。
|
||
#
|
||
# AGENT_API_BASE=https://api.deepseek.com
|
||
# AGENT_MODEL=deepseek-v4-flash-vision-exp
|
||
# AGENT_API_KEY=请填写模型 API Key
|
||
# DEEPSEEK_API_KEY= # AGENT_API_KEY 的兼容别名
|
||
# AGENT_MCP_URL=http://127.0.0.1:8033/mcp
|
||
# AGENT_DEFAULT_SERIAL=
|
||
# AGENT_MAX_STEPS=40
|
||
# AGENT_TIMEOUT=120
|
||
# AGENT_LANG=zh
|
||
|
||
|
||
# ==================== 开发/测试 ====================
|
||
# 设置后不启动 cron 调度器(跑测试脚本时避免真实触发任务、占用设备)
|
||
# DISABLE_SCHEDULER=1
|
||
|
||
# 视频发布计划的素材目录(默认 data/videos)。
|
||
# **自动化测试必须指到临时目录**,否则测试传的视频会落进用户真实数据目录。
|
||
# DATA_VIDEO_DIR=/tmp/videos_test
|
||
|
||
# 单次上传体积上限(MB,默认 2048)。
|
||
# ⚠ 必须大于「应用管理」里最大的 APK(实测有 336MB 的包),否则 APK 上传会被一起卡死。
|
||
# MAX_UPLOAD_MB=2048
|
||
|
||
# ==================== 发布计划:抖音「我」页面上的控件(抓一次填这里) ====================
|
||
# 发布任务按**名字**发(名字 = 抖音昵称),所以平台要知道"名字在屏幕上哪个控件里"。
|
||
# 用「抓取元素」抓一次抖音「我」页面上的**昵称**(那个 TextView),填到下面。
|
||
# 一处配置、三处一致:任务骨架的「读取本机账号名字」步骤默认值、切号后的回读校验、
|
||
# 以及「发布计划 → 一键推送(按名字找设备)」的实时探测。
|
||
# 留空 = 还没抓:相关步骤会明确报错并跳过,**绝不会猜一个名字去发**。
|
||
#
|
||
# 2026-10-12 在 A01(抖音 40.6.0)实测可用的值:昵称那个 TextView 的 resource-id 是混淆 id `tk+`,
|
||
# 所以填 resourceId(等价 xpath://*[@resource-id="com.ss.android.ugc.aweme:id/tk+"])。
|
||
# DOUYIN_NAME_SELECTOR_TYPE=resourceId
|
||
# DOUYIN_NAME_SELECTOR_VALUE=com.ss.android.ugc.aweme:id/tk+
|
||
|
||
# 「我」页面 →「切换账号」列表那个入口(自动切号用,同样抓一次填这里)。
|
||
# 它是个只有 content-desc 的 ImageView(desc 就是「切换账号」),所以用 descriptionContains。
|
||
# 留空 = 「切换账号」步骤会明确报错并跳过(不会瞎点)。
|
||
# DOUYIN_SWITCH_SELECTOR_TYPE=descriptionContains
|
||
# DOUYIN_SWITCH_SELECTOR_VALUE=切换账号
|
||
#
|
||
# 细节与结构图见 doc/research/U2_ELEMENT_SELECTORS.md §七(含"为什么不要用 (…b7w)[N]")。
|
||
|
||
|
||
# ==============================================================================
|
||
# 已废弃的历史配置(STF 已从代码层摘除,下列键代码不再使用,保留仅为兼容旧 .env)
|
||
# STF_URL / STF_TOKEN / STF_SSH_TARGET / STF_SSH_PASSWORD /
|
||
# STF_DOCKER_CONTAINER / STF_ADB_CONTAINER / STF_SCRIPT_PATH /
|
||
# AUTO_RELEASE_STALE_OCCUPY
|
||
# 迁移背景见 doc/STF_REMOVAL.md
|
||
# ==============================================================================
|