Files
memind/wechat/handlers/sync-replies.mjs
T
john f91ee97502
Memind CI / Test, build, and release guards (push) Has been cancelled
feat(wechat): send rich subscribe welcome with clickable intro and bind links
New followers receive capability overview plus WeChat anchor links for the
deep intro page and account binding instead of exposing raw URLs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-28 09:39:06 +08:00

88 lines
3.2 KiB
JavaScript

import { resolveWechatAddressName } from '../user/display-name.mjs';
export const DEFAULT_SUBSCRIBE_INTRO_URL =
'https://m.tkmind.cn/MindSpace/a70ff537-8908-486e-9b6c-042e07cc25db/public/tkmind-deep-intro.html';
/** 103 生产默认绑定入口:{H5_PUBLIC_BASE_URL}/auth/wechat/authorize?intent=login */
export const DEFAULT_PRODUCTION_BIND_URL =
'https://m.tkmind.cn/auth/wechat/authorize?intent=login';
export function buildWechatTextLink(href, label) {
const normalizedHref = String(href ?? '').trim();
const normalizedLabel = String(label ?? '').trim();
if (!normalizedHref) return normalizedLabel;
if (!normalizedLabel) return normalizedHref;
return `<a href="${normalizedHref}">${normalizedLabel}</a>`;
}
export function buildSubscribeWelcomeText({ bindUrl, introUrl = DEFAULT_SUBSCRIBE_INTRO_URL } = {}) {
const normalizedBindUrl = String(bindUrl ?? '').trim();
const normalizedIntroUrl = String(introUrl ?? '').trim();
const lines = [
'欢迎关注 TKMind 智趣 👋',
'',
'在微信里直接发消息即可:',
'· 问答、写作、翻译',
'· 生成精美网页并给链接',
'· 发图解读报告/截图',
'· 设置定时提醒与每日推送',
];
if (normalizedIntroUrl) {
lines.push('', '📖 了解更多:', buildWechatTextLink(normalizedIntroUrl, '点击链接'));
}
if (normalizedBindUrl) {
lines.push('', '👉 先完成绑定再开始对话:', buildWechatTextLink(normalizedBindUrl, '点我绑定'));
}
lines.push('', '绑定后回复「你好」,或试试:', '「帮我做一个读书笔记页面」');
return lines.join('\n');
}
export function buildGreetingText(user) {
const name = resolveWechatAddressName(user);
return name ? `你好,${name}!我在呢,有什么需要?` : '你好!我在呢,有什么需要?';
}
export function buildStatusText(user, fallbackText) {
const name = resolveWechatAddressName(user);
if (!name) return fallbackText;
return `我在这边,${name}。上一条如果还没完成,我会继续把结果发给你;你也可以直接补一句要求。`;
}
export function buildConnectivityTestReply(user) {
const name = resolveWechatAddressName(user);
return name
? `${name},公众号消息通道正常,我收到你的测试了。`
: '公众号消息通道正常,我收到你的测试了。';
}
/**
* Resolve an immediate sync XML reply for lightweight intents.
* @returns {string|null}
*/
export function resolveSyncReply(wechatIntent, user, { statusFallbackText = '' } = {}) {
switch (wechatIntent?.kind) {
case 'status.probe':
return buildStatusText(user, statusFallbackText);
case 'greeting':
return buildGreetingText(user);
case 'connectivity.test':
return buildConnectivityTestReply(user);
default:
return null;
}
}
/**
* Whether this intent should be answered synchronously before agent dispatch.
*/
export function shouldHandleSyncReply(intent, wechatIntent) {
const msgType = String(intent?.msgType ?? '').toLowerCase();
if (wechatIntent?.kind === 'connectivity.test') {
return msgType === 'text' || msgType === 'voice';
}
if (wechatIntent?.kind === 'status.probe' || wechatIntent?.kind === 'greeting') {
return msgType === 'text';
}
return false;
}