Skip to content

fix(synology-chat): resolve Chat API user_id for reply delivery#23709

Merged
steipete merged 3 commits intoopenclaw:mainfrom
druide67:fix/synology-chat-user-id-resolution
Mar 2, 2026
Merged

fix(synology-chat): resolve Chat API user_id for reply delivery#23709
steipete merged 3 commits intoopenclaw:mainfrom
druide67:fix/synology-chat-user-id-resolution

Conversation

@druide67
Copy link
Contributor

@druide67 druide67 commented Feb 22, 2026

Summary

Synology Chat outgoing webhooks use a per-integration sequential user_id (e.g. 1) that differs from the global Chat API user_id (e.g. 4) required by method=chatbot. This caused reply messages to fail silently when the IDs diverged.

  • Add fetchChatUsers() and resolveChatUserId() to resolve the correct Chat API user_id via the user_list endpoint (nickname-first matching, cached 5min)
  • Use resolved user_id for all sendMessage() calls in webhook handler and channel dispatcher
  • Add Provider field to MsgContext so the agent runner correctly identifies the message channel (was "unknown", now "synology-chat")
  • Log warnings when user_list API fails or when falling back to unresolved webhook user_id

Background

The Synology Chat API has two separate user_id spaces:

Context user_id Example
Outgoing webhook (user_id field) Per-integration sequential 1
Chat API (method=chatbot, user_ids[]) Global internal 4

The outgoing webhook's username field corresponds to the Chat user's nickname. Resolution is done by calling method=user_list with the bot's token and matching by nickname (primary) then username (fallback), case-insensitive.

Test plan

  • 68/68 unit tests pass (5 new tests for user_id resolution)
  • 0 TypeScript errors, 0 lint warnings
  • Tested in production: DM and group channel delivery confirmed working
  • Verified messageChannel=synology-chat in agent runner logs (was unknown)
  • Verified fallback behavior when user_list API is unavailable

🤖 Generated with Claude Code

Greptile Summary

Added user_id resolution to fix reply delivery failures in Synology Chat integration. The PR correctly addresses the mismatch between webhook user_id (per-integration sequential) and Chat API user_id (global internal) by fetching the user list and matching by nickname/username. The implementation includes proper caching (5min TTL), fallback behavior, and comprehensive test coverage.

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The changes are well-tested (68/68 tests passing, 5 new tests), properly scoped to the Synology Chat extension, include appropriate error handling and fallback mechanisms, and follow the existing codebase patterns. The user_id resolution logic is sound with proper caching to minimize API overhead.
  • No files require special attention

Last reviewed commit: ae7aeea

(5/5) You can turn off certain types of comments like style here!

@druide67 druide67 force-pushed the fix/synology-chat-user-id-resolution branch 5 times, most recently from d1b3d00 to e8a769b Compare February 27, 2026 14:31
@druide67 druide67 force-pushed the fix/synology-chat-user-id-resolution branch from bd175a5 to 812f7ae Compare March 2, 2026 18:28
druide67 and others added 3 commits March 2, 2026 19:47
Synology Chat outgoing webhooks use a per-integration user_id that
differs from the global Chat API user_id required by method=chatbot.
This caused reply messages to fail silently when the IDs diverged.

Changes:
- Add fetchChatUsers() and resolveChatUserId() to resolve the correct
  Chat API user_id via the user_list endpoint (cached 5min)
- Use resolved user_id for all sendMessage() calls in webhook handler
  and channel dispatcher
- Add Provider field to MsgContext so the agent runner correctly
  identifies the message channel (was "unknown", now "synology-chat")
- Log warnings when user_list API fails or when falling back to
  unresolved webhook user_id
- Add 5 tests for user_id resolution (nickname, username, case,
  not-found, URL rewrite)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ws compat

Replace EventEmitter + process.nextTick with Readable stream for
request body simulation. The process.nextTick approach caused the test
to hang on Windows CI (120s timeout) because events were not reliably
delivered to readBody() listeners.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@steipete steipete force-pushed the fix/synology-chat-user-id-resolution branch from 812f7ae to 326a8fb Compare March 2, 2026 19:50
@steipete steipete merged commit 9a3800d into openclaw:main Mar 2, 2026
10 checks passed
@steipete
Copy link
Contributor

steipete commented Mar 2, 2026

Landed via temp rebase onto main.

  • Gate: pnpm vitest run extensions/synology-chat/src/client.test.ts extensions/synology-chat/src/webhook-handler.test.ts extensions/synology-chat/src/channel.integration.test.ts --maxWorkers=1
  • Land commit: 326a8fb
  • Merge commit: 9a3800d

Thanks @druide67!

execute008 pushed a commit to execute008/openclaw that referenced this pull request Mar 2, 2026
…claw#23709)

* fix(synology-chat): resolve Chat API user_id for reply delivery

Synology Chat outgoing webhooks use a per-integration user_id that
differs from the global Chat API user_id required by method=chatbot.
This caused reply messages to fail silently when the IDs diverged.

Changes:
- Add fetchChatUsers() and resolveChatUserId() to resolve the correct
  Chat API user_id via the user_list endpoint (cached 5min)
- Use resolved user_id for all sendMessage() calls in webhook handler
  and channel dispatcher
- Add Provider field to MsgContext so the agent runner correctly
  identifies the message channel (was "unknown", now "synology-chat")
- Log warnings when user_list API fails or when falling back to
  unresolved webhook user_id
- Add 5 tests for user_id resolution (nickname, username, case,
  not-found, URL rewrite)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(synology-chat): use Readable stream in integration test for Windows compat

Replace EventEmitter + process.nextTick with Readable stream for
request body simulation. The process.nextTick approach caused the test
to hang on Windows CI (120s timeout) because events were not reliably
delivered to readBody() listeners.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: harden synology reply user resolution and cache scope (openclaw#23709) (thanks @druide67)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
dawi369 pushed a commit to dawi369/davis that referenced this pull request Mar 3, 2026
…claw#23709)

* fix(synology-chat): resolve Chat API user_id for reply delivery

Synology Chat outgoing webhooks use a per-integration user_id that
differs from the global Chat API user_id required by method=chatbot.
This caused reply messages to fail silently when the IDs diverged.

Changes:
- Add fetchChatUsers() and resolveChatUserId() to resolve the correct
  Chat API user_id via the user_list endpoint (cached 5min)
- Use resolved user_id for all sendMessage() calls in webhook handler
  and channel dispatcher
- Add Provider field to MsgContext so the agent runner correctly
  identifies the message channel (was "unknown", now "synology-chat")
- Log warnings when user_list API fails or when falling back to
  unresolved webhook user_id
- Add 5 tests for user_id resolution (nickname, username, case,
  not-found, URL rewrite)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(synology-chat): use Readable stream in integration test for Windows compat

Replace EventEmitter + process.nextTick with Readable stream for
request body simulation. The process.nextTick approach caused the test
to hang on Windows CI (120s timeout) because events were not reliably
delivered to readBody() listeners.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: harden synology reply user resolution and cache scope (openclaw#23709) (thanks @druide67)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
OWALabuy pushed a commit to kcinzgg/openclaw that referenced this pull request Mar 4, 2026
…claw#23709)

* fix(synology-chat): resolve Chat API user_id for reply delivery

Synology Chat outgoing webhooks use a per-integration user_id that
differs from the global Chat API user_id required by method=chatbot.
This caused reply messages to fail silently when the IDs diverged.

Changes:
- Add fetchChatUsers() and resolveChatUserId() to resolve the correct
  Chat API user_id via the user_list endpoint (cached 5min)
- Use resolved user_id for all sendMessage() calls in webhook handler
  and channel dispatcher
- Add Provider field to MsgContext so the agent runner correctly
  identifies the message channel (was "unknown", now "synology-chat")
- Log warnings when user_list API fails or when falling back to
  unresolved webhook user_id
- Add 5 tests for user_id resolution (nickname, username, case,
  not-found, URL rewrite)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(synology-chat): use Readable stream in integration test for Windows compat

Replace EventEmitter + process.nextTick with Readable stream for
request body simulation. The process.nextTick approach caused the test
to hang on Windows CI (120s timeout) because events were not reliably
delivered to readBody() listeners.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: harden synology reply user resolution and cache scope (openclaw#23709) (thanks @druide67)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
zooqueen pushed a commit to hanzoai/bot that referenced this pull request Mar 6, 2026
…claw#23709)

* fix(synology-chat): resolve Chat API user_id for reply delivery

Synology Chat outgoing webhooks use a per-integration user_id that
differs from the global Chat API user_id required by method=chatbot.
This caused reply messages to fail silently when the IDs diverged.

Changes:
- Add fetchChatUsers() and resolveChatUserId() to resolve the correct
  Chat API user_id via the user_list endpoint (cached 5min)
- Use resolved user_id for all sendMessage() calls in webhook handler
  and channel dispatcher
- Add Provider field to MsgContext so the agent runner correctly
  identifies the message channel (was "unknown", now "synology-chat")
- Log warnings when user_list API fails or when falling back to
  unresolved webhook user_id
- Add 5 tests for user_id resolution (nickname, username, case,
  not-found, URL rewrite)


* fix(synology-chat): use Readable stream in integration test for Windows compat

Replace EventEmitter + process.nextTick with Readable stream for
request body simulation. The process.nextTick approach caused the test
to hang on Windows CI (120s timeout) because events were not reliably
delivered to readBody() listeners.


* fix: harden synology reply user resolution and cache scope (openclaw#23709) (thanks @druide67)

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants