fix(wechat): defer 45047/45015 delivery and control customer message budget
Memind CI / Test, build, and release guards (push) Failing after 10s
Memind CI / Test, build, and release guards (push) Failing after 10s
Persist formal replies when WeChat customer-service quota is exhausted, claim them once on the next passive response, skip progress notices for page generation, and suppress failure notices while a formal reply is pending. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+56
-4
@@ -1220,7 +1220,7 @@ test('wechat mp service splits long agent replies into multiple customer message
|
||||
assert.equal(combined, longReply);
|
||||
});
|
||||
|
||||
test('wechat mp service surfaces wechat customer-service errcode and errmsg', async () => {
|
||||
test('wechat mp service defers 45047 customer-service delivery instead of throwing', async () => {
|
||||
const service = createBoundWechatService({
|
||||
userAuth: {
|
||||
async getWechatOpenidForUser() {
|
||||
@@ -1241,10 +1241,62 @@ test('wechat mp service surfaces wechat customer-service errcode and errmsg', as
|
||||
},
|
||||
});
|
||||
|
||||
await assert.rejects(
|
||||
service.sendTextToUser('user-1', 'hello'),
|
||||
/errcode=45047.*out of response count limit/,
|
||||
const result = await service.sendTextToUser('user-1', 'hello');
|
||||
assert.equal(result.deferred, true);
|
||||
assert.equal(result.errcode, 45047);
|
||||
});
|
||||
|
||||
test('wechat mp service claims deferred delivery on next passive response once', async () => {
|
||||
const token = 'token';
|
||||
const timestamp = '1710000000';
|
||||
const nonce = 'nonce';
|
||||
const service = createBoundWechatService({
|
||||
config: {
|
||||
progressDelayMs: 0,
|
||||
ackText: '已收到',
|
||||
},
|
||||
userAuth: {
|
||||
async getWechatOpenidForUser() {
|
||||
return 'openid-1';
|
||||
},
|
||||
},
|
||||
wechatFetch: async (url) => {
|
||||
if (String(url).includes('/cgi-bin/stable_token')) {
|
||||
return new Response(JSON.stringify({ access_token: 'access-1', expires_in: 7200 }), {
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
});
|
||||
}
|
||||
return new Response(JSON.stringify({ errcode: 45047, errmsg: 'out of response count limit rid: test-rid' }), {
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
const deferred = await service.sendTextToUser(
|
||||
'user-1',
|
||||
'页面已生成:https://example.com/MindSpace/user-1/public/demo.html',
|
||||
);
|
||||
assert.equal(deferred.deferred, true);
|
||||
assert.equal(deferred.errcode, 45047);
|
||||
|
||||
const claimed = await service.handleInboundMessage(inboundXml({ content: '继续' }), {
|
||||
timestamp,
|
||||
nonce,
|
||||
signature: signatureFor(token, timestamp, nonce),
|
||||
});
|
||||
assert.equal(claimed.status, 200);
|
||||
assert.match(String(claimed.body), /demo\.html/);
|
||||
assert.doesNotMatch(String(claimed.body), /已收到/);
|
||||
|
||||
const followUp = await service.handleInboundMessage(inboundXml({ content: '再来一条' }), {
|
||||
timestamp,
|
||||
nonce,
|
||||
signature: signatureFor(token, timestamp, nonce),
|
||||
});
|
||||
assert.doesNotMatch(String(followUp.body), /demo\.html/);
|
||||
assert.ok(followUp.task);
|
||||
});
|
||||
|
||||
test('wechat mp service strips markdown emphasis around outbound links', async () => {
|
||||
|
||||
Reference in New Issue
Block a user