2020-03-01 05:01:03 +07:00
|
|
|
const nodemailer = require("nodemailer")
|
|
|
|
const core = require("@actions/core")
|
2021-06-23 00:18:21 +07:00
|
|
|
const glob = require("@actions/glob")
|
2020-03-01 05:01:03 +07:00
|
|
|
const fs = require("fs")
|
2021-04-25 21:14:13 +07:00
|
|
|
const showdown = require("showdown")
|
2022-03-25 01:30:26 +07:00
|
|
|
const path = require("path")
|
2020-03-01 05:01:03 +07:00
|
|
|
|
2023-08-08 19:24:30 +07:00
|
|
|
function getText(textOrFile, convertMarkdown) {
|
|
|
|
let text = textOrFile
|
2020-12-01 00:51:34 +07:00
|
|
|
|
2023-08-08 19:24:30 +07:00
|
|
|
// Read text from file
|
|
|
|
if (textOrFile.startsWith("file://")) {
|
|
|
|
const file = textOrFile.replace("file://", "")
|
|
|
|
text = fs.readFileSync(file, "utf8")
|
2020-12-01 00:51:34 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
// Convert Markdown to HTML
|
|
|
|
if (convertMarkdown) {
|
2024-11-20 13:42:26 +07:00
|
|
|
const converter = new showdown.Converter({tables: true})
|
2023-08-08 19:24:30 +07:00
|
|
|
text = converter.makeHtml(text)
|
2020-03-01 05:01:03 +07:00
|
|
|
}
|
|
|
|
|
2023-08-08 19:24:30 +07:00
|
|
|
return text
|
2020-03-01 05:01:03 +07:00
|
|
|
}
|
|
|
|
|
2020-09-24 15:24:29 +07:00
|
|
|
function getFrom(from, username) {
|
2021-04-25 21:14:13 +07:00
|
|
|
if (from.match(/.+ <.+@.+>/)) {
|
2020-03-25 22:18:35 +07:00
|
|
|
return from
|
|
|
|
}
|
|
|
|
|
|
|
|
return `"${from}" <${username}>`
|
|
|
|
}
|
|
|
|
|
2021-06-23 00:18:21 +07:00
|
|
|
async function getAttachments(attachments) {
|
|
|
|
const globber = await glob.create(attachments.split(',').join('\n'))
|
|
|
|
const files = await globber.glob()
|
2022-03-25 01:30:26 +07:00
|
|
|
return files.map(f => ({ filename: path.basename(f), path: f, cid: f.replace(/^.*[\\\/]/, '')}))
|
2021-06-23 00:18:21 +07:00
|
|
|
}
|
|
|
|
|
2024-02-14 18:26:05 +07:00
|
|
|
function sleep(ms) {
|
|
|
|
return new Promise((resolve) => {
|
|
|
|
setTimeout(resolve, ms);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-03-01 05:01:03 +07:00
|
|
|
async function main() {
|
2020-03-01 05:13:30 +07:00
|
|
|
try {
|
2022-09-09 23:53:48 +07:00
|
|
|
let serverAddress = core.getInput("server_address")
|
|
|
|
let serverPort = core.getInput("server_port")
|
|
|
|
let secure = core.getInput("secure")
|
|
|
|
let username = core.getInput("username")
|
|
|
|
let password = core.getInput("password")
|
|
|
|
|
|
|
|
if (!secure) {
|
|
|
|
secure = serverPort === "465" ? "true" : "false"
|
|
|
|
}
|
|
|
|
|
|
|
|
const connectionUrl = core.getInput("connection_url")
|
|
|
|
if (connectionUrl) {
|
|
|
|
const url = new URL(connectionUrl)
|
|
|
|
switch (url.protocol) {
|
|
|
|
default:
|
|
|
|
throw new Error(`Unsupported connection protocol '${url.protocol}'`)
|
|
|
|
case "smtp:":
|
|
|
|
serverPort = "25"
|
|
|
|
secure = "false"
|
|
|
|
break
|
|
|
|
case "smtp+starttls:":
|
|
|
|
serverPort = "465"
|
|
|
|
secure = "true"
|
|
|
|
break
|
|
|
|
}
|
|
|
|
if (url.hostname) {
|
|
|
|
serverAddress = url.hostname
|
|
|
|
}
|
|
|
|
if (url.port) {
|
|
|
|
serverPort = url.port
|
|
|
|
}
|
|
|
|
if (url.username) {
|
|
|
|
username = unescape(url.username)
|
|
|
|
}
|
|
|
|
if (url.password) {
|
|
|
|
password = unescape(url.password)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-01 18:37:11 +07:00
|
|
|
const subject = core.getInput("subject", { required: true })
|
|
|
|
const from = core.getInput("from", { required: true })
|
2023-09-27 13:49:06 +07:00
|
|
|
const to = core.getInput("to", { required: false })
|
2021-04-25 21:11:54 +07:00
|
|
|
const body = core.getInput("body", { required: false })
|
|
|
|
const htmlBody = core.getInput("html_body", { required: false })
|
2020-12-16 23:16:24 +07:00
|
|
|
const cc = core.getInput("cc", { required: false })
|
|
|
|
const bcc = core.getInput("bcc", { required: false })
|
2021-04-08 00:34:58 +07:00
|
|
|
const replyTo = core.getInput("reply_to", { required: false })
|
2021-10-17 14:45:58 +07:00
|
|
|
const inReplyTo = core.getInput("in_reply_to", { required: false })
|
2020-04-07 15:30:45 +07:00
|
|
|
const attachments = core.getInput("attachments", { required: false })
|
2020-12-01 00:51:34 +07:00
|
|
|
const convertMarkdown = core.getInput("convert_markdown", { required: false })
|
2021-03-26 14:42:12 +07:00
|
|
|
const ignoreCert = core.getInput("ignore_cert", { required: false })
|
2021-07-02 23:33:56 +07:00
|
|
|
const priority = core.getInput("priority", { required: false })
|
2024-01-06 00:40:18 +07:00
|
|
|
const nodemailerlog = core.getInput("nodemailerlog", { required: false })
|
|
|
|
const nodemailerdebug = core.getInput("nodemailerdebug", { required: false })
|
2020-03-01 05:01:03 +07:00
|
|
|
|
2023-09-27 13:49:06 +07:00
|
|
|
// if neither to, cc or bcc is provided, throw error
|
|
|
|
if (!to && !cc && !bcc) {
|
|
|
|
throw new Error("At least one of 'to', 'cc' or 'bcc' must be specified")
|
|
|
|
}
|
|
|
|
|
2022-09-09 23:53:48 +07:00
|
|
|
if (!serverAddress) {
|
|
|
|
throw new Error("Server address must be specified")
|
|
|
|
}
|
|
|
|
|
2020-03-24 20:03:35 +07:00
|
|
|
const transport = nodemailer.createTransport({
|
2020-12-01 00:51:34 +07:00
|
|
|
host: serverAddress,
|
2021-06-15 01:04:27 +07:00
|
|
|
auth: username && password ? {
|
2020-03-24 20:03:35 +07:00
|
|
|
user: username,
|
2021-06-15 01:04:27 +07:00
|
|
|
pass: password
|
|
|
|
} : undefined,
|
|
|
|
port: serverPort,
|
2022-09-09 23:53:48 +07:00
|
|
|
secure: secure === "true",
|
2021-06-15 01:04:27 +07:00
|
|
|
tls: ignoreCert == "true" ? {
|
2021-03-26 14:42:12 +07:00
|
|
|
rejectUnauthorized: false
|
2021-06-15 01:04:27 +07:00
|
|
|
} : undefined,
|
2024-01-06 00:40:18 +07:00
|
|
|
logger: nodemailerdebug == "true" ? true : nodemailerlog,
|
|
|
|
debug: nodemailerdebug,
|
2020-03-24 20:03:35 +07:00
|
|
|
})
|
2021-04-25 21:14:13 +07:00
|
|
|
|
2024-02-14 18:26:05 +07:00
|
|
|
var i = 1;
|
|
|
|
while (true) {
|
|
|
|
try {
|
|
|
|
const info = await transport.sendMail({
|
|
|
|
from: getFrom(from, username),
|
|
|
|
to: to,
|
|
|
|
subject: getText(subject, false),
|
|
|
|
cc: cc ? cc : undefined,
|
|
|
|
bcc: bcc ? bcc : undefined,
|
|
|
|
replyTo: replyTo ? replyTo : undefined,
|
|
|
|
inReplyTo: inReplyTo ? inReplyTo : undefined,
|
|
|
|
references: inReplyTo ? inReplyTo : undefined,
|
|
|
|
text: body ? getText(body, false) : undefined,
|
|
|
|
html: htmlBody ? getText(htmlBody, convertMarkdown) : undefined,
|
|
|
|
priority: priority ? priority : undefined,
|
|
|
|
attachments: attachments ? (await getAttachments(attachments)) : undefined,
|
|
|
|
});
|
|
|
|
break;
|
|
|
|
} catch (error) {
|
|
|
|
if (!error.message.includes("Try again later,")) {
|
|
|
|
core.setFailed(error.message)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (i > 10) {
|
|
|
|
core.setFailed(error.message)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
console.log("Received: " + error.message);
|
|
|
|
if (i < 2) {
|
|
|
|
console.log("Trying again in a minute...");
|
|
|
|
} else {
|
|
|
|
console.log("Trying again in " + i + " minutes...");
|
|
|
|
}
|
|
|
|
await sleep(i * 60000);
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
2020-03-01 05:13:30 +07:00
|
|
|
} catch (error) {
|
|
|
|
core.setFailed(error.message)
|
|
|
|
}
|
2020-03-01 05:01:03 +07:00
|
|
|
}
|
|
|
|
|
2020-03-25 22:06:11 +07:00
|
|
|
main()
|