Xms export automation
Skill xuluoforcainiao/xms-export-automation/xms-export-automation
Automates the XMS customer service abnormal item export workflow. Covers SSO login, clearing the shelf organization filter, exporting abnormal items, polling the download center, downloading the result file, and optionally uploading to DingTalk. Use when the user needs to export XMS abnormal items, set up scheduled XMS exports, or manage XMS data delivery.From its SKILL.md
npx -y skills add xuluoforcainiao/xms-export-automation --skill xms-export-automationAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
9.3 KB, ~2.3k tokens by cl100k_base, as published. Nobody here has run it
XMS 异常件导出自动化
Overview
Automates the full workflow of exporting abnormal items from the XMS customer service system (cs-packet.i4px.com). The workflow includes browser health checks, SSO login, data export, polling for completion, file download, and optional DingTalk delivery.
Prerequisites
Create a configuration file webhook_config.json (managed by xms_config_manager.py):
{
"xms": {
"url": "http://cs.packet.i4px.com/",
"username": "YOUR_USERNAME",
"password": "YOUR_PASSWORD"
},
"webhooks": [
{
"name": "Group Name",
"token": "dingtalk_robot_token",
"keyword": "required_keyword",
"folderId": "https://alidocs.dingtalk.com/i/nodes/YOUR_FOLDER_ID",
"enabled": true,
"schedule": {
"timeSlots": [{"hour": 9, "minute": 0}],
"days": [1, 2, 3, 4, 5, 6, 0]
}
}
],
"export": {
"poll_interval_seconds": 120,
"max_wait_minutes": 70,
"file_name_template": "xms异常件导出_{timestamp}.xlsx",
"max_retries": 3,
"retry_interval_seconds": 60,
"browser_max_recovery_attempts": 4,
"send_notification_on_failure": true
}
}
days: 0=Sunday, 1=Monday, ..., 6=Saturdaypoll_interval_seconds: Seconds between progress checksmax_wait_minutes: Max total wait time for export completionmax_retries: Max full-workflow retry attempts when any phase failsretry_interval_seconds: Seconds to wait between retry attemptsbrowser_max_recovery_attempts: Max browser recovery strategies to try per attemptsend_notification_on_failure: Whether to send a DingTalk alert when all retries exhausted
Retry & Error Handling
The automation runs inside an outer retry loop:
- Browser recovery first: Each attempt begins with a 4-step browser health check (check size → JS resize → new tab → recreate window). If the browser MCP returns "Extension not connected" or
0x0, the agent progressively escalates recovery strategies. - Phase-level retries: If login, export trigger, polling, download, or DingTalk upload fails, the agent records the error, waits
retry_interval_seconds, and restarts the entire workflow from browser recovery. - Failure notification: If all
max_retriesare exhausted andsend_notification_on_failureis true, the agent sends a DingTalk message to every matched webhook reporting the failure reason, so you are never left in the dark.
Workflow
Phase 0: Read Config & Filter Webhooks
- Read
webhook_config.json - Get current Beijing time (
Asia/Shanghai) and day of week - For each webhook where
enabled=true, check if current time matches anytimeSlotsand current day is indays - Collect matching webhooks. If none match and this is a scheduled run, exit silently
Phase 0.5: Browser Window Health Check
Before any interaction, verify the browser window:
- Check size:
window.innerWidth + ',' + window.innerHeight - JS resize: If broken,
window.moveTo(0,0); window.resizeTo(1440,900)then wait 2s and recheck - New tab: Call
tabs_create_mcp, check new tab size - Recreate window: Close all tabs one by one (
tabs_close_mcponly accepts a singletabIdper call), thentabs_context_mcpwithcreateIfEmpty:true - Small window fallback: If persistently small (e.g., 256x116) but not
0,0, DOM operations still work. Only terminate if literally0,0after all steps
Phase 1: Login
- Navigate to
http://cs.packet.i4px.com/ - If redirected to
sso.i4px.com, inject credentials via JavaScript:document.getElementById('username').value = USERNAME; document.getElementById('passwordOrg').value = PASSWORD; ['input', 'change', 'keyup'].forEach(evt => { document.getElementById('username').dispatchEvent(new Event(evt, {bubbles:true})); document.getElementById('passwordOrg').dispatchEvent(new Event(evt, {bubbles:true})); }); document.getElementById('signbtn').click(); - Handle "already logged in elsewhere" dialog: If a dialog appears saying "此账号已在别的地方登录" or similar, click the "是"/"确定" button to continue
- Handle QR code / device verification: If after clicking login, a QR code scan, mobile device authentication popup, or slider captcha appears that the Agent cannot complete automatically:
- Do NOT retry repeatedly
- Immediately notify the user via IM (e.g., 小Q channel)
- Wait 3 minutes, then recheck if the page has redirected to XMS homepage
- If still not redirected after timeout, record error and exit to failure notification
- Handle "server exception" error: If at any point the page displays "服务器异常" (or "系统异常"/"服务异常"):
- Close the current tab using
tabs_close_mcp - Create a new tab using
tabs_create_mcp - Re-navigate to
http://cs.packet.i4px.com/in the new tab - Restart the login flow from Phase 1 Step 1
- This counts toward the outer retry loop's
max_retries
Do NOT repeatedly interact with the error page. Always close and recreate the tab.
- Close the current tab using
- Login timeout: If the login page URL does not change within 3 minutes and no special scenario above occurs, record "XMS login timeout" and handle via retry logic
- Wait for redirect to
cs-packet.i4px.com/index
Phase 2: Export Data
- Click 异常件管理 in left sidebar to expand submenu
- Click 自有业务异常件管理
- Clear the shelf organization field (critical):
- The visible field is
id=txtUpShelfOgCodeShow(default value: "客户服务部") - The hidden field is
id=txtUpShelfOgCode(default value: "D000414") - Clear both via JavaScript:
.value = ''then dispatchinput/changeevents - Alternative: left-click inside the input field on the right side of the text; the text should disappear automatically
- The visible field is
- Click 查询 (
id=abnormalSearch) - Wait for data, then click 导出原因(新) button (top-right)
Phase 3: Poll for Completion
- Click 下载中心 to open the export records dialog
- Read the drawer table. First data row shows: task name, file size, progress %, status, export time, download action
- If progress is not 100%, wait
poll_interval_seconds, click 刷新, and recheck - Repeat until 100% or
max_wait_minutesexceeded
Modal reading tip:
read_pageandget_page_textcannot see modal overlays. Usecomputerscreenshot or JavaScript DOM queries on.next-drawerto read the export record table.
Phase 4: Download
- Read the 导出时间 from the first row (format:
2026-05-09 22:59:29) - Generate filename:
xms异常件导出_2026-05-09 22_59_29.xlsx(replace colons with underscores for Windows compatibility) - Click the 下载 button in the first row's action cell
- Find the downloaded file in
~/Downloads/(filename starts withxms-cts-) - Copy to output directory with the generated filename
Phase 5: DingTalk Delivery (Optional)
For each matched webhook:
- Call
get_file_upload_infofor upload credentials - Upload the xlsx via HTTP PUT to
resourceUrl - Call
commit_uploaded_filewithfolderIdand filename to getnodeId - Generate permanent link:
https://alidocs.dingtalk.com/i/nodes/{nodeId} - Send message via
send_message_by_custom_robotincluding the webhook's keyword and the permanent link
Verified Element References
| Element | ID / Text | Notes |
|---|---|---|
| SSO username | id=username | Not loginName |
| SSO password | id=passwordOrg | Not loginPwd |
| SSO login button | id=signbtn | Not loginBtn |
| Shelf org visible | id=txtUpShelfOgCodeShow | Default: "客户服务部" |
| Shelf org hidden | id=txtUpShelfOgCode | Default: "D000414" |
| Query button | id=abnormalSearch | |
| Export reason button | text=导出原因(新) | |
| Download center | text=下载中心 | Opens drawer |
| Refresh button | text=刷新 | In drawer |
| Drawer table | .next-drawer table tr | First data row = latest export |
Critical Rules
- Model: When creating the QoderWork cron job, set
payload.modelto"qwork-auto"(standard model). Do not use flagship model for production. - Small window: 256x116 is functional. DOM queries,
.click(), and.valueassignments work even in tiny windows. Only abort at0,0. - tabs_close_mcp: Only accepts a single integer
tabIdper call. Close tabs one by one. - Filename: Use the export record's "导出时间", not system time. Replace
:with_for Windows filenames. - DingTalk links: Always use
https://alidocs.dingtalk.com/i/nodes/{nodeId}, never temporary OSS links. - Keywords: Every robot message must contain that webhook's configured keyword.
- Robot token parameter: Use
robotToken(notaccess_token) when callingsend_message_by_custom_robot. - Upload Content-Type: When uploading xlsx via HTTP PUT to
resourceUrl, setContent-Typeheader to an empty string"", and include the returnedAuthorizationandx-oss-dateheaders.
What ships with it: 5 files
15.8 KB alongside SKILL.md
- CHANGELOG.md12.0 KB
- config-template.json691 B
- README.md866 B
- webhook_config.json1.1 KB
- xms_export_config.json1.1 KB