From d8eaef3fbdf94823ecc6c321c7b98fbe0fa7553c Mon Sep 17 00:00:00 2001 From: john Date: Fri, 11 Sep 2026 12:32:13 +0800 Subject: [PATCH] feat(wechat): MindSpace public draft push with 143 host defaults Add public-page WeChat draft button, publication standard conversion for poem/prose/generic pages, and quick push APIs. Default Studio release SSH targets to john@180.159.29.143 with 105 edge upstream via 10.10.0.2. Co-authored-by: Cursor --- .env.example | 13 +- docs/branch-disposition.md | 20 +- docs/goosed-local-build-delivery.md | 6 +- docs/wechat-draft-publication-standard.md | 57 ++ mindspace-chat-wechat-draft.mjs | 162 ++++ mindspace-chat-wechat-draft.test.mjs | 103 +++ mindspace-public-share-widget.mjs | 166 +++- mindspace-public-share-widget.test.mjs | 25 +- mindspace-wechat-page-draft.mjs | 817 ++++++++++++++++-- mindspace-wechat-page-draft.test.mjs | 191 +++- package.json | 2 +- public/dev/mp-follow-qrcode.png | Bin 0 -> 27833 bytes scripts/release-deep-search-runtime-prod.sh | 2 +- scripts/release-mindspace-service-prod.sh | 2 +- scripts/release-portal-canary-prod.sh | 18 +- scripts/release-portal-runtime-prod.sh | 2 +- scripts/release-prod.sh | 2 +- scripts/rollback-portal-canary-prod.sh | 10 +- scripts/rollback-portal-runtime-prod.sh | 2 +- scripts/verify-canary-promotion-evidence.mjs | 2 +- server.mjs | 3 + server/portal-gateway-services-bootstrap.mjs | 12 + server/portal-mindspace-chat-share-routes.mjs | 95 ++ ...ortal-mindspace-chat-share-routes.test.mjs | 12 + wechat-daily-news-inline.mjs | 118 ++- wechat-draft-article-layout.mjs | 105 +++ wechat-draft-publication-standard.mjs | 89 ++ wechat-draft-publication-standard.test.mjs | 70 ++ wechat-news-morning-draft.mjs | 128 ++- 29 files changed, 2094 insertions(+), 140 deletions(-) create mode 100644 docs/wechat-draft-publication-standard.md create mode 100644 mindspace-chat-wechat-draft.mjs create mode 100644 mindspace-chat-wechat-draft.test.mjs create mode 100644 public/dev/mp-follow-qrcode.png create mode 100644 wechat-draft-article-layout.mjs create mode 100644 wechat-draft-publication-standard.mjs create mode 100644 wechat-draft-publication-standard.test.mjs diff --git a/.env.example b/.env.example index 042710b..3896f0f 100644 --- a/.env.example +++ b/.env.example @@ -52,7 +52,9 @@ H5_PUBLIC_BASE_URL=http://127.0.0.1:5173 # Tool Gateway Queue v0(/agent/runs 后台任务队列,默认保守限流)。 # MEMIND_AGENT_RUN_QUEUE_CONCURRENCY=1 -# MEMIND_AGENT_RUN_TIMEOUT_MS=900000 +# MEMIND_AGENT_RUN_TIMEOUT_MS=1200000 +# Goose 页面任务超时且未产出 HTML 时,由 Cursor 执行器接管重试(需 MEMIND_CURSOR_EXECUTOR_ENABLED=1) +# MEMIND_CURSOR_PAGE_TIMEOUT_TAKEOVER=1 # P6.1 外部 Tool Worker 接管入口。默认 Portal 内部 auto-dispatch 保持开启; # 只有外部 worker 验证就绪后,才把 Portal 设为 0 并独立运行 scripts/agent-run-worker.mjs。 # MEMIND_AGENT_RUN_AUTODISPATCH=1 @@ -130,6 +132,15 @@ H5_PUBLIC_BASE_URL=http://127.0.0.1:5173 # TKMIND_API_TARGET=https://127.0.0.1:18006 # TKMIND_API_TARGET_1=https://127.0.0.1:18007 +# DashScope / nassaapi 中转兼容代理(deepseek-cp 等;默认 :18037) +# - 自动把 max_tokens 截到 131072,避免 DashScope 400 +# - 出站限流默认 10 次/分钟,与中转商配额对齐 +# MEMIND_RELAY_COMPAT_PORT=18037 +# MEMIND_RELAY_UPSTREAM_BASE=https://card.nassaapi.xyz +# MEMIND_RELAY_MAX_PER_MINUTE=10 +# MEMIND_RELAY_COMPAT_HOST=host.docker.internal +# MEMIND_RELAY_COMPAT_ENABLED=1 + # H5 Router normalized decision(docs/h5-session-architecture-20260706.md Patch 3) # 默认 0/off:gateway 仍读 legacy route # shadow:只打 [router-shadow] 日志,行为不变 diff --git a/docs/branch-disposition.md b/docs/branch-disposition.md index 7dd5eff..7173160 100644 --- a/docs/branch-disposition.md +++ b/docs/branch-disposition.md @@ -1,6 +1,24 @@ # 历史分支处置登记 -本文件记录已经完成迁移、但仍可能因为 Git 拓扑或遗留 worktree 被误判为“尚未进入 `main`”的分支。 +## `feature/wechat-news-morning-draft-worker` + +**状态:禁止再次引用。已 fast-forward 并入 `origin/main` 并完成 103 Portal + memind_adm 发布。** + +审计日期:2026-09-11 +Memind HEAD:`1f6e8c9b` · memind_adm HEAD:`799afd1` + +### 交付内容 + +- Portal:`wechat-news-morning-draft-worker` 定时生成当日 `daily-news-MMDD.html` 并自动推微信草稿箱 +- 管理后台:今日早报状态卡片 + 自动预览当天页面与草稿 + +### 103 发布记录 + +- Portal runtime:`20260911-090522-1f6e8c9b`(快速发布,`STUDIO_HOST=10.10.0.2`) +- memind_adm:`20260911-092700-799afd1` +- 发布后日志:`WeChat news morning draft worker enabled` + +--- 它是分支复用、合并、cherry-pick 和清理前的必查清单。 ## `feature/memfuse-recall-benchmark` diff --git a/docs/goosed-local-build-delivery.md b/docs/goosed-local-build-delivery.md index 94d54ad..d59a531 100644 --- a/docs/goosed-local-build-delivery.md +++ b/docs/goosed-local-build-delivery.md @@ -188,10 +188,10 @@ ls -lh goosed.tar # 3. 传输到 103 # 方式 1: 通过 scp -scp goosed.tar john@103:~/incoming/ +scp goosed.tar john@180.159.29.143:~/incoming/ # 方式 2: 通过 rsync -rsync -av goosed.tar john@103:~/incoming/ +rsync -av goosed.tar john@180.159.29.143:~/incoming/ # 4. 在 103 上导入(后续操作) # docker load -i goosed.tar @@ -287,7 +287,7 @@ docker logs docker save tkmind/goosed:local | gzip > goosed.tar.gz # 传输 -scp goosed.tar.gz john@103:~/ +scp goosed.tar.gz john@180.159.29.143:~/ # 在 103 上解压导入 gunzip < goosed.tar.gz | docker load diff --git a/docs/wechat-draft-publication-standard.md b/docs/wechat-draft-publication-standard.md new file mode 100644 index 0000000..c9d2a82 --- /dev/null +++ b/docs/wechat-draft-publication-standard.md @@ -0,0 +1,57 @@ +# 公众号草稿推送格式标准 + +版本:`2026-09-11`(代码常量 `WECHAT_DRAFT_PUBLICATION_STANDARD_VERSION`) + +本规范随公众号推送能力与 MindSpace 发布链路演进**持续更新完善**;版本号标识当前快照,发现规范缺口或实现偏差时,应同步修订本文档、校验用例与代码常量。 + +## 适用范围 + +所有 MindSpace 页面推送到**用户绑定公众号草稿箱**的流程,包括: + +- 页面详情「推送到公众号草稿箱」 +- **公开页右下角「公众号」按钮**(页面 owner 登录后可见,服务端注入) +- 公开页 quick API(`mindspace-chat-wechat-draft.mjs`) +- 后续新增的页面级草稿推送入口 + +**必须**走 `mindspace-wechat-page-draft.mjs` → `pushPageDraft()`,禁止旁路拼装 HTML 或直接调用微信 draft API。 + +每日新闻早报定时推送(`wechat-news-morning-draft.mjs`)复用同一套底部 layout(阅读原文 + 关注区),栏目正文保持早报专用结构。 + +## 正文 layout(MindSpace 页面) + +自上而下: + +1. **Hero 实图**(若有):与页面 `mindspace-cover.cover` / hero 背景 / 侧车缩略图同源,经 `uploadimg` 上传 +2. **页面正文**:按 profile 转换(诗页 / 散文 / 技能模板 / 通用语义提取) +3. **阅读原文**:12px 小胶囊链接,位于正文末尾、关注区之前;有 `publicUrl` 时必须出现 +4. **欢迎关注 TKMind 智趣** + 公众号二维码(无 logo、无额外导语) + +## 封面(thumb_media_id) + +优先级: + +1. **Hero 位图**(webp/png/jpeg 等,与正文顶部 hero 同源) +2. `{页面}.thumbnail.png` 侧车图(仅当无 hero 时) +3. `{页面}.thumbnail.svg` 矢量侧车图(无 PNG 时,推送前转为 PNG) +4. TKMind 占位图 + +无 AI 生成图时,正文 Hero 与封面均可回退到 PNG/SVG 侧车缩略图。 + +## 校验 + +本地/CI: + +```bash +npm run verify:mindspace-wechat-mp +``` + +核心断言见 `wechat-draft-publication-standard.test.mjs`。 + +## 相关文件 + +| 文件 | 职责 | +|------|------| +| `wechat-draft-publication-standard.mjs` | 标准常量 + 合规校验 | +| `wechat-draft-article-layout.mjs` | 阅读原文 + 底部关注区 | +| `mindspace-wechat-page-draft.mjs` | 转换、封面上传、`pushPageDraft` | +| `mindspace-chat-wechat-draft.mjs` | 公开页 quick 推送(委托 `pushPageDraft`) | diff --git a/mindspace-chat-wechat-draft.mjs b/mindspace-chat-wechat-draft.mjs new file mode 100644 index 0000000..db3e28b --- /dev/null +++ b/mindspace-chat-wechat-draft.mjs @@ -0,0 +1,162 @@ +import path from 'node:path'; +import { normalizeWorkspaceRelativePath } from './mindspace-workspace-relative-path.mjs'; +import { validatePageForWechatDraft } from './mindspace-wechat-page-draft.mjs'; + +function normalizePublicHtmlRelativePath(relativePath) { + const normalized = normalizeWorkspaceRelativePath(relativePath); + if (!normalized || !normalized.startsWith('public/') || !normalized.toLowerCase().endsWith('.html')) { + throw Object.assign(new Error('仅支持 workspace 公开 HTML 页面'), { code: 'invalid_public_html_path' }); + } + return normalized; +} + +function titleFromPublicHtml(html, relativePath) { + const match = String(html ?? '').match(/]*>([\s\S]*?)<\/title>/i); + const fromTitle = match?.[1]?.replace(/\s+/g, ' ').trim(); + if (fromTitle) return fromTitle; + const basename = path.basename(String(relativePath ?? ''), '.html'); + return basename || 'MindSpace 页面'; +} + +async function resolvePublicHtmlContext({ + user, + relativePath, + mindSpacePages, + mindSpacePublications, + readWorkspaceHtml, +}) { + if (!mindSpacePages) { + throw Object.assign(new Error('MindSpace 页面服务未启用'), { code: 'mindspace_unavailable' }); + } + if (typeof readWorkspaceHtml !== 'function') { + throw Object.assign(new Error('MindSpace 页面读取服务不可用'), { code: 'mindspace_read_unavailable' }); + } + + const normalized = normalizePublicHtmlRelativePath(relativePath); + const { html: content } = await readWorkspaceHtml({ + userId: user.id, + relativePath: normalized, + }); + + const page = await mindSpacePages.findPageByRelativePath(user.id, normalized); + if (!page?.id) { + throw Object.assign(new Error('无法识别页面对应的 MindSpace 记录'), { code: 'page_not_found' }); + } + + let publicUrl = ''; + if (mindSpacePublications?.getCurrent) { + const publication = await mindSpacePublications.getCurrent(user.id, page.id); + publicUrl = publication?.publicUrl ?? ''; + } + + return { + normalized, + content, + page, + pageTitle: page.title || titleFromPublicHtml(content, normalized), + pageSummary: page.summary ?? '', + publicUrl, + }; +} + +export async function getQuickWechatDraftFromPublicHtmlStatus({ + user, + relativePath, + mindSpacePages, + mindSpacePublications, + readWorkspaceHtml, + getWechatMpConfig, + getWechatPageDraft, +}) { + const configService = getWechatMpConfig?.(); + const config = configService + ? await configService.getConfig(user.id) + : { configured: false }; + + let context = null; + let validation = null; + try { + context = await resolvePublicHtmlContext({ + user, + relativePath, + mindSpacePages, + mindSpacePublications, + readWorkspaceHtml, + }); + validation = validatePageForWechatDraft(context.content, { + pageTitle: context.pageTitle, + pageSummary: context.pageSummary, + publicUrl: context.publicUrl, + }); + } catch (error) { + if (error?.code === 'page_not_found' || error?.code === 'invalid_public_html_path') { + return { + configured: Boolean(config.configured), + pageId: null, + canPush: false, + validation: { + ok: false, + profile: 'unknown', + blockers: [error.message], + warnings: [], + estimatedContentLength: 0, + }, + }; + } + throw error; + } + + let latestRun = null; + const draftService = getWechatPageDraft?.(); + if (draftService?.listRuns) { + const runs = await draftService.listRuns(user.id, { pageId: context.page.id, limit: 1 }); + latestRun = runs[0] ?? null; + } + + return { + configured: Boolean(config.configured), + pageId: context.page.id, + pageTitle: context.pageTitle, + canPush: Boolean(config.configured) && validation.ok, + validation, + latestRun, + }; +} + +export async function quickWechatDraftFromPublicHtml({ + user, + relativePath, + mindSpacePages, + mindSpacePublications, + readWorkspaceHtml, + getWechatPageDraft, +}) { + const draftService = getWechatPageDraft?.(); + if (!draftService?.pushPageDraft) { + throw Object.assign(new Error('公众号草稿推送未启用'), { code: 'wechat_draft_unavailable' }); + } + + const context = await resolvePublicHtmlContext({ + user, + relativePath, + mindSpacePages, + mindSpacePublications, + readWorkspaceHtml, + }); + const validation = validatePageForWechatDraft(context.content, { + pageTitle: context.pageTitle, + pageSummary: context.pageSummary, + publicUrl: context.publicUrl, + }); + if (!validation.ok) { + throw Object.assign(new Error(validation.blockers[0] ?? '页面不符合公众号草稿推送要求'), { + code: 'wechat_draft_validation_failed', + validation, + }); + } + + return draftService.pushPageDraft(user.id, context.page.id, { + triggeredBy: user.id, + skipValidation: true, + }); +} diff --git a/mindspace-chat-wechat-draft.test.mjs b/mindspace-chat-wechat-draft.test.mjs new file mode 100644 index 0000000..cede6cd --- /dev/null +++ b/mindspace-chat-wechat-draft.test.mjs @@ -0,0 +1,103 @@ +import assert from 'node:assert/strict'; +import test from 'node:test'; +import { + getQuickWechatDraftFromPublicHtmlStatus, + quickWechatDraftFromPublicHtml, +} from './mindspace-chat-wechat-draft.mjs'; + +const SAMPLE_HTML = `测试页面

标题

正文

`; + +test('getQuickWechatDraftFromPublicHtmlStatus reports validation and config state', async () => { + const result = await getQuickWechatDraftFromPublicHtmlStatus({ + user: { id: 'user-1' }, + relativePath: 'public/demo.html', + mindSpacePages: { + async findPageByRelativePath(userId, relativePath) { + assert.equal(userId, 'user-1'); + assert.equal(relativePath, 'public/demo.html'); + return { id: 'page-1', title: '测试页面', summary: '摘要' }; + }, + }, + mindSpacePublications: { + async getCurrent(userId, pageId) { + assert.equal(userId, 'user-1'); + assert.equal(pageId, 'page-1'); + return { publicUrl: 'https://m.tkmind.cn/u/demo/pages/demo.html' }; + }, + }, + readWorkspaceHtml: async ({ userId, relativePath }) => { + assert.equal(userId, 'user-1'); + assert.equal(relativePath, 'public/demo.html'); + return { html: SAMPLE_HTML }; + }, + getWechatMpConfig: () => ({ + async getConfig() { + return { configured: true }; + }, + }), + getWechatPageDraft: () => ({ + async listRuns() { + return []; + }, + }), + }); + + assert.equal(result.pageId, 'page-1'); + assert.equal(result.configured, true); + assert.equal(result.canPush, true); + assert.equal(result.validation.profile, 'generic'); +}); + +test('quickWechatDraftFromPublicHtml validates before push', async () => { + await assert.rejects( + () => quickWechatDraftFromPublicHtml({ + user: { id: 'user-1' }, + relativePath: 'public/empty.html', + mindSpacePages: { + async findPageByRelativePath() { + return { id: 'page-1', title: '', summary: '' }; + }, + }, + mindSpacePublications: { + async getCurrent() { + return { publicUrl: 'https://example.com/empty.html' }; + }, + }, + readWorkspaceHtml: async () => ({ html: '' }), + getWechatPageDraft: () => ({ + async pushPageDraft() { + throw new Error('should not push invalid page'); + }, + }), + }), + (error) => error.code === 'wechat_draft_validation_failed', + ); +}); + +test('quickWechatDraftFromPublicHtml delegates to draft service', async () => { + const calls = []; + const result = await quickWechatDraftFromPublicHtml({ + user: { id: 'user-1' }, + relativePath: 'public/demo.html', + mindSpacePages: { + async findPageByRelativePath() { + return { id: 'page-1', title: '测试页面', summary: '摘要' }; + }, + }, + mindSpacePublications: { + async getCurrent() { + return { publicUrl: 'https://example.com/demo.html' }; + }, + }, + readWorkspaceHtml: async () => ({ html: SAMPLE_HTML }), + getWechatPageDraft: () => ({ + async pushPageDraft(userId, pageId, options) { + calls.push([userId, pageId, options]); + return { ok: true, draftMediaId: 'draft-1' }; + }, + }), + }); + + assert.deepEqual(calls, [['user-1', 'page-1', { triggeredBy: 'user-1', skipValidation: true }]]); + assert.equal(result.draftMediaId, 'draft-1'); +}); diff --git a/mindspace-public-share-widget.mjs b/mindspace-public-share-widget.mjs index bce2957..cb0cf9a 100644 --- a/mindspace-public-share-widget.mjs +++ b/mindspace-public-share-widget.mjs @@ -7,7 +7,9 @@ if(!root)return; var shareButton=root.querySelector('[data-action="share"]'); var captureButton=root.querySelector('[data-action="capture"]'); var plazaButton=root.querySelector('[data-action="plaza"]'); +var wechatButton=root.querySelector('[data-action="wechat-draft"]'); var dialog=root.querySelector('[data-mindspace-public-share-dialog]'); +var wechatDialog=root.querySelector('[data-mindspace-wechat-dialog]'); var plazaCancel=root.querySelector('[data-action="plaza-cancel"]'); var plazaConfirm=root.querySelector('[data-action="plaza-confirm"]'); var plazaAlreadyClose=root.querySelector('[data-action="plaza-already-close"]'); @@ -103,6 +105,92 @@ showPlazaView('error'); setStatus(e&&e.message?e.message:'发布失败',true); }finally{publishing=false;plazaConfirm.disabled=false;} }); +if(wechatButton&&wechatDialog){ +var wechatCancel=wechatDialog.querySelector('[data-action="wechat-cancel"]'); +var wechatConfirm=wechatDialog.querySelector('[data-action="wechat-confirm"]'); +var wechatSuccessClose=wechatDialog.querySelector('[data-action="wechat-success-close"]'); +var wechatErrorClose=wechatDialog.querySelector('[data-action="wechat-error-close"]'); +var wechatBlockedClose=wechatDialog.querySelector('[data-action="wechat-blocked-close"]'); +var wechatForbiddenClose=wechatDialog.querySelector('[data-action="wechat-forbidden-close"]'); +var wechatDraftId=wechatDialog.querySelector('[data-wechat-draft-id]'); +var wechatHint=wechatDialog.querySelector('[data-wechat-view="confirm"] [data-wechat-hint]'); +var wechatViews={ + confirm:wechatDialog.querySelector('[data-wechat-view="confirm"]'), + loading:wechatDialog.querySelector('[data-wechat-view="loading"]'), + success:wechatDialog.querySelector('[data-wechat-view="success"]'), + error:wechatDialog.querySelector('[data-wechat-view="error"]'), + blocked:wechatDialog.querySelector('[data-wechat-view="blocked"]'), + forbidden:wechatDialog.querySelector('[data-wechat-view="forbidden"]') +}; +var pushing=false; +var wechatChecking=false; +function isPageOwner(){return root.getAttribute('data-is-owner')==='true';} +function showWechatView(name){Object.keys(wechatViews).forEach(function(key){var view=wechatViews[key];if(view)view.hidden=key!==name;});} +function openWechatDialog(){ +wechatDialog.hidden=false; +if(!isPageOwner()){showWechatView('forbidden');return;} +showWechatView('loading'); +void refreshWechatDialog(); +} +function closeWechatDialog(){wechatDialog.hidden=true;showWechatView('confirm');} +function setWechatHint(text){if(wechatHint)wechatHint.textContent=text||'';} +async function refreshWechatDialog(){ +if(wechatChecking)return; +var relativePath=workspaceRelativePath(); +if(!relativePath){showWechatView('error');setWechatHint('无法识别页面路径');return;} +wechatChecking=true; +try{ +var res=await fetch('/api/mindspace/v1/pages/quick-wechat-draft-from-public-html/status?relative_path='+encodeURIComponent(relativePath),{credentials:'same-origin'}); +var payload=await res.json().catch(function(){return{};}); +if(!res.ok){ +if(res.status===401)throw new Error('请先登录 MindSpace'); +var errBody=apiErrorBody(payload); +throw new Error(errBody.message||'无法检查公众号草稿状态'); +} +var data=payload.data||{}; +if(!data.configured){showWechatView('blocked');setWechatHint('请先在 M 配置中绑定公众号 AppID 和 AppSecret。');return;} +var blockers=(data.validation&&data.validation.blockers)||[]; +if(!data.canPush){showWechatView('error');setWechatHint(blockers[0]||'当前页面暂不符合推送要求');return;} +setWechatHint(data.pageTitle||'当前页面'); +showWechatView('confirm'); +}catch(e){ +showWechatView('error'); +setWechatHint(e&&e.message?e.message:'无法检查公众号草稿状态'); +}finally{wechatChecking=false;} +} +wechatButton.addEventListener('click',openWechatDialog); +wechatCancel&&wechatCancel.addEventListener('click',closeWechatDialog); +wechatSuccessClose&&wechatSuccessClose.addEventListener('click',closeWechatDialog); +wechatErrorClose&&wechatErrorClose.addEventListener('click',closeWechatDialog); +wechatBlockedClose&&wechatBlockedClose.addEventListener('click',closeWechatDialog); +wechatForbiddenClose&&wechatForbiddenClose.addEventListener('click',closeWechatDialog); +wechatDialog.addEventListener('click',function(event){if(event.target===wechatDialog)closeWechatDialog();}); +wechatConfirm&&wechatConfirm.addEventListener('click',async function(){ +if(pushing)return; +var relativePath=workspaceRelativePath(); +if(!relativePath){setStatus('无法识别页面路径',true);closeWechatDialog();return;} +pushing=true; +wechatConfirm.disabled=true; +showWechatView('loading'); +setWechatHint('正在推送到公众号草稿箱…'); +try{ +var res=await fetch('/api/mindspace/v1/pages/quick-wechat-draft-from-public-html',{method:'POST',credentials:'same-origin',headers:{'Content-Type':'application/json'},body:JSON.stringify({relative_path:relativePath})}); +var payload=await res.json().catch(function(){return{};}); +if(!res.ok){ +if(res.status===401)throw new Error('请先登录 MindSpace'); +var errBody=apiErrorBody(payload); +throw new Error(errBody.message||'推送失败'); +} +var data=payload.data||{}; +showWechatView('success'); +if(wechatDraftId){wechatDraftId.textContent=data.draftMediaId?'草稿 media_id:'+data.draftMediaId:'';} +setStatus('已推送到公众号草稿箱',false,true); +}catch(e){ +showWechatView('error'); +setWechatHint(e&&e.message?e.message:'推送失败'); +}finally{pushing=false;wechatConfirm.disabled=false;} +}); +} })();`; const PUBLIC_FILE_SHARE_SCRIPT_HASH = crypto @@ -110,9 +198,16 @@ const PUBLIC_FILE_SHARE_SCRIPT_HASH = crypto .update(PUBLIC_FILE_SHARE_SCRIPT) .digest('base64'); +const PUBLIC_FILE_SHARE_WIDGET_BLOCK_PATTERN = + / -
-${plazaDialogMarkup} +
+${plazaDialogMarkup}${wechatDialogMarkup}
-${plazaButtonMarkup} +${wechatButtonMarkup}${plazaButtonMarkup}
@@ -212,4 +357,5 @@ ${plazaButtonMarkup}