官方文档:GeWe API - GeWe API|微信 API 开发文档
一、业务痛点与技术背景
社群运营高频能力:建群、邀人、踢人、公告、关键词回复、违规治理、活跃统计。痛点在于:
群事件与消息回调混杂,规则引擎易误伤
多群广播无灰度,一次发错全网爆炸
成员进退不同步到 CRM,运营「群是群、库是库」
关键词自动踢人缺少审计与申诉
GeWe 提供群列表、创建、邀请、移除、群信息管理等能力,适合作为社群中台的执行层。
二、核心架构设计与数据流转
群消息/系统事件 Webhook │ ▼ Group Event Normalizer │ ├─ member_join / member_leave ├─ chat_text / chat_image └─ system_notice ▼ Group Rule Engine(按群画像匹配策略包) │ ├─ 欢迎语 / 关键词 FAQ ├─ 违规检测 → warn / mute逻辑 / kick └─ 同步 CRM 社群成员表 ▼ Broadcast Planner(灰度、分批、静默时段) ▼ Outbound Gateway + Risk Policy三、关键代码与配置示例
3.1 群画像与策略包
group_profile: group_id: "123@chatroom" tags: ["正式课学员"] policy_pack: "class_group_v2" quiet_hours: ["23:00-08:00"] max_warn_before_kick: 2 policy_packs: class_group_v2: welcome: enabled: true template: "welcome_class" keywords: - match: "^(打卡|作业)$" reply_template: "homework_guide" - match: "(广告|加我外链)" action: warn anti_spam: duplicate_window_sec: 60 duplicate_threshold: 33.2 进群欢迎(防刷屏)
def on_member_join(evt): g = groups.get(evt.group_id) if not g.policy.welcome.enabled: return # 同一用户 24h 内只欢迎一次 key = f"gewe:welcome:{evt.group_id}:{evt.member}" if not redis.set(key, "1", nx=True, ex=86400): return text = templates.render(g.policy.welcome.template, evt) guarded_send(appid=evt.appid, to=evt.group_id, content=text, priority=1) crm.upsert_member(group_id=evt.group_id, wxid=evt.member, status="joined")3.3 关键词规则引擎
type RuleAction = "reply" | "warn" | "kick" | "ignore"; function matchRules(text: string, rules: Rule[]): Rule | null { for (const r of rules) { if (new RegExp(r.match, "i").test(text)) return r; } return null; } async function handleGroupText(msg: CanonicalMessage) { const profile = await loadProfile(msg.peerId); if (inQuietHours(profile) && !isAdmin(msg.fromUser)) { return; // 静默期不自动回复,避免扰民 } const rule = matchRules(msg.text!, profile.keywords); if (!rule) return; if (rule.action === "reply") { await guardedSend({ to: msg.peerId, content: await render(rule.reply_template) }); } else if (rule.action === "warn") { const n = await warns.incr(msg.peerId, msg.fromUser); await guardedSend({ to: msg.peerId, content: `@成员 请勿发广告(警告 ${n})` }); if (n >= profile.max_warn_before_kick) { await gewe.removeMember({ appid: msg.appid, groupId: msg.peerId, wxid: msg.fromUser }); await audit.write({ action: "kick", reason: "spam", ...msgMeta(msg) }); } } }3.4 分批广播
def broadcast(appid: str, group_ids: list[str], content: str, batch=5, pause=20): # 灰度:先 1 个管理员群 canary = group_ids[:1] rest = group_ids[1:] for gid in canary: guarded_send(appid, gid, content, priority=2) time.sleep(60) if not ops.confirm_canary_ok(): return for i in range(0, len(rest), batch): chunk = rest[i:i+batch] for gid in chunk: guarded_send(appid, gid, content, priority=2) time.sleep(pause)3.5 成员真相表
CREATE TABLE group_members ( group_id VARCHAR(128), wxid VARCHAR(128), status VARCHAR(16), -- joined|left|kicked joined_at TIMESTAMPTZ, left_at TIMESTAMPTZ, PRIMARY KEY(group_id, wxid) );四、生产环境避坑与安全风控
踢人必须审计 + 可回滚话术;误踢成本极高。
广播默认灰度;禁止管理后台「一键全量」无二次确认。
群内 @ 与昵称编码注意 UTF-8,避免乱码引发重复发送。
系统消息解析与文本分开,防止把「你已退出群聊」当用户发言。
合规:群发广告、诱导分享易封号,策略包要过审。
群接口说明见文首官方文档。
五、本篇交付清单
群画像与策略包
进群欢迎 / 关键词 / 踢人审计
灰度分批广播
成员真相表