#6591: fix(signal): process all inbound attachments in parallel
channel: signal
Cluster:
Attachment Processing Enhancements
## Summary
- **Fixes Signal only processing first attachment** - Previously `attachments[0]` was taken, silently dropping additional attachments
- **Parallel fetching** - Uses `Promise.all()` for ~4x speedup when processing multiple images
- **UX improvement** - Sends "Processing N images..." message for multi-attachment messages
- **Backwards compatible** - Populates both `MediaPath` (singular) and `MediaPaths` (array)
## Test plan
- [x] Tested with 4-image Signal message - all 4 images detected and processed
- [x] Verified parallel fetch reduces processing time
- [x] Confirmed "Processing images" message appears for multi-attachment messages
- [x] Single attachment messages still work as before
## Related
Follows the same pattern as the Line channel which already supports multiple attachments.
---
🦞 Generated with [Claude Code](https://claude.ai/code)
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR updates the Signal inbound event handler to support multiple attachments per message by fetching all attachments (with an `id`) in parallel via `Promise.all`, and by emitting array fields (`MediaPaths`, `MediaTypes`, `MediaUrls`) alongside the existing singular media fields for backward compatibility. It also adds a user-facing "Processing N images..." status message when multiple attachments are present, and updates debouncing/placeholder generation to account for multi-attachment messages.
Overall the change matches existing multi-media patterns in the codebase (e.g., Line/iMessage) and improves correctness by no longer silently dropping attachments beyond index 0.
<h3>Confidence Score: 4/5</h3>
- This PR is likely safe to merge, with minor edge-case handling to consider around group targets and attachment counts.
- The changes are localized to Signal inbound processing and follow established multi-media patterns (MediaPaths/Types/Urls). Main risk is around small edge cases: constructing `group:${groupId}` without guarding against undefined and UI placeholder counts using total attachments vs valid/fetched attachments.
- src/signal/monitor/event-handler.ts
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#22113: feat: support non-image file attachments in webchat chat.send
by Kt-L · 2026-02-20
76.6%
#15095: fix(slack): process all file attachments instead of only the first
by Lar000ki · 2026-02-13
75.0%
#22540: fix(signal): preserve original filename in outbound attachments
by lailoo · 2026-02-21
75.0%
#8271: feat(signal): Add full quoted message context support
by ProofOfReach · 2026-02-03
74.2%
#15956: feat(signal): enhanced inbound message handling
by heyhudson · 2026-02-14
74.0%
#22942: fix(slack): parse generic attachment text for inbound events
by danielalkurdi · 2026-02-21
73.7%
#16573: fix(signal): increase attachment fetch timeout to 30s (#16545)
by robbyczgw-cla · 2026-02-14
72.7%
#21309: feat(telegram): support outbound media groups (albums) via sendMedi...
by smysle · 2026-02-19
72.6%
#22781: fix(webchat): persist chat attachments after guards and expose medi...
by Kansodata · 2026-02-21
72.5%
#13961: fix(telegram): support media attachments in replied Telegram messages
by shan-mx · 2026-02-11
71.4%