Skip to content

Commit b1aed1e

Browse files
committed
chore: fix mailto support for components v2
1 parent 6428679 commit b1aed1e

File tree

2 files changed

+28
-23
lines changed

2 files changed

+28
-23
lines changed

src/pages/api/mailto.ts

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,32 @@
11
import type { APIRoute } from 'astro';
22

3+
import { formatDate } from '$utils/helpers/date';
4+
35
export const prerender = false;
46

5-
export const GET: APIRoute = async ({ request }) => {
7+
export const GET: APIRoute = async ({ request, redirect }) => {
68
try {
79
const url = new URL(request.url);
8-
const mailtoUrl = decodeURIComponent(url.searchParams.get('url') || '');
10+
const email = url.searchParams.get('email') || '';
11+
const name = url.searchParams.get('name') || '';
12+
const message = url.searchParams.get('message') || '';
913

10-
if (!mailtoUrl || !mailtoUrl.toLowerCase().startsWith('mailto:')) {
11-
return new Response('Invalid mailto URL', { status: 400 });
14+
if (!email) {
15+
return new Response('Missing email', { status: 400 });
1216
}
1317

14-
return Response.redirect(mailtoUrl, 302);
18+
// Compose subject and body using the date helper for ISO
19+
const subject = `Re: Message from ${name}`;
20+
const isoDate = formatDate(new Date(), 'iso');
21+
const body = `\n\nOn ${isoDate}, ${name} wrote:\n\n${message
22+
.split('\n')
23+
.map((line) => `> ${line}`)
24+
.join('\n')}`;
25+
26+
// Properly encode subject and body for mailto
27+
const mailtoUrl = `mailto:${email}?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(body)}`;
28+
29+
return redirect(mailtoUrl);
1530
} catch (error) {
1631
console.error('Error processing mailto URL:', error);
1732
return new Response('Error processing mailto URL', { status: 500 });

src/utils/forms/message.ts

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { DISCORD_CONTACT_WEBHOOK_URL, TURNSTILE_SECRET_TOKEN } from 'astro:env/s
22

33
import { site } from '$utils/config';
44
import { CLOUDFLARE_TURNSTILE_URL, MESSAGE_CHARACTER_LIMIT } from '$utils/constants';
5-
import { formatDate } from '$utils/helpers/date';
65

76
export interface MessageDetails {
87
name: string;
@@ -16,14 +15,12 @@ export interface SubmissionResult {
1615
}
1716

1817
const returnEncodedMailtoUrl = (email: string, name: string, message: string) => {
19-
const mailtoUrl = `mailto:${encodeURIComponent(email)}?subject=${encodeURIComponent(`Re: Message from ${name}`)}&body=${encodeURIComponent(
20-
`%0D%0A%0D%0AOn ${formatDate(new Date(), 'iso')}, ${name} wrote:%0D%0A%0D%0A${message
21-
.split('\n')
22-
.map((line) => `> ${line}`)
23-
.join('%0D%0A')}`
24-
)}`;
25-
26-
return `${site.url}/api/mailto?url=${encodeURIComponent(mailtoUrl)}`;
18+
const url = new URL(`${site.url}/api/mailto`);
19+
url.searchParams.set('email', email);
20+
url.searchParams.set('name', name);
21+
url.searchParams.set('message', message);
22+
23+
return `<${url.href}>`;
2724
};
2825

2926
const sendDiscordMessage = async (details: MessageDetails, url: string) => {
@@ -55,15 +52,8 @@ const sendDiscordMessage = async (details: MessageDetails, url: string) => {
5552
accent_color: 0xf38ba8,
5653
components: [
5754
{
58-
type: 1,
59-
components: [
60-
{
61-
type: 2,
62-
label: 'Reply via Email',
63-
style: 5,
64-
url: returnEncodedMailtoUrl(details.email, details.name, details.message),
65-
},
66-
],
55+
type: 10,
56+
content: `🔗 [Reply via email](${returnEncodedMailtoUrl(details.email, details.name, details.message)})`,
6757
},
6858
],
6959
},

0 commit comments

Comments
 (0)