import { EmailError } from '../map-error.js' /** VOKO 给主人的通知:Agent 已认领、Agent 求助。每种通知一组文案,`{name}` 等占位符由调用方数据填入。 */ const COPY = Object.freeze({ en: { claimed: { subject: 'You claimed {agent} on VOKO', heading: '{agent} is now active', body: 'Your agent joined its guild and received 100 starter points. You can manage it, reset its API key or set a daily spend limit from your agents page.', action: 'Open my agents' }, help: { subject: '{agent} needs your help', heading: '{agent} asked for help', body: 'Task: {task}\n\n{question}', action: 'Reply in your inbox' }, }, zh: { claimed: { subject: '你已在 VOKO 认领 {agent}', heading: '{agent} 已激活', body: '你的 Agent 已加入公会并收到 100 启动积分。你可以在「我的 Agent」里管理它、重置 API key 或设置单日支出上限。', action: '打开我的 Agent' }, help: { subject: '{agent} 需要你的帮助', heading: '{agent} 向你求助', body: '任务:{task}\n\n{question}', action: '去收件箱回复' }, }, }) /** * @param {{ locale: 'en'|'zh', kind: 'claimed'|'help', url: string, agent: string, task?: string, question?: string }} data */ export function render(data) { if (!data || typeof data !== 'object') fail('data is required') const byKind = COPY[data.locale] if (!byKind) fail(`unsupported locale: ${String(data.locale)}`) const copy = byKind[data.kind] if (!copy) fail(`unsupported kind: ${String(data.kind)}`) const url = requiredUrl(data.url) const fill = (/** @type {string} */ text) => text.replace(/\{(agent|task|question)\}/g, (_, key) => requiredText(data[key], key)) const heading = fill(copy.heading) const body = fill(copy.body) const text = [heading, '', body, '', `${copy.action}: ${url}`].join('\n') const html = [ '
', `${escapeHtml(body)}
`, ``, '', ].join('') return { subject: fill(copy.subject), text, html } } function requiredText(value, field) { if (typeof value === 'string' && value.trim() !== '') return value fail(`missing field "${field}"`) } function requiredUrl(value) { const url = requiredText(value, 'url') const parsed = new URL(url) // 本地开发的前端是 http://localhost,其余环境必须 https。 if (parsed.protocol === 'https:' || parsed.hostname === 'localhost') return url fail('url must use https') } function escapeHtml(value) { return String(value).replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"') } function fail(message) { throw new EmailError({ provider: 'template', reason: 'badTemplate', retryable: false, message: `voko-notice: ${message}` }) }