Adaptive Card

Mailer

npm install @nestjs-modules/mailer

email.module.ts

import { MailerModule } from '@nestjs-modules/mailer';
import { EjsAdapter } from '@nestjs-modules/mailer/dist/adapters/ejs.adapter';

@Module({
  imports: [
    MailerModule.forRoot({
      transport: {
        host: 'mx.xxx.xxx.com', // 需要在服务器上申请防火墙
        port: 25,
        ignoreTLS: true, // 踩坑:TLSSocket.SMTPConnection._onSocketTimeout
        secure: false,
      },
      preview: true,
      defaults: {
        from: '"Test" <test@xxx.com>',
      },
      template: {
        dir: process.cwd() + '/email-template',
        adapter: new EjsAdapter(),
        options: {
          strict: true,
        },
      },
    }),
  ],
})
export class EmailModule {}

email.service.ts

import { MailerService } from '@nestjs-modules/mailer';
import * as ACData from 'adaptivecards-templating';
import * as approvalCard from './template/template.json';
import * as responseCard from './template/response.json';
import * as data from './template/data.json';

@Injectable()
export class EmailService {
  renderTemplate(courseData) {
    const tempCard =
      courseData.status === Status.Created ? approvalCard : responseCard;
    const template = new ACData.Template(tempCard);
    const cardData = {
      ...data,
    };

    const card = template.expand({
      $root: cardData,
    });
    return {
      card,
      cardData
    };
  }

  async sendEmailCode(courseData: mdmEventDto) {
    const { card, cardData } = this.renderTemplate(courseData);
    try {
      const sendMailOptions: SendMailOptions = {
        to: courseData.user_email,
        from: process.env.ADDRESSER_MAIL,
        cc: process.env.SEND_MAIL,
        subject: 'APPLY COURSE',
        template: 'template.code.ejs',
        context: {
          card,
          cardData,
        },
      };
      await this.mailerService.sendMail(sendMailOptions);
      return { code: 200, message: '发送成功' };
    } catch (error) {
      console.error('发送邮件出错:', error);
      return { error };
    }
  }
}

Template

email-template/template.code.ejs

<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script type="application/adaptivecard+json">
      <%- JSON.stringify(locals.card) %>
    </script>
  </head>
  <body>
    <p>课程名称:<%- locals.cardData.course_name %></p>
  </body>
</html>

email/template/template.json

{
  "hideOriginalBody": true,
  "type": "AdaptiveCard",
  "originator": "xxx", // generate in https://outlook.office.com/connectors/oam/publish
  "body": [
    {
      "type": "TextBlock",
      "verticalContentAlignment": "Center",
      "horizontalAlignment": "Left",
      "size": "Large",
      "text": "开班申请",
      "isSubtle": true
    },
    {
      "separator": true,
      "spacing": "Medium",
      "type": "Container",
      "items": [
        {
          "type": "TextBlock",
          "size": "Medium",
          "weight": "Bolder",
          "text": "班级基本信息"
        },
        {
          "type": "FactSet",
          "spacing": "Large",
          "facts": [
            {
              "title": "课程名称",
              "value": "**${course_name}**"
            },
            {
              "title": "科室信息",
              "value": "${department_name}"
            },
          ]
        }
      ]
    },
  ],
  "actions": [
    {
      "type": "Action.OpenUrl",
      "title": "完善信息",
      "url": "${form_url}"
    }
  ],
  "autoInvokeAction": {
    "method": "POST",
    "url": "https://xxx.jjmc.cn/iqvia/mdm/updateCard",
    "body": "{ \"id\": ${event_id} }",
    "type": "Action.Http",
    "headers": [
      { "name": "Content-Type", "value": "application/json" }
    ]
  },
  "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
  "version": "1.0"
}

email/template/data.json

{
  "event_id": "",
  "course_name": "暂无课程名称",
}

adaptivecard

踩坑:Outlook windows 客户端样式错乱,网页版样式正常,MAC 样式正常

Outlook windows 客户端 页面渲染模式为文本渲染,类似于Word:

  1. 不能使用布局属性,包括flex、float、absolute、relative等布局,浮动属性 ul,li,dl,dd标签不能用
  2. HTML结构搭建使用table表格编写
  3. css不能用外部样式,不能用内联样式表,样式必须写在行内,否则不生效

https://blog.51cto.com/u_15155081/2720389

解决:https://documentation.mjml.io/#inside-node-js mjml 写模板,用mjml2html转成html

GrapeJS:export MJML 邮件中的HTML

Category: Cloud

Author: Yoga

Article
Tagcloud
DVA Java Express Architecture Azure CI/CD database ML AWS ETL nest sql AntV Next Deep Learning Flutter TypeScript Angular DevTools Microsoft egg Tableau SAP Token Regexp Unit test Nginx nodeJS sails wechat Jmeter HTML2Canvas Swift Jenkins JS event GTM Algorithm Echarts React-Admin Rest React hook Flux Redux ES6 Route Component Ref AJAX Form JSX Virtual Dom Javascript CSS design pattern