feat(meetings): email invites + add external participants by email + share link (batch69)

#4: scheduled meetings can now invite people who aren't on Connect.
- SMTP config (config.js, env-gated: SMTP_HOST/PORT/USER/PASS/FROM/SECURE,
  PUBLIC_BASE_URL) + a small nodemailer wrapper (mailer.js) with a branded
  meeting-invite template carrying the guest join link. No-op until SMTP is set.
- /api/meetings/schedule + /update accept participantEmails; external emails are
  persisted (scheduled_meetings.guest_emails migration) and emailed the guest
  link (plus any invited Connect users with an email on file). Fire-and-forget —
  a mail outage never fails scheduling.
- Meetings list DTO returns `link`; schedule form gains an "Invite by email"
  chip input; each scheduled-meeting card gets a "Copy link" action.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-10 16:02:45 +05:30
parent 466c0d5d70
commit 7bc40d8397
6 changed files with 175 additions and 18 deletions
+20
View File
@@ -26,6 +26,18 @@ const LIVEKIT_API_KEY = process.env.LIVEKIT_API_KEY || '';
const LIVEKIT_API_SECRET = process.env.LIVEKIT_API_SECRET || '';
const LIVEKIT_ENABLED = !!(LIVEKIT_URL && LIVEKIT_API_KEY && LIVEKIT_API_SECRET);
// SMTP for outbound email (meeting invites to external participants, #4). Entirely optional and
// config-gated: email is only sent when SMTP_HOST/USER/PASS are set. Credentials stay server-side.
// PUBLIC_BASE_URL is the origin used to build guest meeting links in emails (e.g. https://remote.bizgaze.com).
const SMTP_HOST = process.env.SMTP_HOST || '';
const SMTP_PORT = Number(process.env.SMTP_PORT || 587);
const SMTP_SECURE = String(process.env.SMTP_SECURE || '').toLowerCase() === 'true' || SMTP_PORT === 465; // TLS on connect (465) vs STARTTLS
const SMTP_USER = process.env.SMTP_USER || '';
const SMTP_PASS = process.env.SMTP_PASS || '';
const SMTP_FROM = process.env.SMTP_FROM || (SMTP_USER ? ('Biz Connect <' + SMTP_USER + '>') : '');
const SMTP_ENABLED = !!(SMTP_HOST && SMTP_USER && SMTP_PASS);
const PUBLIC_BASE_URL = (process.env.PUBLIC_BASE_URL || 'https://remote.bizgaze.com').replace(/\/+$/, '');
module.exports = {
PORT: process.env.PORT || 8090,
HTTPS_PORT: process.env.HTTPS_PORT || 8443,
@@ -33,6 +45,14 @@ module.exports = {
LIVEKIT_API_KEY,
LIVEKIT_API_SECRET,
LIVEKIT_ENABLED,
SMTP_HOST,
SMTP_PORT,
SMTP_SECURE,
SMTP_USER,
SMTP_PASS,
SMTP_FROM,
SMTP_ENABLED,
PUBLIC_BASE_URL,
PUBLIC_DIR,
REC_DIR,
TRANS_DIR,