Grtsinry43的前端札记 | 大三技术成长实录 & 学习笔记 | 「岁月漫长,值得等待」
文章
技术学习

快速搭建专属域名邮箱服务,简单整合邮箱消息推送功能至 Spring Boot 应用程序

2025年1月2日 12 分钟阅读 浏览 0 喜欢 0 评论 0

作为即时通信的重要方式,邮件在互联网互动中起到举足轻重的作用,而搭建邮件推送服务不仅可以做到实时的消息交流,更能拉近网站与用户的距离,增加用户粘性,本文将介绍获取域名邮箱,启用 smtp,集成后端,实现推送的全过程,带你让网站“活起来”。

搭建域名邮箱服务

感谢 @miaoer @Innei 大佬提供的快捷解决方案,节省折腾 Postfix 和 Dovecot 的精力,不过后续也会更新服务器手动搭建邮件首发服务的详细步骤(等期末之后有精力写详细文档,步骤还是挺复杂的)

这里我们选择 Lark(飞书国际版,国内版的操作类似,只是多了实名步骤)提供的邮箱服务

获取邮箱

我们可以使用邮箱或者 Google 帐号注册并创建企业(个人就是 1-50 人企业选项),注册完成后,我们需要为当前登录帐号分配邮箱:

进入 企业管理页面 ,点击上方产品设置,找到邮箱,在域名管理中即可为自己的邮箱指定域。

邮箱管理

添加自定义地址

按照要求填写并前往对应的 DNS 提供商管理面板添加解析记录,我们便成功获取到了域名邮箱。

设置DNS记录

随后我们返回企业管理——组织架构——成员与部门,为自己的登录账户添加企业邮箱,由此便可以通过网页直接收发邮件

设置 smtp

依然是管理面板——产品设置——邮箱,这次我们找到左面的地址管理——公共邮箱,我们便可以创建支持 smtp 的公共推送地址

获取SMTP

整合至后端程序

条件具备,回到主线。

整合依赖

我们这里使用的是 Spring 提供的 spring-boot-starter-mail ,在 pom.xml 中添加以下依赖:

xml
<!--邮箱服务-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
            <version>3.4.1</version>
        </dependency>

随后在 application.xml 中添加好对应的配置:

xml
spring:
  mail:
    host: smtp.larksuite.com
    port: 587
    username: [email protected]
    password: your_password
    properties:
      mail.smtp.auth: true
      mail.smtp.starttls.enable: true
      mail.smtp.starttls.required: true
    default-encoding: UTF-8

创建服务

我们先以最小可行性思想来完成这个实验,先创建基础的 EmailService.java

java
package com.grtsinry43.grtblog.service;

import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;

/**
 * @author grtsinry43
 * @date 2025/1/1 23:04
 * @description 热爱可抵岁月漫长
 */
@Service
public class EmailService {
    private final JavaMailSender mailSender;

    public EmailService(JavaMailSender mailSender) {
        this.mailSender = mailSender;
    }

    public void sendEmail(String to, String subject, String content) {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom("[email protected]");
        message.setTo(to);
        message.setSubject(subject);
        message.setText(content);
        mailSender.send(message);
    }
}

额,就这么简单,是不是很 ruozhi

邮件模板

当然,我们给用户展示的不可能是简单的一点点文字而已吧,所以我们需要自定义邮件的样式,由于其支持使用 html,那我们便可以利用模板引擎 thymeleaf 来快速创建模板,添加如下依赖:

xml
<!--模板支持-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

我们在 src/main/resources/templates 中新建 emailTemplate.html,这样我们便可以使用模板语法将内容填充进我们的邮件啦,利用 org.thymeleaf.context.Context;,也就是创建上下文,由模板引擎提供,在 html 生成时消费,语法大概是 th:text="${type} 这种,你也可以参考下我的:

html
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Comment Reply Notification</title>
        <style>
            /*太多了,这里省略了*/
        </style>
    </head>
    <body>
        <div class="bg-container">
            <div class="main-container">
                <div class="header">
                    <img src="https://dogeoss.grtsinry43.com/img/author.jpeg" alt="Logo">
                    <h1>Grtsinry43's Blog | 邮件通知 </h1>
                </div>
                <div class="content">
                    <h2 style="font-size: medium"> 亲爱的朋友 <span th:text="${name}"></span>, 您在
                        <span th:text="${type}"></span><span th:text="${title}"></span>」的评论收到了新的回复哇 </h2>
                    <div class="user-info">
                        <img class="user-avatar" th:src="${avatarUrl}" alt="Logo">
                        <div style="margin-left: 10px"><span th:text="${replyName}"></span><span
                                th:text="${replyTime}"></span> 回复了您的评论
                        </div>
                    </div>
                    <div style="margin-top: 10px">
                        <span th:utext="${replyContent}"></span>
                    </div>
                    <div>
                        <span> 您的原评论内容:</span>
                        <div style="margin-top: 10px">
                            <span th:utext="${commentContent}"></span>
                        </div>
                    </div>
                    <div class="action-container">
                        <a class="more-button" th:href="${url}">
                            点击查看详情
                        </a>
                    </div>
                </div>
                <div class="footer">
                    <p>Powered by Grtblog. 此邮件由系统自动发出,请勿回复。</p>
                    <p>Copyright &copy; 2022-2025 Grtsinry43's Blog. All rights reserved.</p>
                    <p><a href="https://blog.grtsinry43.com"> 前往主站 </a></p>
                </div>
            </div>
        </div>
    </body>
</html>

这里我选择在发送邮件的方法中添加一个HashMap作为参数,传递所需的上下文,也就是这样:

java
package com.grtsinry43.grtblog.service;

import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import java.util.HashMap;

/**
 * @author grtsinry43
 * @date 2025/1/1 23:04
 * @description 热爱可抵岁月漫长
 */
@Service
public class EmailService {
    private final JavaMailSender mailSender;
    private final TemplateEngine templateEngine;

    public EmailService(JavaMailSender mailSender, TemplateEngine templateEngine) {
        this.mailSender = mailSender;
        this.templateEngine = templateEngine;
    }

    @Async
    public void sendEmail(String to, String subject, HashMap<String,String> info) throws MessagingException {
        MimeMessage message = mailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");

        Context context = new Context();
        context.setVariable("name", info.getOrDefault("name", " "));
        context.setVariable("type", info.getOrDefault("type", " "));
        // ... 这里都是设置上下文咯
        String html = templateEngine.process("emailTemplate", context);

        helper.setFrom("[email protected]");
        helper.setTo(to);
        helper.setSubject(subject);
        helper.setText(html, true);

        mailSender.send(message);

        System.out.println("邮件发送成功" + to);
    }
}

Tip!这里还有一个小问题,邮件发送是花费时间很长的时间,如果同步进行会严重阻塞业务,这里采用异步模式,你也可以配合日志记录来追溯所有的邮件发送记录

结果

最后的效果大约是这样的,你可以在任意需要的场景触发,或是自定义邮件的内容,任你喜欢!

最后效果

分享此文
评论区在赶来的路上...