Skip to content

Commit bc6c86b

Browse files
committed
fix(gmail): RFC 2047 encode subject headers for non-ASCII characters
1 parent 19ef526 commit bc6c86b

File tree

1 file changed

+18
-2
lines changed

1 file changed

+18
-2
lines changed

apps/sim/tools/gmail/utils.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,22 @@ function generateBoundary(): string {
294294
return `----=_Part_${Date.now()}_${Math.random().toString(36).substring(2, 15)}`
295295
}
296296

297+
/**
298+
* Encode a header value using RFC 2047 Base64 encoding if it contains non-ASCII characters.
299+
* Email headers per RFC 2822 must be ASCII-only. Non-ASCII characters (emojis, accented
300+
* characters, etc.) must be encoded as =?UTF-8?B?<base64>?= to avoid mojibake.
301+
* @param value The header value to encode
302+
* @returns The encoded header value, or the original if it's already ASCII
303+
*/
304+
export function encodeRfc2047(value: string): string {
305+
// eslint-disable-next-line no-control-regex
306+
if (/^[\x00-\x7F]*$/.test(value)) {
307+
return value
308+
}
309+
const encoded = Buffer.from(value, 'utf-8').toString('base64')
310+
return `=?UTF-8?B?${encoded}?=`
311+
}
312+
297313
/**
298314
* Encode string or buffer to base64url format (URL-safe base64)
299315
* Gmail API requires base64url encoding for the raw message field
@@ -333,7 +349,7 @@ export function buildSimpleEmailMessage(params: {
333349
emailHeaders.push(`Bcc: ${bcc}`)
334350
}
335351

336-
emailHeaders.push(`Subject: ${subject || ''}`)
352+
emailHeaders.push(`Subject: ${encodeRfc2047(subject || '')}`)
337353

338354
if (inReplyTo) {
339355
emailHeaders.push(`In-Reply-To: ${inReplyTo}`)
@@ -380,7 +396,7 @@ export function buildMimeMessage(params: BuildMimeMessageParams): string {
380396
if (bcc) {
381397
messageParts.push(`Bcc: ${bcc}`)
382398
}
383-
messageParts.push(`Subject: ${subject || ''}`)
399+
messageParts.push(`Subject: ${encodeRfc2047(subject || '')}`)
384400

385401
if (inReplyTo) {
386402
messageParts.push(`In-Reply-To: ${inReplyTo}`)

0 commit comments

Comments
 (0)