- 
          
 - 
                Notifications
    
You must be signed in to change notification settings  - Fork 33
 
feat: email support using lettre #250
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
base: master
Are you sure you want to change the base?
Conversation
Initial commit of email.rs using lettre Initial commit of Add email support using lettre crate Added the message printout if debug mode is enabled Added a test and deferred the extra headers and attachment features. Added tests for config and send_email(ignore).
…/cot into feat-add-email-support
          Codecov ReportAttention: Patch coverage is  
 
 Flags with carried forward coverage won't be shown. Click here to find out more. 
 ... and 3 files with indirect coverage changes 🚀 New features to boost your workflow:
  | 
    
There was a problem hiding this 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 and interest in Cot! I have some questions and made some suggestions for improvement, I'd appreciate it if you acted on them.
Additionally, it'd be great if you could write more tests to ensure sufficient code coverage!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great improvement, but there's still some work to do!
| let transport = if self.config.username.is_some() && self.config.password.is_some() { | ||
| transport_builder.credentials(credentials).build() | ||
| } else { | ||
| transport_builder.build() | ||
| }; | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You already did that check above when creating Credentials, no need to duplicate it I think
| let transport = if self.config.username.is_some() && self.config.password.is_some() { | |
| transport_builder.credentials(credentials).build() | |
| } else { | |
| transport_builder.build() | |
| }; | |
| let transport = transport_builder.credentials(credentials).build(); | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is still current
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall, this looks fairly good and certainly goes in the right direction! There's still one major issue that needs to be fixed before merging, however.
| 
           @seqre I just noticed your comment: I think the issue is in project.rs and the bootstrapping timing between WithApps, WithDatabase, and WithEmail.  | 
    
| 
           Thank you for your patience, @trkelly23! We looked at the code and found out you have just forgotten to call the  As a side note, you might want to install a pre-commit hook, which will ensure your code always follows our formatting standards! Check out our contributing guide for more details! Additionally, please feel empowered to resolve conversations in PR with comments that you fully applied to the code. Leave open only those where you're unsure or we're actively discussing something. This reduces the amount of work we have to do, thanks!  | 
    
| 
           Thanks for the update and for taking care of the reorganization and merge — much appreciated! I took a look, but I wasn’t able to find where you inserted or put the with_email function in the codebase. It’s possible I’m missing something — could you point me to where it’s defined or committed? Just want to make sure I’m aligned before continuing. Thanks again!  | 
    
          
  | 
    
| 
           @seqre Thanks for the link.  I think I resolved many/all the review comments and completed a working example for others to learn from.  | 
    
| name = "send-email" | ||
| version = "0.1.0" | ||
| publish = false | ||
| description = "Send email - Cot example." | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| description = "Send email - Cot example." | |
| description = "Send email - Cot example." | |
| license = "MIT OR Apache-2.0" | 
| /// The SMTP server host address. | ||
| /// Defaults to "localhost". | ||
| #[builder(setter(into, strip_option), default)] | ||
| pub smtp_mode: email::SmtpTransportMode, | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add tests to ensure all variants of this enum can be constructed from TOML.
| let transport = if self.config.username.is_some() && self.config.password.is_some() { | ||
| transport_builder.credentials(credentials).build() | ||
| } else { | ||
| transport_builder.build() | ||
| }; | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is still current
This pull request relates #184 email sending functionality using the SMTP protocol. The implementation includes the following key components:
EmailError Enum: Defines various errors that can occur when sending an email, such as message errors, configuration errors, connection errors, and send errors.
SmtpConfig Struct: Represents the configuration for the SMTP email backend. It includes fields for the SMTP server host, port, username, password, fail silently option, and timeout duration. A default implementation is provided.
EmailMessage Struct: Represents an email message with fields for the subject, body, sender email, recipient emails, CC, BCC, reply-to addresses, and alternative parts (e.g., plain text and HTML versions).
EmailBackend Struct: Provides the core functionality for sending emails.
It includes methods to:
Create a new instance with the given configuration.
Open a connection to the SMTP server.
Close the connection to the SMTP server.
Dump the email message to stdout for debugging purposes.
Send a single email message.
Send multiple email messages.
Unit Tests:
Notes
The implementation uses the lettre crate for SMTP transport and message building.
The EmailBackend struct includes a debug flag to enable dumping email messages to stdout for debugging purposes.
The unit tests demonstrate the setup but do not actually send emails, as they mock the transport. In a real test environment, you might use a real SMTP server or a more sophisticated mock.
Future Work
Integration tests with a real SMTP server or a mock server.
Additional configuration options for TLS/SSL support.
Improved error handling and logging.
Integration with API email providers.