feat(wechat): send rich subscribe welcome with clickable intro and bind links
Memind CI / Test, build, and release guards (push) Has been cancelled

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>
This commit is contained in:
john
2026-08-28 09:39:06 +08:00
parent 760a1760ae
commit f91ee97502
4 changed files with 91 additions and 1 deletions
+37
View File
@@ -1,5 +1,42 @@
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}!我在呢,有什么需要?` : '你好!我在呢,有什么需要?';
+45
View File
@@ -0,0 +1,45 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import {
buildSubscribeWelcomeText,
buildWechatTextLink,
DEFAULT_PRODUCTION_BIND_URL,
DEFAULT_SUBSCRIBE_INTRO_URL,
} from './sync-replies.mjs';
test('buildWechatTextLink renders WeChat anchor without exposing raw url', () => {
assert.equal(
buildWechatTextLink(DEFAULT_PRODUCTION_BIND_URL, '点我绑定'),
`<a href="${DEFAULT_PRODUCTION_BIND_URL}">点我绑定</a>`,
);
});
test('buildSubscribeWelcomeText uses clickable anchors instead of raw urls', () => {
const text = buildSubscribeWelcomeText({ bindUrl: DEFAULT_PRODUCTION_BIND_URL });
assert.match(text, /欢迎关注 TKMind 智趣/);
assert.match(text, /生成精美网页并给链接/);
assert.match(text, /📖 了解更多:/);
assert.match(
text,
/<a href="[^"]*tkmind-deep-intro\.html">点击链接<\/a>/,
);
assert.match(text, /👉 先完成绑定再开始对话:/);
assert.match(
text,
/<a href="[^"]*auth\/wechat\/authorize\?intent=login">点我绑定<\/a>/,
);
assert.doesNotMatch(text, /\nhttps:\/\/m\.tkmind\.cn/);
assert.match(text, /帮我做一个读书笔记页面/);
});
test('buildSubscribeWelcomeText omits intro section when introUrl is empty', () => {
const text = buildSubscribeWelcomeText({
bindUrl: 'https://m.tkmind.cn/bind',
introUrl: '',
});
assert.doesNotMatch(text, /📖 了解更多:/);
assert.doesNotMatch(text, /tkmind-deep-intro\.html/);
});