Skip to content

Commit

Permalink
#5 enable send w3 events with email
Browse files Browse the repository at this point in the history
  • Loading branch information
Hai Liang Wang committed Oct 8, 2022
1 parent 7171645 commit d0d1195
Show file tree
Hide file tree
Showing 9 changed files with 218 additions and 81 deletions.
13 changes: 12 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,16 @@ services:
- NODE_ENV=${NODE_ENV:-development}
- FEISHU_GROUP_GITHUB_BOTS=${FEISHU_GROUP_GITHUB_BOTS:-placeholder}
- FEISHU_GROUP_W3_BOTS=${FEISHU_GROUP_W3_BOTS:-placeholder}
- MAIL_W3_EVENTS_CC=${MAIL_W3_EVENTS_CC:-placeholder}
- MAIL_W3_EVENTS_BCC=${MAIL_W3_EVENTS_BCC:-placeholder}
- SMTP_HOST=smtp.feishu.cn
- SMTP_PORT=465
- SMTP_SSL=true
- SMTP_USER_FROM=${SMTP_USER_FROM:-placeholder}
- SMTP_USER_NAME="CSKeFu W3"
- SMTP_USER_PASS=${SMTP_USER_PASS:-placeholder}
ports:
- "${SYNC_PORT:-8201}:8201"
- "${SYNC_PORT:-8201}:8201"



13 changes: 12 additions & 1 deletion sample.env
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,15 @@ COMPOSE_PROJECT_NAME=cskefu.sync

NODE_ENV=development
FEISHU_GROUP_GITHUB_BOTS=
FEISHU_GROUP_W3_BOTS=
FEISHU_GROUP_W3_BOTS=

MAIL_W3_EVENTS_CC=
MAIL_W3_EVENTS_BCC=

# SMTP Client
SMTP_HOST=smtp.feishu.cn
SMTP_PORT=465
SMTP_SSL=true
SMTP_USER_FROM=
SMTP_USER_NAME="CSKeFu W3"
SMTP_USER_PASS=
120 changes: 66 additions & 54 deletions sync/app/controllers/w3.ctrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
const debug = require("debug")("sync:ctrl:w3");
const utils = require("../utils/index");
const feishuService = require("../services/feishu.service");


const mailService = require("../services/email.service");

function Controller() {

Expand All @@ -19,66 +18,79 @@ function Controller() {
* @param {*} body
*/
Controller.prototype.handleW3broadcast = async function (headers, params, body) {
let ret = { "msg": "done" };
/**
* sync:routes:w3 /broadcast ctx.params {} , body
let ret = { "msg": "done" };
/**
* sync:routes:w3 /broadcast ctx.params {} , body
{
"link": "https://www.cskefu.com/2022/10/08/test-c/",
"post_title": "Test C",
"author_id": "99",
"display_name": "Hai",
"user_email": "h@cskefu.com",
"user_profile": "https://www.cskefu.com/user/99/",
"categories": [
{
"term_id": 118,
"name": "业务观点",
"slug": "business",
"term_group": 0,
"term_taxonomy_id": 118,
"taxonomy": "category",
"description": "业务、产品及服务的应用和解决方案:呼叫中心、联络中心、智能客服、客服机器人、CTI、云计算等。有价值的干货:应用场景、业务价
"link": "https://www.cskefu.com/2022/10/08/test-c/",
"post_title": "Test C",
"author_id": "99",
"display_name": "Hai",
"user_email": "h@cskefu.com",
"user_profile": "https://www.cskefu.com/user/99/",
"categories": [
{
"term_id": 118,
"name": "业务观点",
"slug": "business",
"term_group": 0,
"term_taxonomy_id": 118,
"taxonomy": "category",
"description": "业务、产品及服务的应用和解决方案:呼叫中心、联络中心、智能客服、客服机器人、CTI、云计算等。有价值的干货:应用场景、业务价
值、创新方案。",
"parent": 0,
"count": 12,
"filter": "raw",
"cat_ID": 118,
"category_count": 12,
"category_description": "业务、产品及服务的应用和解决方案:呼叫中心、联络中心、智能客服、客服机器人、CTI、云计算等。有价值的干货:应用场
"parent": 0,
"count": 12,
"filter": "raw",
"cat_ID": 118,
"category_count": 12,
"category_description": "业务、产品及服务的应用和解决方案:呼叫中心、联络中心、智能客服、客服机器人、CTI、云计算等。有价值的干货:应用场
景、业务价值、创新方案。",
"cat_name": "业务观点",
"category_nicename": "business",
"category_parent": 0
},
{
"term_id": 145,
"name": "产品专栏",
"slug": "product",
"term_group": 0,
"term_taxonomy_id": 145,
"taxonomy": "category",
"description": "产品理念、产品设计、产品构想等;主要由春松客服产品经理或产品办公室发布。",
"parent": 0,
"count": 2,
"filter": "raw",
"cat_ID": 145,
"category_count": 2,
"category_description": "产品理念、产品设计、产品构想等;主要由春松客服产品经理或产品办公室发布。",
"cat_name": "产品专栏",
"category_nicename": "product",
"category_parent": 0
}
]
"cat_name": "业务观点",
"category_nicename": "business",
"category_parent": 0
},
{
"term_id": 145,
"name": "产品专栏",
"slug": "product",
"term_group": 0,
"term_taxonomy_id": 145,
"taxonomy": "category",
"description": "产品理念、产品设计、产品构想等;主要由春松客服产品经理或产品办公室发布。",
"parent": 0,
"count": 2,
"filter": "raw",
"cat_ID": 145,
"category_count": 2,
"category_description": "产品理念、产品设计、产品构想等;主要由春松客服产品经理或产品办公室发布。",
"cat_name": "产品专栏",
"category_nicename": "product",
"category_parent": 0,
"content": "Formatted HTML, https://www.kevinleary.net/get-wordpress-post-content-by-post-id/"
}
]
}
*/
utils.writeTmpOutputFileOnDevelopment(body);
*/
utils.writeTmpOutputFileOnDevelopment(body);

// 发送 W3 文章通知到飞书群
// 发送 W3 文章通知到飞书群
try {
await feishuService.sendW3BroadcastNotification(body);
} catch (e) {
console.log("[Error] feishuService.sendW3BroadcastNotification")
console.error(e);
}

// 发送 W3 文章通知到邮件列表服务
try {
await mailService.sendW3BroadcastMaillists(body);
} catch (e) {
console.log("[Error] mailService.sendW3BroadcastMaillists")
console.error(e);
}

debug("[handleW3broadcast] ret", JSON.stringify(ret))
return ret;
debug("[handleW3broadcast] ret", JSON.stringify(ret))
return ret;
}


Expand Down
4 changes: 3 additions & 1 deletion sync/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@
"koa-static": "^5.0.0",
"koa2-cors": "^2.0.6",
"lodash": "^4.17.21",
"moment-timezone": "^0.5.37"
"moment-timezone": "^0.5.37",
"nodemailer": "^6.8.0",
"nodemailer-smtp-transport": "^2.7.4"
},
"devDependencies": {
"ava": "^4.3.3",
Expand Down
2 changes: 1 addition & 1 deletion sync/app/routers/w3.router.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
let body = ctx.request.body;
debug("/broadcast headers", JSON.stringify(ctx.request.headers, null, 2))
debug("/broadcast", "ctx.params", JSON.stringify(ctx.params), ", body\n", JSON.stringify(body, null, 2));

ctx.body = await w3Ctrl.handleW3broadcast(ctx.request.headers, ctx.params, body);

await next();
Expand Down
12 changes: 12 additions & 0 deletions sync/app/sample.env
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,15 @@
NODE_ENV=development
FEISHU_GROUP_GITHUB_BOTS=xxx,yyy
FEISHU_GROUP_W3_BOTS=xxx,yyy

MAIL_W3_EVENTS_CC=
MAIL_W3_EVENTS_BCC=

# SMTP Client
SMTP_HOST=smtp.feishu.cn
SMTP_PORT=465
SMTP_SSL=true
SMTP_USER_FROM=
SMTP_USER_NAME="CSKeFu W3"
SMTP_USER_PASS=

87 changes: 87 additions & 0 deletions sync/app/services/email.service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/**
* Send Emails
*/


const debug = require("debug")("sync:services:email");
const nodemailer = require('nodemailer');
const smtpTransport = require('nodemailer-smtp-transport');
const utils = require("../utils/index");

const SMTP_HOST = process.env["SMTP_HOST"];
const SMTP_PORT = process.env["SMTP_PORT"];
const SMTP_SSL = process.env["SMTP_SSL"];
const SMTP_USER_FROM = process.env["SMTP_USER_FROM"];
const SMTP_USER_NAME = process.env["SMTP_USER_NAME"];
const SMTP_USER_PASS = process.env["SMTP_USER_PASS"];
const MAIL_W3_EVENTS_CC = process.env["MAIL_W3_EVENTS_CC"];
const MAIL_W3_EVENTS_BCC = process.env["MAIL_W3_EVENTS_BCC"];
const BRAND_SUFFIX = process.env["BRAND_SUFFIX"] || "春松客服 W3";

const transport = nodemailer.createTransport(smtpTransport({
host: SMTP_HOST, // 服务
port: SMTP_PORT, // smtp端口
secure: SMTP_SSL,
auth: {
user: SMTP_USER_FROM, // 用户名
pass: SMTP_USER_PASS // SMTP授权码
}
}));

/**
* Send Mail
* @param {*} options
* @returns
*/
function send(options) {
debug("[send] %j", options)

return new Promise((resolve, reject) => {
transport.sendMail({
from: `${SMTP_USER_NAME}<${SMTP_USER_FROM}>`, // 发件邮箱
to: options.to, // 收件列表
bcc: options.bcc, // 收件列表
subject: options.subject, // 标题
html: options.html,
attachments: options.attachment ? [{ path: options.attachment }] : null,
},
(error, data) => {
if (error) return reject(error)
resolve(data)
})
})

}

/**
* 发送 W3 服务通知
* @param {*} payload
*/
async function sendW3BroadcastMaillists(payload) {

if (!MAIL_W3_EVENTS_CC) {
debug("[sendW3BroadcastMaillists] not set ENV MAIL_W3_EVENTS_CC, bypass broadcast.");
return;
}

await send({
to: MAIL_W3_EVENTS_CC,
bcc: MAIL_W3_EVENTS_BCC,
subject: utils.capitalizeFirstLetter(utils.getW3PostCategories(payload) + " - ") + payload.display_name + " - " + payload.post_title + " | " + BRAND_SUFFIX,
html: ` LINK: ${payload.link} <br />
AUTHOR: ${payload.display_name}(${payload.user_email}) <br />
PROFILE: ${payload.user_profile} <br />
<br />
CONTENT: <br />
${payload.content} <br />
<br />
<br />
`
})
}

exports = module.exports = {
send,
sendW3BroadcastMaillists
}
23 changes: 2 additions & 21 deletions sync/app/services/feishu.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -491,25 +491,6 @@ async function sendMilestoneEventNotification(payload) {
}
}

/**
* 获得 W3 文章标签分类信息
* @param {*} payload
*/
function getW3PostCategories(payload){
if(payload.categories && payload.categories.length > 0){
let ret = [];

for(let x of payload.categories){
ret.push(x.name);
}

return ret.join("_")
} else {
return "未分类"
}
}


/**
* Send W3 Post Events into Feishu Groups
* @param {*} payload
Expand All @@ -521,7 +502,7 @@ async function sendW3BroadcastNotification(payload) {
elements.push({
"tag": "div",
"text": {
"content": `**标题** ${payload.post_title}\n**作者** [${payload.display_name}(${payload.user_email})](${payload.user_profile})`,
"content": `**标题** ${payload.post_title}\n**作者** [${payload.display_name}(${payload.user_email})](${payload.user_profile})\n**正文**\n ${payload.content.substring(0, 60)}...`,
"tag": "lark_md"
}
})
Expand Down Expand Up @@ -555,7 +536,7 @@ async function sendW3BroadcastNotification(payload) {
"elements": elements,
"header": {
"title": {
"content": utils.capitalizeFirstLetter(getW3PostCategories(payload) + " - ") + payload.post_title + " | 春松客服 W3",
"content": utils.capitalizeFirstLetter(utils.getW3PostCategories(payload) + " - ") + payload.post_title + " | 春松客服 W3",
"tag": "plain_text"
}
}
Expand Down
25 changes: 23 additions & 2 deletions sync/app/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,27 @@ function writeTmpOutputFileOnDevelopment(obj) {

function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
}



/**
* 获得 W3 文章标签分类信息
* @param {*} payload
*/
function getW3PostCategories(payload) {
if (payload.categories && payload.categories.length > 0) {
let ret = [];

for (let x of payload.categories) {
ret.push(x.name);
}

return ret.join("_")
} else {
return "未分类"
}
}


exports = module.exports = {
Expand All @@ -40,5 +60,6 @@ exports = module.exports = {
writeJsonFile,
isNodeEnvDevelopment,
writeTmpOutputFileOnDevelopment,
capitalizeFirstLetter
capitalizeFirstLetter,
getW3PostCategories
}

0 comments on commit d0d1195

Please sign in to comment.