Add smart ACK provider for WeChat MP replies

Replace fixed ackText with a rule-based AckProvider that picks
response templates by message type and intent (translate, summary,
rewrite, poster, ppt, mindmap, code, search, schedule). Pure sync,
zero I/O, auto-falls back to config.ackText on any error.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
john
2026-06-26 15:19:03 +08:00
parent 9ed4fd48d7
commit 9b4a25799f
162 changed files with 17276 additions and 2054 deletions
+21 -3
View File
@@ -12,6 +12,7 @@
// The same factory functions imported here are the ones server.mjs uses, so the
// domain logic has a single source of truth; only the wiring differs.
import path from 'node:path';
import { createSubscriptionService } from './billing-subscription.mjs';
import { createDbPool, isDatabaseConfigured } from './db.mjs';
import { createUserAuth } from './user-auth.mjs';
import { createLlmProviderService } from './llm-providers.mjs';
@@ -21,7 +22,7 @@ import { createPlazaOpsService } from './plaza-ops.mjs';
import { createNoopPlazaRedis } from './plaza-redis.mjs';
import { ensureAlgorithmConfig, loadAlgorithmConfig } from './plaza-algorithm.mjs';
import { createWechatAdminService } from './wechat-admin.mjs';
import { loadWechatMpConfig } from './wechat-mp.mjs';
import { createWechatMpService, loadWechatMpConfig } from './wechat-mp.mjs';
const noop = () => {};
@@ -77,21 +78,38 @@ export async function createAdminServices(env = {}) {
});
// --- platform super-admin services ---
const subscriptionService = createSubscriptionService(pool);
const userAuth = createUserAuth(pool, {
usersRoot,
h5Root,
defaultSignupBalanceCents,
subscriptionService,
});
if (env.ensureAdminUser !== false) {
await userAuth.ensureAdminUser();
}
const llmProviderService = createLlmProviderService(pool, { apiTarget, apiSecret });
const wechatMpConfig = loadWechatMpConfig();
const wechatMpService = createWechatMpService({
config: wechatMpConfig,
userAuth,
apiFetch: async () => {
throw new Error('admin bootstrap does not proxy WeChat chat sessions');
},
});
userAuth.setRechargeNotifier(async ({ userId, title, body }) => {
if (!wechatMpService?.enabled) return;
await wechatMpService.sendTextToUser(userId, `${title}\n${body}`.trim());
});
const wechatAdmin = createWechatAdminService(pool, {
config: loadWechatMpConfig(),
config: wechatMpConfig,
scheduleEnabled: process.env.H5_SCHEDULE_ENABLED === '1',
reminderWorkerEnabled: process.env.H5_REMINDER_WORKER_ENABLED === '1',
sendWechatTextToUser: wechatMpService?.enabled
? (userId, text) => wechatMpService.sendTextToUser(userId, text)
: null,
});
return { pool, userAuth, llmProviderService, plazaPosts, plazaOps, wechatAdmin };
return { pool, userAuth, llmProviderService, plazaPosts, plazaOps, wechatAdmin, subscriptionService };
}