Files
memind/server/portal-mindspace-wechat-routes.mjs
T
john 78b7d546c2 feat(mindspace): add WeChat MP config and one-click draft push on publish.
Let users bind their own official account credentials in M 配置 and push MindSpace pages to the WeChat draft box during or after publish, reusing the existing draft conversion pipeline.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-10 16:43:25 +08:00

127 lines
3.6 KiB
JavaScript

function assertRouter(api) {
if (
!api ||
typeof api.get !== 'function' ||
typeof api.post !== 'function' ||
typeof api.put !== 'function' ||
typeof api.delete !== 'function'
) {
throw new Error(
'attachPortalMindSpaceWechatRoutes requires an Express-compatible router',
);
}
}
export function attachPortalMindSpaceWechatRoutes(
api,
{
getWechatMpConfig = () => null,
getWechatPageDraft = () => null,
sendData,
handleMindSpaceError,
} = {},
) {
assertRouter(api);
if (typeof sendData !== 'function' || typeof handleMindSpaceError !== 'function') {
throw new Error(
'attachPortalMindSpaceWechatRoutes requires response dependencies',
);
}
api.get('/mindspace/v1/wechat-mp/config', async (req, res) => {
const service = getWechatMpConfig();
if (!service) {
return res.status(503).json({ message: '公众号配置未启用' });
}
try {
return sendData(res, req, await service.getConfig(req.currentUser.id));
} catch (error) {
return handleMindSpaceError(res, req, error);
}
});
api.put('/mindspace/v1/wechat-mp/config', async (req, res) => {
const service = getWechatMpConfig();
if (!service) {
return res.status(503).json({ message: '公众号配置未启用' });
}
try {
return sendData(
res,
req,
await service.upsertConfig(req.currentUser.id, {
appId: req.body?.app_id ?? req.body?.appId,
appSecret: req.body?.app_secret ?? req.body?.appSecret,
accountType: req.body?.account_type ?? req.body?.accountType,
label: req.body?.label,
author: req.body?.author,
verify: req.body?.verify !== false,
}),
);
} catch (error) {
return handleMindSpaceError(res, req, error);
}
});
api.post('/mindspace/v1/wechat-mp/config/verify', async (req, res) => {
const service = getWechatMpConfig();
if (!service) {
return res.status(503).json({ message: '公众号配置未启用' });
}
try {
return sendData(res, req, await service.verifyConfig(req.currentUser.id));
} catch (error) {
return handleMindSpaceError(res, req, error);
}
});
api.delete('/mindspace/v1/wechat-mp/config', async (req, res) => {
const service = getWechatMpConfig();
if (!service) {
return res.status(503).json({ message: '公众号配置未启用' });
}
try {
return sendData(res, req, await service.deleteConfig(req.currentUser.id));
} catch (error) {
return handleMindSpaceError(res, req, error);
}
});
api.post('/mindspace/v1/pages/:pageId/wechat-draft', async (req, res) => {
const service = getWechatPageDraft();
if (!service) {
return res.status(503).json({ message: '公众号草稿推送未启用' });
}
try {
return sendData(
res,
req,
await service.pushPageDraft(req.currentUser.id, req.params.pageId, {
triggeredBy: req.currentUser.id,
}),
);
} catch (error) {
return handleMindSpaceError(res, req, error);
}
});
api.get('/mindspace/v1/pages/:pageId/wechat-draft/runs', async (req, res) => {
const service = getWechatPageDraft();
if (!service) {
return res.status(503).json({ message: '公众号草稿推送未启用' });
}
try {
return sendData(
res,
req,
await service.listRuns(req.currentUser.id, {
pageId: req.params.pageId,
limit: req.query?.limit,
}),
);
} catch (error) {
return handleMindSpaceError(res, req, error);
}
});
}