Skip to content

feat: add string attachments, SMTP keep-alive, and command timelimit#112

Merged
ChiragAgg5k merged 2 commits intomainfrom
feat-smtp-enhancements
Apr 1, 2026
Merged

feat: add string attachments, SMTP keep-alive, and command timelimit#112
ChiragAgg5k merged 2 commits intomainfrom
feat-smtp-enhancements

Conversation

@ChiragAgg5k
Copy link
Copy Markdown
Member

Summary

  • String-based attachments: Attachment class now accepts optional ?string $content for raw content, bypassing file path reads in the SMTP adapter
  • SMTP KeepAlive: New keepAlive constructor param reuses the PHPMailer instance across process() calls, clearing recipients/attachments between sends
  • SMTP command timelimit: New timelimit constructor param configures per-command timeout via $mail->getSMTPInstance()->Timelimit

All new parameters default to current behavior — no breaking changes.

Test plan

  • Unit tests for Attachment string content getter and null default pass locally
  • Unit tests for SMTP constructor with new params pass locally
  • Integration tests for string attachment sending (requires maildev)
  • Integration tests for keep-alive multi-send (requires maildev)
  • Verify existing tests remain green in CI

Add support for three new SMTP adapter features needed by the mail worker:

- String-based attachments: Attachment class accepts optional raw string
  content, used directly via addStringAttachment() instead of file path
- SMTPKeepAlive: reuse PHPMailer instance across process() calls,
  clearing recipients/attachments between sends
- SMTP command timelimit: configurable per-command timeout via Timelimit

All new constructor parameters have backwards-compatible defaults.
@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Apr 1, 2026

Greptile Summary

This PR extends SMTP and Attachment with three new opt-in features — string-based attachment content, SMTP keep-alive connection reuse, and a configurable per-command timelimit — while preserving full backward compatibility through defaulted parameters.

  • String attachments: Attachment gains an optional ?string $content (default null); when set, SMTP::process() skips the file_get_contents call and passes the raw bytes directly to PHPMailer's addStringAttachment. The size-check branch uses strlen for content attachments vs filesize for path attachments, which is consistent.
  • SMTP keep-alive: A private ?PHPMailer $mail instance is stored on the first process() call when keepAlive=true, then reused on subsequent calls after clearing recipients, reply-tos, and attachments. The reset is minimal and correct — per-message fields (Subject, Body, XMailer, CharSet, From) are simply overwritten each iteration, so no stale state leaks between sends.
  • Timelimit: getSMTPInstance()->Timelimit is set unconditionally on every process() call. On a fresh (non-keepAlive) instance this lazily instantiates the SMTP object before send() opens the connection, which is harmless since PHPMailer caches and reuses that same instance. On a reused keepAlive connection it updates the property for the already-open socket, which is equally fine.
  • Both previously-flagged issues (redundant clearAddresses/clearBCCs/clearCCs calls around clearAllRecipients, and missing ENCODING_BASE64 on the file-path branch) have been resolved in this revision.

Confidence Score: 5/5

Safe to merge — all changes are additive, defaults preserve existing behavior, and prior review concerns are resolved.

No P0 or P1 issues found. All three new features default to current behavior, the keepAlive state reset is correct, and the encoding parity between the two attachment branches (raised in an earlier review) has been applied. The unit tests cover the new code paths, and integration tests are present for when the maildev environment is available.

No files require special attention.

Important Files Changed

Filename Overview
src/Utopia/Messaging/Adapter/Email/SMTP.php Adds keepAlive connection reuse (with correct recipient/attachment reset) and per-command timelimit; previous review concerns about redundant clearing and encoding asymmetry are both resolved.
src/Utopia/Messaging/Messages/Email/Attachment.php Adds optional ?string $content parameter with null default and a getContent() accessor; backward-compatible and cleanly documented.
tests/Messaging/Adapter/Email/SMTPTest.php Adds unit tests for the new Attachment content getter/default and SMTP constructor params; integration tests for string attachments and keepAlive multi-send are included but gated on maildev.

Reviews (2): Last reviewed commit: "fix: address PR review comments" | Re-trigger Greptile

- Remove redundant clearAddresses/clearBCCs/clearCCs calls since
  clearAllRecipients() already covers them
- Add explicit ENCODING_BASE64 to file-path attachment branch for
  consistency with the string-content branch
@ChiragAgg5k ChiragAgg5k merged commit b2358fd into main Apr 1, 2026
3 of 4 checks passed
@ChiragAgg5k ChiragAgg5k deleted the feat-smtp-enhancements branch April 1, 2026 10:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants