小Ki班级喊话器
给一位老师搭出他自己的「手机遥控教室喊话 + 课堂点名记录」工作台。
输出是三条能直接用的网址,不是一份说明文档。
这个工作台长什么样
- 手机遥控台(
?r=phone):老师手机打开,选班级 → 点话术 → 点「喊话」。
手机自己不发声,它把指令发到云端。 - 教室播报端(
?r=room&c=1):教室电脑打开后放在那儿(连音箱/广播),
收到指令就用 TTS 念出来,同时全屏显示大字。 - 点名记录:点「说话 / 不认真 / 抄单词」再点学生名字,记一次并当场喊出来。
- 投屏大字:满屏超大字,投影仪/大屏直接用。
链路是:手机写一条指令到云端 → 教室端每 2.5 秒拉一次新指令 → 播报。
所以两边必须都能上网,教室电脑要一直开着这个页面。
执行前必须先问用户 4 件事
不要用示例值硬填。缺信息就问,一次问完:
- 怎么称呼你(显示在顶栏和教室大屏,如「王老师」「Miss Chen」)
- 教哪几个班(班级全名,数量不限)
- 教什么学科(决定话术库;英语要中英双语)
- 平时最常喊哪几句(口述 3-5 句,这是话术库的种子)
如果用户一上来就说"帮我搭一个",或只给了一部分信息 —— 先把缺的问齐再动手。
执行步骤
完整流程见 @references/setup.md,照它一步步做。概览:
- 开通 WorkBuddy 云服务 → 拿到
applicationId、endpoint、publishableKey - 执行
templates/schema.sql建 4 张表 - 写
config.json(教师/学科/班级/云服务凭证)→ 跑
node scripts/build-app.js config.json <发布目录> - 发布上线 → 得到链接
- 实测一遍再交付,然后清空测试数据
话术库按学科配置(不用改模板)
模板预置的是英语课中英双语话术,但整套话术库、点名类型、配色、输入框提示语
都可以在 config.json 里直接换掉 —— talks / accents / kinds / kindVoice /
placeholders,不需要动 templates/app.html 一个字。这几个字段都不传时,
才回落到 templates/defaults.json 里的英语默认值。
- 数学 / 语文等单学科老师:只传
talks.zh一层即可,语言切换按钮会自动隐藏,
教室端的声音自检也只念中文。别硬塞英文,老师用不上,学生还会听懵。 - 英语老师:传
talks.zh+talks.en,两边的分类键必须完全一致(build 会拦下来)。 - 起步素材看 @references/talk-library.md。最值钱的是第 4 问收集到的用户原话 ——
原样放进话术库,语气不要改写成书面语。
话术里可以写两个变量:
{班}—— 发送时自动替换成目标班级名。全年级播报时每个班各自替换:
9 班念"四年级9班…",10 班念"四年级10班…"。界面上(话术列表和预览区)
也会显示替换后的班级名,老师看到的就是会念出来的那句话。{n}—— 只在kindVoice里用,替换成学生姓名。
硬性规则
classes的键就是class_code,建好后不要再改。改键会让历史记录全部对不上。- 教室链接必须带班级号,取不到时绝不默认成第一个班。
?c=<班级键>是教室电脑
"听哪个班"的唯一依据。参数缺失或写错时,应用会进入「待选班」页面并暂停播报,
这是有意设计:默认错班 = 把 A 班的指令喊进 B 班教室,比不出声严重得多。
以后动这块逻辑,别为了"看起来更顺"加回|| "1"那种兜底。
参数解析已做宽容匹配(c/class/cls/班级名都认),但交付时仍要把每个班的
完整链接逐条列出来,不要让老师自己拼。 - 各语言的分类键必须完全一致。
talks.zh和talks.en(以及任何新增语言)
的分类数量与顺序都要对齐,不一致时切语言分类标签会错乱 ——build-app.js
已加校验会直接报错退出,别绕过它。 - 「全年级」的班级列表由
CLASSES动态生成,不要写死编号。 曾经的写法是
["1","2","3"],班号是 9/10 的老师点「全年级」会发给根本不存在的班 —— 静默失效。 - 选中态配色不要写死分类名。
.tab[data-k="英语课"]这类选择器在分类名可自定义后
必然失效,模板已改为 JS 注入--ac/--acl、--c1/--c2,加新分类不用碰 CSS。 - 分类名保持中文,English 模式下也不翻译。分类是导航要秒扫,内容才跟语言走。
- 座号必须写进
student.seat。不写的话前端按name排序,而中文在数据库里
是按字节排的 = 乱序,上课找不到人。这是最常见的返工点。 - SDK 加载分两种模式,别搞混(
config.json的sdkMode): "cdn"(默认,分发/上架用这个):只从 4 个公共源依次尝试
(国内镜像cdn.jsdmirror.com→ jsdelivr → fastly → unpkg)。包体不携带第三方代码。"local"(只用于老师自己的部署,最稳):先读同目录的wbcloud.js,
读不到再回退那 4 个源。SDK 与页面同域名、不跨站,校园网和教室电脑都拦不住 ——
这是唯一"谁也拦不住"的方案,用过的老师都该用这个。
代价是发布目录里多一个wbcloud.js(约 62KB)。
对外分发 / 售卖时必须用cdn,否则等于在分发腾讯的代码。这是合规问题,不是技术偏好。- SDK 引用必须锁版本 + 多源兜底,不要退回单源和
@dev。
@tencent-ai/workbuddy-cloud-sdk@dev是浮动标签,官方发新版可能直接改坏接口;
只写一个 jsdelivr 地址更是整个工具最脆弱的一环 —— 拉不到就cloud=null,
教室端收不到任何指令。当前模板已内置兜底加载器(window.SDK_READY),
启动流程也必须等它落定后再createCloud(),顺序反了会误报"组件没加载上"。 - 加载失败要给可操作的办法,不要只报一句"失败"。 老师看不懂"连接组件加载失败",
也帮不上忙。模板里的showSdkHelp()会列出已试过的源 + 三步自助办法 + 重试按钮,
这是有意设计,别删。 - 交付前清空
shout_cmd/class_record/room_presence测试数据。
room_presence不清会出现"教室在线"的假绿点。 - 一个工作台只能有一个域名、一套数据库。 用同一个账号把同一份应用发布到第二个
域名,会生出另一个独立的云应用 + 另一套空数据库,两边的数据完全不通。
这时手机端(旧域名)喊话、教室端(新域名)永远收不到,而两端界面都显示「已连接」,
从屏幕上完全看不出问题 —— 这是踩过的最贵的一个坑。所以: - 重新发布永远复用原来的
appId+domainPrefix,不要新建应用; - 换了域名就必须重新抄一遍链接给老师,并让他把旧书签删掉;
- 交付时确认两端「台号」一致(见下一条)。
- 交付前确认两端「台号」一致。 台号取自
publishableKey里的 appId 后 4 位,
手机端顶栏和教室端底栏都会显示。两个数字一样 = 同一个工作台;不一样就是接错了系统。
别只看「已连接」——那个只说明它连上了它自己的数据库。 - 点名话术保持"提醒"语气,不要写成处罚口吻。这个工具是给老师自己复盘用的,
被当众播报成处分会让家长反感,工具就用不长。
出问题怎么办
看 @references/troubleshoot.md。用户最常反馈的是教室端没声音,
九成是微信内置浏览器(让用户换系统浏览器),到那一节按现象对号入座即可。
交付话术
给用户这三样:手机遥控台链接、各班教室链接、一段使用说明。
说明文案在 @references/setup.md 末尾,可直接复制。必须提醒:
教室电脑第一次打开要点一次「🔊 点击启用声音」—— 这是浏览器规定,不点不给出声。
点下去它会念一遍班级名,并顺手检查这台电脑有没有装语音包:
缺中文或英文会直接写在状态栏上,说清缺哪个,别让用户以为工具坏了。
再补两条交付提醒:
- 让老师核对两端的「台号」(手机端顶栏、教室端底栏,形如 台号 FNP9)。
数字一样才是同一个工作台。教室电脑上若看不到「台号」字样,说明它加载的是旧缓存,
按 Ctrl+F5(Mac 是 Cmd+Shift+R)强刷一次。
- 教室电脑的链接存成书签,别靠聊天记录里的链接 —— 转发几次容易被截断参数。
按钮之后变成「🔊 测试声音」,随时可再点一次自证。
另外微信内置浏览器里语音会没声音,要用系统浏览器。
如果教室端出现「云服务组件没加载上」,那是这台电脑没从公共 CDN 下载到云端组件
(不是你的工具坏了)。屏幕会自己列出试过哪些源和三步自助办法,
最常见的原因就是教室网络出不去 —— 让老师换手机热点刷新一次即可。
排查细节见 @references/troubleshoot.md。