Skip to content

Commit fee3546

Browse files
authored
Merge pull request #2617 from 16Miku/agent/wechat-official-account-adapter
agent: add adapter for WeChat Official Accounts
2 parents 340df57 + 3a1392d commit fee3546

3 files changed

Lines changed: 60 additions & 0 deletions

File tree

src/chrome/src/agent/adapters.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15942,6 +15942,21 @@ const ADAPTERS = [
1594215942
- Login pages (\`wp-login.php\`) have a stable shape: \`#user_login\` (username/email), \`#user_pass\` (password), \`#wp-submit\` (submit). The password field is type=password — when the user provides credentials, do not echo them in any summary.`,
1594315943
},
1594415944

15945+
{
15946+
name: 'wechat-official-account',
15947+
category: 'general',
15948+
matches: (url) => /^https?:\/\/mp\.weixin\.qq\.com\/(?:$|[?#]|cgi-bin(?:[/?#]|$))/.test(url),
15949+
notes: `
15950+
- Confirm the current official account name in the top bar before editing or publishing; an old tab or session-token URL may belong to a different account.
15951+
- The article editor has separate title and body editable regions. The body uses ProseMirror/contenteditable; focus each region separately and verify its text after writing so the title is not inserted into the body or vice versa.
15952+
- "保存为草稿" (Save as draft) and "发表" (Publish) are different outcomes. A saved draft is not publicly visible and must never be reported as published.
15953+
- Under "封面" (Cover), "从正文选择" (Select from article) can reuse an inline image. Confirm the intended image and crop instead of accepting the first thumbnail automatically.
15954+
- Before clicking "发表", re-check the account, title, author/byline, summary, and cover because publishing is externally visible.
15955+
- Publishing can open stacked confirmation dialogs followed by "微信验证" with a QR code. Pause for the user to complete verification; do not dismiss, bypass, or repeatedly retry the dialog.
15956+
- Treat publishing as successful only when "发表记录" shows the new article (or a final public article URL is available), not when the editor closes or a confirmation button was clicked.
15957+
- Dashboard links contain short-lived session tokens. If a deep link expires or redirects, navigate from the current dashboard instead of inventing or reusing a tokenized URL.`,
15958+
},
15959+
1594515960
// ─── Commerce ─────────────────────────────────────────────────────────
1594615961
{
1594715962
name: 'amazon',

src/firefox/src/agent/adapters.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15940,6 +15940,21 @@ const ADAPTERS = [
1594015940
- Login pages (\`wp-login.php\`) have a stable shape: \`#user_login\` (username/email), \`#user_pass\` (password), \`#wp-submit\` (submit). The password field is type=password — when the user provides credentials, do not echo them in any summary.`,
1594115941
},
1594215942

15943+
{
15944+
name: 'wechat-official-account',
15945+
category: 'general',
15946+
matches: (url) => /^https?:\/\/mp\.weixin\.qq\.com\/(?:$|[?#]|cgi-bin(?:[/?#]|$))/.test(url),
15947+
notes: `
15948+
- Confirm the current official account name in the top bar before editing or publishing; an old tab or session-token URL may belong to a different account.
15949+
- The article editor has separate title and body editable regions. The body uses ProseMirror/contenteditable; focus each region separately and verify its text after writing so the title is not inserted into the body or vice versa.
15950+
- "保存为草稿" (Save as draft) and "发表" (Publish) are different outcomes. A saved draft is not publicly visible and must never be reported as published.
15951+
- Under "封面" (Cover), "从正文选择" (Select from article) can reuse an inline image. Confirm the intended image and crop instead of accepting the first thumbnail automatically.
15952+
- Before clicking "发表", re-check the account, title, author/byline, summary, and cover because publishing is externally visible.
15953+
- Publishing can open stacked confirmation dialogs followed by "微信验证" with a QR code. Pause for the user to complete verification; do not dismiss, bypass, or repeatedly retry the dialog.
15954+
- Treat publishing as successful only when "发表记录" shows the new article (or a final public article URL is available), not when the editor closes or a confirmation button was clicked.
15955+
- Dashboard links contain short-lived session tokens. If a deep link expires or redirects, navigate from the current dashboard instead of inventing or reusing a tokenized URL.`,
15956+
},
15957+
1594315958
// ─── Commerce ─────────────────────────────────────────────────────────
1594415959
{
1594515960
name: 'amazon',

test/run.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2330,6 +2330,36 @@ test('matches Xiaohongshu surfaces with mirrored regional guidance', () => {
23302330
assert.match(chromeAdapter?.notes || '', /Creator Center.*final public note URL/s);
23312331
});
23322332

2333+
test('matches WeChat Official Account admin surfaces with safe publishing guidance', () => {
2334+
const urls = [
2335+
'https://mp.weixin.qq.com/',
2336+
'https://mp.weixin.qq.com/cgi-bin/home?t=home/index&lang=zh_CN&token=123',
2337+
'https://mp.weixin.qq.com/cgi-bin/appmsg?t=media/appmsg_edit_v2&action=edit&type=77&token=123&lang=zh_CN',
2338+
];
2339+
for (const url of urls) {
2340+
assert.equal(getActiveAdapter(url)?.name, 'wechat-official-account', `chrome did not match ${url}`);
2341+
assert.equal(getActiveAdapterFx(url)?.name, 'wechat-official-account', `firefox did not match ${url}`);
2342+
}
2343+
assert.notEqual(
2344+
getActiveAdapter('https://mp.weixin.qq.com.evil.example/cgi-bin/home')?.name,
2345+
'wechat-official-account',
2346+
);
2347+
assert.notEqual(
2348+
getActiveAdapter('https://example.com/?next=https://mp.weixin.qq.com/')?.name,
2349+
'wechat-official-account',
2350+
);
2351+
2352+
const chromeAdapter = getActiveAdapter(urls[1]);
2353+
const firefoxAdapter = getActiveAdapterFx(urls[1]);
2354+
assert.equal(firefoxAdapter?.notes, chromeAdapter?.notes);
2355+
assert.match(chromeAdapter?.notes || '', /separate title and body.*ProseMirror\/contenteditable/s);
2356+
assert.match(chromeAdapter?.notes || '', /保存为草稿.*发表.*not publicly visible/s);
2357+
assert.match(chromeAdapter?.notes || '', /从正文选择.*intended image and crop/s);
2358+
assert.match(chromeAdapter?.notes || '', /微信验证.*QR code.*Pause for the user/s);
2359+
assert.match(chromeAdapter?.notes || '', /发表记录.*public article URL/s);
2360+
assert.match(chromeAdapter?.notes || '', /short-lived session tokens.*current dashboard/s);
2361+
});
2362+
23332363
test('regional social action shims expose Bilibili and Xiaohongshu custom controls', () => {
23342364
const axChrome = fs.readFileSync(path.join(ROOT, 'src/chrome/src/content/accessibility-tree.js'), 'utf8');
23352365
const axFirefox = fs.readFileSync(path.join(ROOT, 'src/firefox/src/content/accessibility-tree.js'), 'utf8');

0 commit comments

Comments
 (0)