vidcmt 给在线影视(video_info 里 newsType=SP)铺机器人评论,条数按 fakePlayCount 分层(热门 20~50 条,长尾 1 条),而不是像短剧那样一刀切—— 真实影视评论区本来就稀,统一铺 20~50 既是 300 万条文档也一眼假。 跑完自动重算 commentCount / fakeCommentCount,口径取自后端自己的修复函数 rebuildSingleObjCommentCount 的 video 分支,顺带修掉 fakeCommentCount 被 减穿成负数的历史脏数据。 同时修正 dramacmt:city 改成写 "-"。发评论路径里 GetLocationByIP 的调用 是注释掉的,线上真实评论没有一条带归属地,给真城市等于在评论区挂个 「我是机器人」的标。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
dramacmt
给在线短剧铺机器人评论。一次性运营工具,不进 cron。
为什么不用后台已有的评论导入
web/api/commentctrl.AddContentExcel 有三个限制:
- 只认视频(按
vidmod.GetVideoInfo查对象),短剧的objID是media._id,走不通 - 要上传 Excel
- 它的
userID取自static.json的sysUser——那些 uid 在user表里并不存在
第 3 点是实际踩到的坑:评论列表填充用户信息时(app/service/commentser/cmtcoverter.go)
查不到用户不会丢弃评论,只是把昵称和头像留空。线上已经有 5962 条这样的
「无名无头像」评论(抽查 400 个引用 uid,0 命中)。
所以本工具自己建一批机器人用户,评论挂在它们身上。
机器人用户
- uid 从 1001 开始往上发,默认 400 个。该区间原本完全空闲(
uid 1~17是库里 已有的 17 个机器人,1000 以下整段不碰) - uid 必须
<= 111999(common/constant.RobotUIDLimit)——commentser.getTrackInfo靠这个阈值判定isRobot,后台可按机器人筛选和撤回 - uid 池远低于
auto_id的 uid 计数器(当时是 3111989,只增不减), 不会和后续真实注册撞号 - 昵称按「姓 + 名」随机拼,风格对齐库里现有那 17 个机器人(郏哲、溪焱这种)
- 头像从库里现有用户采样,不写死路径(各站
static.json里是同一批 90 张)
user 表的唯一索引要当心:
| 索引 | 类型 | 处理 |
|---|---|---|
devID |
非 sparse 唯一 | 必须给唯一非空值,用 ROBOT%07d |
token / promotionCode / mobile |
部分唯一({$gt: ""}) |
留空串即豁免 |
已存在的 uid 不覆盖(昵称头像可能被运营改过),所以可以重复跑。
评论
要能在 App 里显示,必须满足 models/v/cmtmod.GetParentCmtList 的全部条件:
level = 1 status = 1 isGodComment = false
isDelete = false isAdvertiser 非 true
createdAt <= now
注意 status:App 发评论走的 getTrackInfo 写的是 status: 2(未审核),
而列表只认 1。所以铺数据必须直接写 1,否则一条都不显示。
其余字段整体对齐线上真实短剧评论的形状,两个容易写错的地方:
type是"VIDEO",不是"drama"——objType才是"drama"。getTrackInfo对所有 objType 都传cmtmod.CmtTypeVideotousername落库键名是小写的:结构体那个字段只有form/jsontag, 没写bsontag,driver 默认把字段名小写city必须写"-":发评论路径里GetLocationByIP的调用是注释掉的 (app/service/commentser/cmtsend.go:114-116),线上真实评论没有一条带 归属地。City会原样出参给 App(cmtcoverter.go:46),给真城市等于在评论区 挂个「我是机器人」的标。第一版写了随机城市,已改掉,线上那 19,697 条也已回刷
media.countComment 必须同步 $inc。App 的「总评论条数」在第一页直接读这个
字段(app/api/commentctrl),不补的话前端显示 0 条、但列表里有评论。
点赞数与时间
createdAt随机铺在该剧latestPublishedAt(没有就退createdAt)到现在之间, 再按时间排序写入likeCount走长尾:55% 落 05、30% 落 630、12% 落 31120、3% 落 121400。 热门评论区要求likeCount > 0且按它倒序,所以不能全给 0- 再按文案长短压上限:≤4 字的短评最多 30 赞,≤8 字最多 120。 不压的话会出现「可以」两个字拿 164 赞这种明显假的数据
- 不写
like集合的记录。likeCount是展示值,isLike只反映当前请求用户, 不建 like 文档不影响功能,也省掉几万条垃圾数据
文案池在 content.go,179 条互不重复。单剧内文案和用户都不重复,
所以 --max 不能超过池子容量。
用法
go build -o /tmp/dramacmt ./scripts/dramacmt/
# 干跑,看会写多少
/tmp/dramacmt --dst "$DST_TANGGUO" --db tangguo --dry-run
# 只给评论数为 0 的剧铺,每部 20~50 条(默认)
/tmp/dramacmt --dst "$DST_TANGGUO" --db tangguo
# 全部在线短剧都补到 20~50 条
/tmp/dramacmt --dst "$DST_TANGGUO" --db tangguo --only-empty=false
# 调试:只跑 3 部,固定种子便于复现
/tmp/dramacmt --dst "$DST_TANGGUO" --db tangguo --limit 3 --seed 42
--db 必须显式传:URI 里的 authSource 通常是 admin,推不出业务库名。
撤回
机器人用户和评论都带标记,撤回是两条命令:
// 撤回评论(软删,保守做法)
db.comment.updateMany({isRobot: true, objType: "drama", userID: {$gte: 1001, $lte: 1400}},
{$set: {isDelete: true}})
// countComment 要跟着减,按 objID 分组重算
硬删同理,把 $set 换成 deleteMany。重算 countComment 用
countDocuments({objID, level:1, status:1, isDelete:false})。