Skip to content

Feature to add "reply_to" option when sending mails. #58

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Apr 18, 2025

Conversation

aolamide
Copy link
Contributor

@aolamide aolamide commented Apr 9, 2025

Motivation

Mailtrap has the option of a reply_to field, but this currently does not exist in the SDK. This PR introduces the functionality to allow users to pass a reply_to email address, which will be used as the default reply email in email clients.

Changes

  • Added reply_to in the CommonMail type.
  • Updated nodemailer adaptor to handle this change
  • Updated the "everything" example to show how to use the reply_to feature.

Summary by CodeRabbit

  • New Features
    • Enhanced outgoing emails with a reply-to option, allowing responses to be directed to a designated address.
  • Tests
    • Updated test scenarios to verify proper handling of the reply-to functionality across various recipient inputs.

Copy link

coderabbitai bot commented Apr 9, 2025

Walkthrough

This update enhances email functionality by introducing reply-to support. A new constant is added in the sending example, and the mail adapter function is modified to process a reply-to field using a newly added recipient adaptation function. Test cases have been updated accordingly, and the CommonMail type now contains an optional reply-to property.

Changes

File(s) Change Summary
examples/sending/everything.ts Added constant REPLY_TO_EMAIL with a placeholder email and incorporated it into the email object under the reply_to field in the client.send method.
src/tests/adapters/mail.test.ts Updated test cases for adaptMail to include a new replyTo field. Expected results are revised to incorporate a reply_to field populated via the new adaptReplyToRecipient function.
src/adapters/mail.ts Modified adaptMail to import and call adaptReplyToRecipient, adding the reply_to property to the mail object derived from the replyTo input.
src/adapters/recipients.ts Added new function adaptReplyToRecipient to process the reply-to recipients. It checks the input type and adapts a single recipient accordingly, as Mailtrap supports only one reply-to recipient.
src/types/mailtrap.ts Extended the CommonMail type by adding an optional property reply_to of type Address, enabling specification of a reply-to address in email communications.
src/tests/adapters/recipients.test.ts Introduced tests for adaptReplyToRecipient to cover various scenarios including undefined input, empty arrays, and single or multiple recipients.
examples/sending/transport.ts Added constant REPLY_TO_EMAIL and updated the sendMail method to include a replyTo property referencing this constant.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant EmailAdapter as adaptMail
    participant RecipientAdapter as adaptReplyToRecipient
    participant MailService

    Client->>EmailAdapter: Send email data with replyTo field
    EmailAdapter->>RecipientAdapter: Process replyTo value
    RecipientAdapter-->>EmailAdapter: Return adapted reply-to address
    EmailAdapter->>MailService: Send email with added reply_to property
Loading

Poem

I’m a little rabbit, soft and fleet,
Hopping through code with joyful feet.
Reply-to added with a clever twist,
Emails now dance in a brand new mist.
With ASCII hops and a smile so sweet!
🐇💻✨


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 89a26f0 and 089b7f5.

📒 Files selected for processing (1)
  • examples/sending/transport.ts (2 hunks)
🔇 Additional comments (2)
examples/sending/transport.ts (2)

14-14: Good addition of the new constant.

The REPLY_TO_EMAIL constant follows the same naming convention as the other email address constants in this file, maintaining consistency in the codebase.


30-30: Excellent implementation of the reply-to functionality.

The replyTo property has been correctly added to the sendMail method options, following Nodemailer's camelCase naming convention. This implementation aligns perfectly with the PR's objective to add reply-to support to the Mailtrap SDK.

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (4)
src/adapters/mail.ts (1)

4-4: Fix import formatting

The import line should be reformatted for better readability according to the project's style guidelines.

-import adaptRecipients, { adaptSingleRecipient, adaptReplyToRecipient } from "./recipients";
+import adaptRecipients, {
+  adaptSingleRecipient,
+  adaptReplyToRecipient,
+} from "./recipients";
🧰 Tools
🪛 ESLint

[error] 4-4: Replace ·adaptSingleRecipient,·adaptReplyToRecipient· with ⏎··adaptSingleRecipient,⏎··adaptReplyToRecipient,⏎

(prettier/prettier)

src/adapters/recipients.ts (1)

42-64: Well-implemented reply_to adapter function with minor formatting issues

The new adaptReplyToRecipient function correctly handles various input scenarios and is well-documented. It properly handles the case where Mailtrap doesn't support multiple reply-to recipients by taking just the first one.

There are a few formatting issues to fix:

/**
 * If there is no recipient or empty array is passed, then return undefined since it is an optional field.
 * If it's not array, then adapt recipient and returns it.
-* Otherwise, if type is array as nodemailer allows, we pick the first recipient 
+* Otherwise, if type is array as nodemailer allows, we pick the first recipient
 * as Mailtrap doesn't support multiple reply-to recipients.
 */
export function adaptReplyToRecipient(
  recipients:
    | string
    | NodemailerAddress
    | Array<string | NodemailerAddress>
    | undefined
): Address | undefined {
-  if(!recipients || (Array.isArray(recipients) && recipients.length === 0)) {
+  if (!recipients || (Array.isArray(recipients) && recipients.length === 0)) {
    return undefined;
  }

  if (!Array.isArray(recipients)) {
    return adaptSingleRecipient(recipients);
  }

  return adaptSingleRecipient(recipients[0]);
}
+
🧰 Tools
🪛 ESLint

[error] 45-45: Delete ·

(prettier/prettier)


[error] 55-55: Insert ·

(prettier/prettier)


[error] 64-64: Insert

(prettier/prettier)

src/__tests__/adapters/mail.test.ts (2)

4-4: Fix import formatting to match code style guidelines.

The import line should follow the project's formatting style as indicated by ESLint.

-import { adaptSingleRecipient, adaptReplyToRecipient } from "../../adapters/recipients";
+import {
+  adaptSingleRecipient,
+  adaptReplyToRecipient,
+} from "../../adapters/recipients";
🧰 Tools
🪛 ESLint

[error] 4-4: Replace ·adaptSingleRecipient,·adaptReplyToRecipient· with ⏎··adaptSingleRecipient,⏎··adaptReplyToRecipient,⏎

(prettier/prettier)


100-297: Consider adding replyTo to additional test cases.

The replyTo field is currently tested in 3 scenarios, but not in the template, category, text, or HTML test cases. For complete test coverage, consider adding the replyTo field to these test cases as well.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 52afee1 and 7e6376f.

📒 Files selected for processing (5)
  • examples/sending/everything.ts (2 hunks)
  • src/__tests__/adapters/mail.test.ts (7 hunks)
  • src/adapters/mail.ts (2 hunks)
  • src/adapters/recipients.ts (1 hunks)
  • src/types/mailtrap.ts (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (3)
src/adapters/mail.ts (1)
src/adapters/recipients.ts (1)
  • adaptReplyToRecipient (48-64)
src/__tests__/adapters/mail.test.ts (1)
src/adapters/recipients.ts (1)
  • adaptReplyToRecipient (48-64)
src/adapters/recipients.ts (1)
src/types/mailtrap.ts (1)
  • Address (5-8)
🪛 ESLint
src/adapters/mail.ts

[error] 4-4: Replace ·adaptSingleRecipient,·adaptReplyToRecipient· with ⏎··adaptSingleRecipient,⏎··adaptReplyToRecipient,⏎

(prettier/prettier)

src/__tests__/adapters/mail.test.ts

[error] 4-4: Replace ·adaptSingleRecipient,·adaptReplyToRecipient· with ⏎··adaptSingleRecipient,⏎··adaptReplyToRecipient,⏎

(prettier/prettier)

src/adapters/recipients.ts

[error] 45-45: Delete ·

(prettier/prettier)


[error] 55-55: Insert ·

(prettier/prettier)


[error] 64-64: Insert

(prettier/prettier)

🔇 Additional comments (7)
src/types/mailtrap.ts (1)

26-26: Clean addition of reply_to field

The reply_to field has been properly added as an optional property to the CommonMail type, maintaining consistency with other address fields like from, to, cc, and bcc.

examples/sending/everything.ts (2)

15-15: Good example of reply_to configuration

The addition of the REPLY_TO_EMAIL constant provides a clear example of how to set up a reply-to address.


32-32: Proper implementation of reply_to field

The reply_to field is correctly implemented in the email configuration object, demonstrating how to use this new feature.

src/adapters/mail.ts (1)

30-30: Good implementation of reply_to adapter

The implementation correctly uses the new adaptReplyToRecipient function to handle the replyTo field from the input data, maintaining consistency with how other recipient fields are processed.

src/__tests__/adapters/mail.test.ts (3)

27-27: Implementation of reply-to support looks good.

The test cases correctly add the replyTo field in the test data and verify that adaptReplyToRecipient is called to adapt the value in the expected result.

Also applies to: 37-37


52-52: Testing empty array for replyTo looks good.

Good job testing the edge case of an empty array for the replyTo field. This ensures that the adaptReplyToRecipient function handles this case correctly.

Also applies to: 63-63


81-81: Testing replyTo with array of strings looks good.

Testing with an array containing a string value is a good approach to verify that the adaptReplyToRecipient function correctly processes array inputs.

Also applies to: 93-93

@aolamide
Copy link
Contributor Author

aolamide commented Apr 9, 2025

Good day, @mklocek @vittorius @JSFernandes
Mind taking a look?

Copy link
Contributor

@vittorius vittorius left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your contribution @aolamide! Could you please also update the Nodemailer usage example and we'll be good to go.

@aolamide
Copy link
Contributor Author

Thank you for your contribution @aolamide! Could you please also update the Nodemailer usage example and we'll be good to go.

Thank you, @vittorius
I have updated the nodemailer transport example.

@aolamide
Copy link
Contributor Author

Hi, @VladimirTaytor. Could you take a look?

Copy link
Contributor

@VladimirTaytor VladimirTaytor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thanks for contribution 💪

@vittorius vittorius merged commit 8114775 into railsware:main Apr 18, 2025
3 checks passed
@vittorius vittorius mentioned this pull request Apr 18, 2025
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.

4 participants