chatwoot/spec/services
Sojan Jose 8e42307bdc
fix: improve email inbox IMAP and SMTP compatibility (#14589)
Fetch IMAP message content using `BODY.PEEK[]` instead of `RFC822` to
avoid provider-specific parser failures while preserving unread state.
This also applies the existing SMTP timeout configuration to custom SMTP
email-channel replies, so provider SMTP responses have enough time to
complete.

Fixes: https://github.com/chatwoot/chatwoot/issues/12762

## Why

Some IMAP providers can return responses for `FETCH RFC822` that Ruby
`net-imap` fails to parse with:

`Net::IMAP::ResponseParseError: unexpected RPAR (expected ATOM or NIL)`

We reproduced this with iCloud IMAP. Authentication, `INBOX` selection,
and header fetches worked, but fetching full message content with
`RFC822` failed before Chatwoot received a `Mail::Message`.

The same mailbox successfully returned full message content when fetched
with `BODY.PEEK[]`.

> During end-to-end iCloud validation, inbound fetch worked after the
IMAP change, but outbound replies through the custom SMTP settings could
still fail with a socket read timeout. The OAuth SMTP path already used
explicit SMTP timeout values; the custom SMTP path was relying on mailer
defaults instead.

## What this change does

- Replaces the full message fetch from `RFC822` to `BODY.PEEK[]`
- Reads the returned message content from `BODY[]`, which is how
`net-imap` exposes the response attribute
- Keeps the existing `BODY.PEEK[HEADER]` header-fetch behavior unchanged
- Applies `SMTP_OPEN_TIMEOUT` and `SMTP_READ_TIMEOUT` to custom SMTP
email-channel replies
- Defaults custom SMTP reply delivery to `open_timeout: 15` and
`read_timeout: 30`
- Updates IMAP service specs for standard and Microsoft IMAP fetch flows
- Updates mailer specs for custom SMTP timeout settings

`BODY.PEEK[]` is preferable here because it fetches the full message
content without marking messages as read.

## Validation

- Configured a local email inbox against iCloud IMAP and SMTP
- Confirmed `FETCH RFC822` reproduces `Net::IMAP::ResponseParseError:
unexpected RPAR (expected ATOM or NIL)`
- Confirmed `BODY[]` and `BODY.PEEK[]` fetch the same mailbox
successfully
- Confirmed Chatwoot imports iCloud messages after the IMAP change
- Sent two outbound replies from the Chatwoot UI through iCloud SMTP
after applying the timeout settings
- Confirmed both UI-created outbound messages were marked `sent`, had
iCloud SMTP `source_id` values, and had no `external_error`
- Ran `bundle exec rspec spec/services/imap/fetch_email_service_spec.rb
spec/services/imap/microsoft_fetch_email_service_spec.rb`
- Ran `bundle exec rspec spec/mailers/conversation_reply_mailer_spec.rb`
2026-06-03 15:56:54 +05:30
..
account feat: Add automatic favicon fetching for companies (#13013) 2026-03-05 18:51:28 -08:00
auto_assignment fix: skip AutoAssignment bulk loop when no agents are online (#14500) 2026-05-25 15:17:05 +05:30
automation_rules feat: Introduce last responding agent option to automation assign agent (#12326) 2026-04-16 18:54:35 +05:30
contacts feat: support bulk label removal (#14534) 2026-05-26 15:23:51 +05:30
conversations revert: restore conversation unread count feature flag (#14623) 2026-06-02 21:11:48 +05:30
crm/leadsquared chore: verbosely log errors for leadsquare activity failure (#14407) 2026-05-11 10:58:23 +05:30
email chore: Migrate mailers from the worker to jobs (#12331) 2025-10-21 16:36:37 -07:00
facebook feat(facebook): use HUMAN_AGENT tag for Messenger replies when human-agent config is enabled (#13690) 2026-03-02 15:32:59 +04:00
google feat: add Google Email fetch and OAuth token refresh service (#9603) 2024-06-11 14:22:03 +05:30
imap fix: improve email inbox IMAP and SMTP compatibility (#14589) 2026-06-03 15:56:54 +05:30
instagram feat: Handle instagram test service (#11244) 2025-04-11 19:11:29 +05:30
internal feat: add job to remove stale contacts and contact_inboxes (#11186) 2025-03-28 12:18:39 +05:30
labels feat(labels): remove label associations asynchronously on delete (#13531) 2026-05-08 13:40:36 +05:30
line fix(line): Use non-expiring URLs for image and video messages (#13949) 2026-04-01 17:29:12 +05:30
linear feat: Whatsapp embedded signup (#11612) 2025-07-14 21:37:06 -07:00
liquid feat: Add liquid processing for SMS campaigns (#10981) 2025-06-11 13:16:44 -04:00
llm_formatter feat: Differentiate bot and user in the summary (#12801) 2025-11-05 11:42:21 -08:00
macros fix: add explicit remove assignment actions to macros and automations (#12172) 2026-04-16 15:57:41 +05:30
mailbox refactor: strategy pattern for mailbox conversation finding (#12766) 2025-11-10 20:47:18 +05:30
message_templates fix: optimize message query with account_id filter (#13759) 2026-03-10 16:46:20 -07:00
messages fix(webhooks): strip trailing newlines from webhook message content (#14272) 2026-06-02 23:28:13 +05:30
mfa feat: MFA (#12290) 2025-09-18 20:19:24 +05:30
microsoft chore: Refactor RefreshOauthTokenService to improve readability (#8820) 2024-01-31 12:24:12 +04:00
notification chore: Disable email notifications for unconfirmed users (#10964) 2025-02-24 12:14:40 -08:00
reporting_events feat(rollup): add models and write path [1/3] (#13796) 2026-03-19 13:12:36 +05:30
reports fix: prevent bot metrics double-counting when handoff and resolution coexist [CW-6210] (#14032) 2026-05-13 18:43:23 +05:30
sms feat: show processing status for one-off campaigns (#14592) 2026-06-01 16:47:17 +05:30
telegram feat(voice): add WhatsApp inbound call webhook pipeline [3] (#14315) 2026-05-12 11:23:57 +05:30
tiktok fix(tiktok): Resolve media upload failures and gate attachments by conversation capability (#13643) 2026-05-06 11:21:15 +04:00
twilio feat: show processing status for one-off campaigns (#14592) 2026-06-01 16:47:17 +05:30
twitter chore: Enable the new Rubocop rules (#7122) 2023-05-19 14:37:10 +05:30
whatsapp fix(whatsapp): truncate location fallback_title to 255 chars to avoid silent message drop (#14517) 2026-06-03 12:50:21 +05:30
widget feat: speed up circleci and github actions (#12849) 2025-11-19 15:32:48 +05:30
account_deletion_service_spec.rb fix(account-deletion): normalize deleted email suffix and handle collisions safely (#13472) 2026-02-07 17:29:27 -08:00
action_service_spec.rb feat: Introduce last responding agent option to automation assign agent (#12326) 2026-04-16 18:54:35 +05:30
base_token_service_spec.rb feat: MFA (#12290) 2025-09-18 20:19:24 +05:30
csat_survey_service_spec.rb fix: Respect survey label rules for WhatsApp CSAT template (#13285) 2026-01-15 22:16:00 -08:00
csat_template_utility_analysis_service_spec.rb feat(csat): Add WhatsApp utility template analyzer with rewrite guidance (#13575) 2026-02-24 15:11:04 +04:00
search_service_spec.rb feat: Advanced Search Backend (#12917) 2026-01-07 15:30:49 +05:30
website_branding_service_spec.rb feat: account enrichment using context.dev [UPM-27] (#13978) 2026-04-08 11:16:52 +05:30