Add email sending functionality with Google SMTP - #54
Conversation
Introduces MailService, MailController, and MailModel to enable sending emails via Google SMTP. Adds configuration classes and properties for SMTP settings, allowing email dispatch through a REST endpoint.
WalkthroughThis change introduces a complete email sending feature using Google SMTP in a Spring Boot application. It adds configuration classes for SMTP properties, a REST controller for sending emails, a service for handling email delivery via Jakarta Mail, a data model for email content, and new SMTP-related properties in the application configuration. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant MailController
participant MailService
participant GoogleSmtpConfig
participant SMTPServer
Client->>MailController: POST /mail/sendMail/{to} (MailModel)
MailController->>MailService: sendMail(to, subject, body)
MailService->>GoogleSmtpConfig: get SMTP properties
MailService->>SMTPServer: Send email via Jakarta Mail
SMTPServer-->>MailService: Response (success/failure)
MailService-->>MailController: ResponseEntity<HttpStatus>
MailController-->>Client: HTTP Response
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~15 minutes Poem
Note ⚡️ Unit Test Generation is now available in beta!Learn more here, or try it out under "Finishing Touches" below. 📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 12
🧹 Nitpick comments (3)
src/main/java/org/justjava/gymcore/config/smtp/GoogleSmtpConfig.java (1)
6-9: LGTM! Consider adding configuration validation.The configuration class structure is correct and follows Spring Boot best practices. The use of
@ConfigurationPropertieswith prefix binding is appropriate.Consider adding validation to ensure configuration completeness:
+import jakarta.validation.constraints.NotBlank; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.validation.annotation.Validated; + @Configuration +@Validated +@EnableConfigurationProperties @ConfigurationProperties(prefix = "smtp.google") public class GoogleSmtpConfig extends AbstractSmtpConfig { + + @Override + @NotBlank(message = "SMTP host must be configured") + public void setHost(String host) { + super.setHost(host); + } + + @Override + @NotBlank(message = "SMTP username must be configured") + public void setUsername(String username) { + super.setUsername(username); + } }src/main/java/org/justjava/gymcore/controller/MailController.java (1)
17-17: Consider using request body for recipient email instead of path variable.Using email address as a path variable can cause issues with URL encoding and special characters commonly found in email addresses.
Consider moving the recipient email to the request body:
+public record MailRequest( + @Email(message = "Invalid recipient email address") + @NotBlank(message = "Recipient email is required") + String to, + @NotBlank(message = "Email subject cannot be blank") + String subject, + @NotBlank(message = "Email body cannot be blank") + String body +) {} - @PostMapping("/sendMail/{to}") - public ResponseEntity<String> sendMail(@PathVariable("to") String to, @RequestBody MailModel mailModel) { + @PostMapping("/sendMail") + public ResponseEntity<String> sendMail(@Valid @RequestBody MailRequest mailRequest) { + return mailService.sendMail(mailRequest.to(), mailRequest.subject(), mailRequest.body()); }src/main/java/org/justjava/gymcore/service/MailService.java (1)
25-25: Consider removing or clarifying the comment.The comment mentions "yaml file" but the configuration appears to be using properties files based on the AI summary. This could be misleading.
Either update the comment to reflect the actual configuration method or remove it if it's not adding value:
- // Host, Host e-mail, password and port will be provided under yaml file. If you want to get configurations from yaml file use smtpConfigurationService. + // SMTP configuration is provided via GoogleSmtpConfig from application properties
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
src/main/java/org/justjava/gymcore/config/smtp/AbstractSmtpConfig.java(1 hunks)src/main/java/org/justjava/gymcore/config/smtp/GoogleSmtpConfig.java(1 hunks)src/main/java/org/justjava/gymcore/controller/MailController.java(1 hunks)src/main/java/org/justjava/gymcore/model/MailModel.java(1 hunks)src/main/java/org/justjava/gymcore/service/MailService.java(1 hunks)src/main/resources/application.properties(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Build
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
src/main/java/org/justjava/gymcore/model/MailModel.java (1)
6-15: Validation constraints properly implemented from previous review.The validation annotations have been correctly added as suggested in the previous review, with appropriate constraints for email subject and body fields following RFC 5322 standards.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/main/java/org/justjava/gymcore/model/MailModel.java(1 hunks)
🧰 Additional context used
🪛 GitHub Actions: Build
src/main/java/org/justjava/gymcore/model/MailModel.java
[error] 16-16: Compilation error: class, interface, enum, or record expected. Likely a syntax error such as an unmatched closing brace '}'.
Adjusted indentation in MailModel.java for improved readability and consistency. No functional changes were made.
|
Great work here Abdul. We are using some AI powered code reviews on Pull Requests as a way to try these new tools. Take a look over its suggestions and see if you agree with any of the suggestions. Resolve them if not. We'll review after. |
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Changed sendMail return type to ResponseEntity<HttpStatus> and replaced logger usage with log for better logging. Enhanced success and error log messages for email sending.
|
All resolved. |
ozkanpakdil
left a comment
There was a problem hiding this comment.
Needs input validation and some tidying up.
Refactored MailController and MailService to provide better error handling and email address validation. MailController now returns a success or error message, and MailService throws MessagingException instead of handling it internally. Removed unused imports and simplified constructor usage with Lombok's @requiredargsconstructor.
|
Thank you for reviews @ozkanpakdil . I commited new changes. |
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (1)
src/main/java/org/justjava/gymcore/service/MailService.java (1)
18-18: Fix dependency injection by making the field final.The
GoogleSmtpConfigfield is not final, so@RequiredArgsConstructorwon't generate a constructor parameter for it, leading to aNullPointerExceptionwhen accessed.Apply this diff to fix the dependency injection:
- private GoogleSmtpConfig googleSmtpConfig; + private final GoogleSmtpConfig googleSmtpConfig;
🧹 Nitpick comments (1)
src/main/java/org/justjava/gymcore/service/MailService.java (1)
38-45: Add input validation for robustness.Consider adding basic input validation to handle null or empty parameters gracefully before creating the message.
Apply this diff to add input validation:
+ if (to == null || to.trim().isEmpty()) { + throw new IllegalArgumentException("Recipient email address cannot be null or empty"); + } + if (subject == null) subject = ""; + if (body == null) body = ""; + Message message = new MimeMessage(session);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/main/java/org/justjava/gymcore/controller/MailController.java(1 hunks)src/main/java/org/justjava/gymcore/service/MailService.java(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- src/main/java/org/justjava/gymcore/controller/MailController.java
🔇 Additional comments (2)
src/main/java/org/justjava/gymcore/service/MailService.java (2)
21-21: Excellent improvement to method signature.The method signature now properly follows service layer patterns by returning void and throwing
MessagingExceptioninstead of mixing HTTP concerns with business logic.
37-37: Good use of thread-safe Session.getInstance().Correctly uses
Session.getInstance()instead of the deprecatedSession.getDefaultInstance(), ensuring thread safety in multi-threaded environments.
Changed googleSmtpConfig to be final in MailService to ensure immutability and proper usage with @requiredargsconstructor.
Introduces MailService, MailController, and MailModel to enable sending emails via Google SMTP. Adds configuration classes and properties for SMTP settings, allowing email dispatch through a REST endpoint.

Summary by CodeRabbit
New Features
Documentation