diff --git a/.env.example b/.env.example index f32d6c1..5f611f1 100644 --- a/.env.example +++ b/.env.example @@ -9,6 +9,7 @@ TRUST_PROXY= ADMIN_EMAILS=corey@blaishome.online RESCUE_STATUS_NOTIFICATION_EMAIL=appadmin@flockpal.app DEFAULT_BIRD_PHOTO_PATH=/app/assets/yoda.png +FLOCKPAL_EMAIL_LOGO_PATH=/app/assets/flockpal-logo.png MILESTONE_REMINDERS_ENABLED=true MILESTONE_REMINDER_TIME_ZONE=America/New_York STRIPE_SECRET_KEY= diff --git a/backend/assets/flockpal-logo.png b/backend/assets/flockpal-logo.png new file mode 100644 index 0000000..248f19f Binary files /dev/null and b/backend/assets/flockpal-logo.png differ diff --git a/backend/src/app.ts b/backend/src/app.ts index 190a411..2d8f861 100644 --- a/backend/src/app.ts +++ b/backend/src/app.ts @@ -838,8 +838,21 @@ const getMilestoneYearCount = (reminder: BirdMilestoneReminderCandidateRow) => { return Number.isFinite(sourceYear) ? Math.max(0, reminder.reminder_year - sourceYear) : 0; }; -const getFlockPalLogoSvg = () => - ``; +const getFlockPalLogoAttachment = () => { + const logoPath = process.env.FLOCKPAL_EMAIL_LOGO_PATH?.trim() || path.join(process.cwd(), 'assets', 'flockpal-logo.png'); + + if (!existsSync(logoPath)) { + console.warn(`Unable to load FlockPal email logo from ${logoPath}`); + return null; + } + + return { + filename: 'flockpal-logo.png', + path: logoPath, + cid: 'flockpal-logo', + contentDisposition: 'inline' as const, + }; +}; const parseDataImage = (dataUrl: string) => { const match = /^data:(image\/[a-zA-Z0-9.+-]+);base64,(.+)$/.exec(dataUrl); @@ -865,6 +878,7 @@ const getDefaultBirdPhotoAttachment = () => { filename: 'yoda.png', path: defaultPhotoPath, cid: 'flockpal-default-bird-photo', + contentDisposition: 'inline' as const, }; }; @@ -1126,24 +1140,23 @@ const sendBirdMilestoneReminderNotification = async ({ } const copy = buildBirdMilestoneReminderCopy(reminder); - const attachments: NonNullable = [ - { - filename: 'flockpal-logo.svg', - content: getFlockPalLogoSvg(), - contentType: 'image/svg+xml', - cid: 'flockpal-logo', - }, - ]; + const attachments: NonNullable = []; + const logoAttachment = getFlockPalLogoAttachment(); const uploadedBirdPhoto = reminder.photo_data_url ? parseDataImage(reminder.photo_data_url) : null; const defaultBirdPhoto = uploadedBirdPhoto ? null : getDefaultBirdPhotoAttachment(); const birdPhotoCid = uploadedBirdPhoto ? 'bird-photo' : defaultBirdPhoto ? defaultBirdPhoto.cid : ''; + if (logoAttachment) { + attachments.push(logoAttachment); + } + if (uploadedBirdPhoto) { attachments.push({ filename: `${reminder.name.replace(/[^a-z0-9_-]+/gi, '-').toLowerCase() || 'bird'}-photo`, content: uploadedBirdPhoto.content, contentType: uploadedBirdPhoto.contentType, cid: birdPhotoCid, + contentDisposition: 'inline', }); } else if (defaultBirdPhoto) { attachments.push(defaultBirdPhoto); @@ -1181,7 +1194,11 @@ const sendBirdMilestoneReminderNotification = async ({
- FlockPal + ${ + logoAttachment + ? 'FlockPal' + : 'FlockPal' + }
diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 380f663..ad99202 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -34,6 +34,7 @@ services: ADMIN_EMAILS: ${ADMIN_EMAILS:-} RESCUE_STATUS_NOTIFICATION_EMAIL: ${RESCUE_STATUS_NOTIFICATION_EMAIL:-appadmin@flockpal.app} DEFAULT_BIRD_PHOTO_PATH: ${DEFAULT_BIRD_PHOTO_PATH:-/app/assets/yoda.png} + FLOCKPAL_EMAIL_LOGO_PATH: ${FLOCKPAL_EMAIL_LOGO_PATH:-/app/assets/flockpal-logo.png} MILESTONE_REMINDERS_ENABLED: ${MILESTONE_REMINDERS_ENABLED:-true} MILESTONE_REMINDER_TIME_ZONE: ${MILESTONE_REMINDER_TIME_ZONE:-America/New_York} GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID:-} diff --git a/docker-compose.yml b/docker-compose.yml index d11260e..301a981 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -33,6 +33,7 @@ services: ADMIN_EMAILS: ${ADMIN_EMAILS:-} RESCUE_STATUS_NOTIFICATION_EMAIL: ${RESCUE_STATUS_NOTIFICATION_EMAIL:-appadmin@flockpal.app} DEFAULT_BIRD_PHOTO_PATH: ${DEFAULT_BIRD_PHOTO_PATH:-/app/assets/yoda.png} + FLOCKPAL_EMAIL_LOGO_PATH: ${FLOCKPAL_EMAIL_LOGO_PATH:-/app/assets/flockpal-logo.png} MILESTONE_REMINDERS_ENABLED: ${MILESTONE_REMINDERS_ENABLED:-true} MILESTONE_REMINDER_TIME_ZONE: ${MILESTONE_REMINDER_TIME_ZONE:-America/New_York} GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID:-}