chatwoot/app/mailers
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
..
administrator_notifications fix: validate OpenAI hook credentials (#14068) 2026-05-18 14:08:57 +05:30
agent_notifications feat: sanitize inbox name (#11597) 2025-06-09 14:46:12 +05:30
team_notifications feat: Add send message, fix issues with message conditions (#4423) 2022-04-14 13:36:55 +05:30
application_mailer.rb chore: log emails sent from chatwoot (#8721) 2024-01-17 13:19:14 +04:00
conversation_reply_mailer_attachment_helper.rb fix: stream attachment handling in workers (#12870) 2025-12-05 13:02:53 -08:00
conversation_reply_mailer_helper.rb fix: improve email inbox IMAP and SMTP compatibility (#14589) 2026-06-03 15:56:54 +05:30
conversation_reply_mailer.rb fix: sanitize parentheses from email From header to prevent SMTP 553 errors (#14075) 2026-04-21 11:30:20 +05:30
portal_instructions_mailer.rb fix: footer in ssl_instructions email (#12076) 2025-07-31 11:44:17 -07:00
references_header_builder.rb feat: add references header to reply emails (#11719) 2025-07-29 15:54:14 +05:30