Add upload email notifications with Seafile direct-upload watcher; v2.0.6
- Portal uploads send one email immediately (host, episode, passage, description, filenames) via Resend to NUGGETS_NOTIFY_EMAIL - Seafile watcher polls /Episode Upload every 15 min for direct uploads and sends a notification for any new file not already seen via portal - Files uploaded through the portal are marked seen so the watcher never sends a duplicate notification - Credentials kept out of git: SEAFILE_TOKEN, SEAFILE_NUGGETS_REPO_ID, NUGGETS_NOTIFY_EMAIL now sourced from docker .env file Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
6a03813914
commit
1e396644a9
7 files changed
+177
-5
No files matched your search
@@ -712,3 +712,55 @@ export async function sendStudyWeeklyDigestEmail(email, displayName, lessons, un
|
||||
console.error('[study-digest] send exception:', err)
|
||||
}
|
||||
}
|
||||
|
||||
// ── Nuggets upload notifications ───────────────────────────────────────────
|
||||
|
||||
export async function sendNuggetsUploadNotification({ to, source, hostName, episodeName, passage, description, filename, infoFile }) {
|
||||
if (!process.env.RESEND_API_KEY) return
|
||||
const resend = new Resend(process.env.RESEND_API_KEY)
|
||||
const from = process.env.RESEND_FROM ?? DEFAULT_RESEND_FROM
|
||||
const sourceLabel = source === 'portal' ? 'Upload Portal' : 'Direct to Seafile'
|
||||
const subject = `New Nuggets Episode Upload: ${episodeName || filename}`
|
||||
|
||||
const bodyHtml = `
|
||||
<p style="margin:0 0 16px;font-family:Arial,sans-serif;font-size:15px;color:#2c2417;">A new episode file has arrived in Seafile.</p>
|
||||
<table style="width:100%;border-collapse:collapse;font-family:Arial,sans-serif;font-size:14px;color:#2c2417;">
|
||||
<tr><td style="padding:6px 0;color:#7a7060;width:120px;">Source</td><td style="padding:6px 0;font-weight:600;">${escapeHtml(sourceLabel)}</td></tr>
|
||||
${hostName ? `<tr><td style="padding:6px 0;color:#7a7060;">Host</td><td style="padding:6px 0;">${escapeHtml(hostName)}</td></tr>` : ''}
|
||||
${episodeName ? `<tr><td style="padding:6px 0;color:#7a7060;">Episode</td><td style="padding:6px 0;font-weight:600;">${escapeHtml(episodeName)}</td></tr>` : ''}
|
||||
${passage ? `<tr><td style="padding:6px 0;color:#7a7060;">Passage</td><td style="padding:6px 0;">${escapeHtml(passage)}</td></tr>` : ''}
|
||||
<tr><td style="padding:6px 0;color:#7a7060;">Audio File</td><td style="padding:6px 0;font-family:monospace;font-size:13px;">${escapeHtml(filename)}</td></tr>
|
||||
${infoFile ? `<tr><td style="padding:6px 0;color:#7a7060;">Info File</td><td style="padding:6px 0;font-family:monospace;font-size:13px;">${escapeHtml(infoFile)}</td></tr>` : ''}
|
||||
</table>
|
||||
${description ? `<p style="margin:16px 0 0;font-family:Arial,sans-serif;font-size:14px;color:#2c2417;"><strong>Description:</strong><br/>${escapeHtml(description).replace(/\n/g, '<br/>')}</p>` : ''}
|
||||
`
|
||||
|
||||
const textBody = [
|
||||
`New Nuggets Episode Upload (${sourceLabel})`,
|
||||
'',
|
||||
hostName ? `Host: ${hostName}` : '',
|
||||
episodeName ? `Episode: ${episodeName}` : '',
|
||||
passage ? `Passage: ${passage}` : '',
|
||||
`Audio File: ${filename}`,
|
||||
infoFile ? `Info File: ${infoFile}` : '',
|
||||
description ? `\nDescription:\n${description}` : '',
|
||||
].filter(Boolean).join('\n')
|
||||
|
||||
try {
|
||||
const { error } = await resend.emails.send({
|
||||
from,
|
||||
to: [to],
|
||||
subject,
|
||||
text: textBody,
|
||||
html: buildBrandedEmailHtml({
|
||||
title: 'New Episode Upload',
|
||||
eyebrow: 'Nuggets',
|
||||
bodyHtml,
|
||||
footerHtml: '<p style="margin:0;font-family:Arial,sans-serif;font-size:12px;color:#7a7060;">This notification was sent because a file was uploaded to the Nuggets Seafile library.</p>',
|
||||
}),
|
||||
})
|
||||
if (error) console.error('[nuggets-notify] send error:', error)
|
||||
} catch (err) {
|
||||
console.error('[nuggets-notify] send exception:', err)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user