[GH-ISSUE #444] Support base64 encoded mail messages #340

Closed
opened 2026-05-07 00:23:15 +02:00 by BreizhHardware · 4 comments

Originally created by @barart on GitHub (Oct 20, 2022).
Original GitHub issue: https://github.com/binwiederhier/ntfy/issues/444

Some of the messages i send to ntfy are base64 encoded, this messages are not originated by me but by some external service that send me alerts by mail, as i dont want to receive this messages on my mail i send it to ntfy (via emal) so i can receive it on the ntfy app, however, some messages are base64 encoded and the ntfy app show them in this way instead of decode it, i would like that ntfy can show this messages on the app

Originally created by @barart on GitHub (Oct 20, 2022). Original GitHub issue: https://github.com/binwiederhier/ntfy/issues/444 Some of the messages i send to ntfy are base64 encoded, this messages are not originated by me but by some external service that send me alerts by mail, as i dont want to receive this messages on my mail i send it to ntfy (via emal) so i can receive it on the ntfy app, however, some messages are base64 encoded and the ntfy app show them in this way instead of decode it, i would like that ntfy can show this messages on the app
BreizhHardware 2026-05-07 00:23:15 +02:00
Author
Owner

@binwiederhier commented on GitHub (Oct 21, 2022):

This is a reasonable ask. If you can provide a detailed example of the entire raw email as captured in the logs when log-level = TRACE, that'd be helpful for development. Thank you.

<!-- gh-comment-id:1287051934 --> @binwiederhier commented on GitHub (Oct 21, 2022): This is a reasonable ask. If you can provide a detailed example of the entire raw email as captured in the logs when `log-level = TRACE`, that'd be helpful for development. Thank you.
Author
Owner

@barart commented on GitHub (Oct 21, 2022):

This is a reasonable ask. If you can provide a detailed example of the entire raw email as captured in the logs when log-level = TRACE, that'd be helpful for development. Thank you.

Here you are with one message, i masked and deleted all the personal data, im waiting to receive a 2nd message that is different to this and have a different behaviour on ntfy:

2022/10/21 19:07:22 TRACE hostaname/xx.xxx.xx.xxx:xxxx SMTP DATA: X-Sender-Id:
 xXxXxXxXxX|x-authuser|sender@domain.xx
Received: from sender.hostname.tld (localhost [127.0.0.1])
	by sender.hostname.tld (Postfix) with ESMTP id xXXxxXxxXXxx;
	Fri, 21 Oct 2022 19:07:20 +0000 (UTC)
Received: from sender.hostname.tld (unknown [127.0.0.6])
	(Authenticated sender: xXxXxXxXxx)
	by sender.hostname.tld (Postfix) with ESMTPA id xxXxxXXxxXXx;
	Fri, 21 Oct 2022 19:07:19 +0000 (UTC)
ARC-Seal: i=1; s=arc-2022; d=domain.tld; t=1666379240; a=rsa-sha256;
	cv=none;
	b=xXxXxXxXxXxxXxxXx==
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed;
 d=domain.tld;
	s=arc-2022; t=1666379240;
	h=from:from:reply-to:reply-to:subject:subject:date:date:
	 message-id:message-id:to:to:cc:mime-version:mime-version:
	 content-type:content-type:dkim-signature;
	bh=xXxXxXxXx=;
	b=xXxXxxXxxXXxXX==
ARC-Authentication-Results: i=1;
	rspamd-xXxXxxxXX-xxxxx;
	auth=pass smtp.auth=xxxxxx smtp.mailfrom=sender@domain.tld
X-Sender-Id:
 xXxXxXxX|x-authuser|sender@domain.tld
X-SR-Relay: Neutral
X-server-SenderId:
 xXXxxXxxXXxx|x-authuser|sender@domain.tld
X-Sever-Auth-Id: xxXxxXxx
X-Inform-Eight: xxxxXXxxx
X-SR-Loop-Signature: xxXXxxXXX
X-SR-Ingress-Time: 1666379240359
Received: from server.hostname.tld (server.hostname.tld [xxx.xxx.xx.xxx])
	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384)
	by xxx.xxx.xxx.xxx (trex/6.7.1);
	Fri, 21 Oct 2022 19:07:20 +0000
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;
	d=server.hostname.tld; s=default; h=Content-Type:Mime-Version:To:Subject:
	Reply-To:Message-Id:From:Date:Sender:Cc:Content-Transfer-Encoding:Content-ID:
	Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc
	:Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe:
	List-Subscribe:List-Post:List-Owner:List-Archive;
	bh=xxXXXXxXXXXXX=; b=xXXxxxXXXxXXXxxXXX==;
Received: from localhost ([127.0.0.1]:33812 helo=localhost.localdomain)
	by localhost.localdomain with esmtpa (Exim 4.95)
	(envelope-from <sender@domain.tld>)
	id xXxXXxX;
	Fri, 21 Oct 2022 14:07:18 -0500
Date: Fri, 21 Oct 2022 19:07:18 GMT
From: "Sender on domain.tld" <sender@domain.tld>
Message-Id: <xXXxxxXX@domain.tld>
Reply-To: "Sender on domain.tld" <sender@domain.tld>
Subject: [To NTFY] TEST MESSAGE.
To: xXxxxxXxxntfy@ntfyserver.tld
X-iContact_locale: en
Mime-Version: 1.0
Content-Type: multipart/mixed; boundary="mixed-Custom::Email::Object-11233-4555678910-0.123456478946"
X-AuthUser: XxxXxxXX@domain.tld

--mixed-Custom::Email::Object-xXxxXxxXxxXXX
Content-Type: multipart/alternative; boundary="alternative-Custom::Email::Object-xxxxxxxxxxxx"

--alternative-Custom::Email::Object-xxxxxxx
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable

Teste Message =E2=80=9Cto ntfy=E2=80=9D test test test.

Text text textText text textText text textText te =E2=80=9Ctexttexttexttext=E2=80=9D texttexttext.

mre text text text text text text =
text.
.....
.....
...............
.....

--alternative-Custom::Email::Object-xxxxxxx
Content-Type: multipart/related; boundary="related-Custom::Email::Object-xxxxxxxxxxx"

--related-Custom::Email::Object-xxxxxxx
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: quoted-printable

Message in HTML FORMAT<body> etc... 
...
...
...
...
..
...


--related-Custom::Email::Object-xxxxxxx
Content-Type: image/png; x-unix-mode=0600; name="image.png"
Content-Disposition: attachment; filename="image.png"
Content-ID: <auto_cid_xxxxxxx>
Content-Transfer-Encoding: base64

base64code=

--related-Custom::Email::Object-xxxxxxx--

--alternative-Customl::Email::Object-xxxxxxxx--

--mixed-Custom::Email::Object-xxxxxxxx
Content-Type: text/plain; charset="utf-8"; x-unix-mode=0600; name="filename.txt"
Content-Disposition: attachment; filename="filename.txt"
Content-Transfer-Encoding: base64

base64code==
--mixed-Custom::Email::Object-xxxxxxx--
2022/10/21 19:07:22 TRACE xxx.xx.xxxx HTTP GET /xxxxxxxxxxxxxxxxxxxx/sse Sending keepalive message
2022/10/21 19:07:22 DEBUG xx.xx.xx.xx HTTP POST /xxxxx Dispatching request
2022/10/21 19:07:22 TRACE xx.xx.xx.xx HTTP POST /xxxxx Entire request (headers and body):
POST /asgard HTTP/1.1
X-Forwarded-For: xx.xx.xx.xx
Title: [To NTFY] TEST MESSAGE.

i guess here is base64code ... (peeked 4096 bytes)
2022/10/21 19:07:22 DEBUG xxx.xxx.xxx.xxx/xxx/xxxxx Received message: event=message, body=29516 byte(s), delayed=false, firebase=true, cache=true, up=false, email=
2022/10/21 19:07:22 TRACE xxxxx.xxx.xxx.xx/xxx/xxxx Message body: {
  "id": "xxxxxxxx",
  "time": 1666379242,
  "event": "message",
  "topic": "xxxxx",
  "title": "[To NTFY] TEST MESSAGE.",
  "message": "Iguess is base64 code
2022/10/21 19:07:22 TRACE xxx.xx.xxx.x/xxxxx/xxxxx No stream or WebSocket subscribers, not forwarding
2022/10/21 19:07:22 DEBUG xxx.xx.xxx.x/xxxxx/xxxxx Publishing to Firebase
2022/10/21 19:07:22 TRACE xxx.xx.xxx.x/xxxxx/xxxxx Firebase message: {
  "topic": "xxxxx",
  "data": {
    "click": "",
    "encoding": "",
    "event": "message",
    "icon": "",
    "id": "xxxxx",
    "message": "i guess base64 code
2022/10/21 19:07:22 TRACE xxx.xx.xx.xx HTTP GET /xxxxxxxxxxxx/sse Sending keepalive message
2022/10/21 19:07:22 WARN xx.xx.xx.xx/xxxx/XxXXXXxxXX Unable to publish to Firebase: Request contains an invalid argument.
<!-- gh-comment-id:1287366088 --> @barart commented on GitHub (Oct 21, 2022): > This is a reasonable ask. If you can provide a detailed example of the entire raw email as captured in the logs when `log-level = TRACE`, that'd be helpful for development. Thank you. Here you are with one message, i masked and deleted all the personal data, im waiting to receive a 2nd message that is different to this and have a different behaviour on ntfy: ``` 2022/10/21 19:07:22 TRACE hostaname/xx.xxx.xx.xxx:xxxx SMTP DATA: X-Sender-Id: xXxXxXxXxX|x-authuser|sender@domain.xx Received: from sender.hostname.tld (localhost [127.0.0.1]) by sender.hostname.tld (Postfix) with ESMTP id xXXxxXxxXXxx; Fri, 21 Oct 2022 19:07:20 +0000 (UTC) Received: from sender.hostname.tld (unknown [127.0.0.6]) (Authenticated sender: xXxXxXxXxx) by sender.hostname.tld (Postfix) with ESMTPA id xxXxxXXxxXXx; Fri, 21 Oct 2022 19:07:19 +0000 (UTC) ARC-Seal: i=1; s=arc-2022; d=domain.tld; t=1666379240; a=rsa-sha256; cv=none; b=xXxXxXxXxXxxXxxXx== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=domain.tld; s=arc-2022; t=1666379240; h=from:from:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type:dkim-signature; bh=xXxXxXxXx=; b=xXxXxxXxxXXxXX== ARC-Authentication-Results: i=1; rspamd-xXxXxxxXX-xxxxx; auth=pass smtp.auth=xxxxxx smtp.mailfrom=sender@domain.tld X-Sender-Id: xXxXxXxX|x-authuser|sender@domain.tld X-SR-Relay: Neutral X-server-SenderId: xXXxxXxxXXxx|x-authuser|sender@domain.tld X-Sever-Auth-Id: xxXxxXxx X-Inform-Eight: xxxxXXxxx X-SR-Loop-Signature: xxXXxxXXX X-SR-Ingress-Time: 1666379240359 Received: from server.hostname.tld (server.hostname.tld [xxx.xxx.xx.xxx]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384) by xxx.xxx.xxx.xxx (trex/6.7.1); Fri, 21 Oct 2022 19:07:20 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=server.hostname.tld; s=default; h=Content-Type:Mime-Version:To:Subject: Reply-To:Message-Id:From:Date:Sender:Cc:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=xxXXXXxXXXXXX=; b=xXXxxxXXXxXXXxxXXX==; Received: from localhost ([127.0.0.1]:33812 helo=localhost.localdomain) by localhost.localdomain with esmtpa (Exim 4.95) (envelope-from <sender@domain.tld>) id xXxXXxX; Fri, 21 Oct 2022 14:07:18 -0500 Date: Fri, 21 Oct 2022 19:07:18 GMT From: "Sender on domain.tld" <sender@domain.tld> Message-Id: <xXXxxxXX@domain.tld> Reply-To: "Sender on domain.tld" <sender@domain.tld> Subject: [To NTFY] TEST MESSAGE. To: xXxxxxXxxntfy@ntfyserver.tld X-iContact_locale: en Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="mixed-Custom::Email::Object-11233-4555678910-0.123456478946" X-AuthUser: XxxXxxXX@domain.tld --mixed-Custom::Email::Object-xXxxXxxXxxXXX Content-Type: multipart/alternative; boundary="alternative-Custom::Email::Object-xxxxxxxxxxxx" --alternative-Custom::Email::Object-xxxxxxx Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Teste Message =E2=80=9Cto ntfy=E2=80=9D test test test. Text text textText text textText text textText te =E2=80=9Ctexttexttexttext=E2=80=9D texttexttext. mre text text text text text text = text. ..... ..... ............... ..... --alternative-Custom::Email::Object-xxxxxxx Content-Type: multipart/related; boundary="related-Custom::Email::Object-xxxxxxxxxxx" --related-Custom::Email::Object-xxxxxxx Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable Message in HTML FORMAT<body> etc... ... ... ... ... .. ... --related-Custom::Email::Object-xxxxxxx Content-Type: image/png; x-unix-mode=0600; name="image.png" Content-Disposition: attachment; filename="image.png" Content-ID: <auto_cid_xxxxxxx> Content-Transfer-Encoding: base64 base64code= --related-Custom::Email::Object-xxxxxxx-- --alternative-Customl::Email::Object-xxxxxxxx-- --mixed-Custom::Email::Object-xxxxxxxx Content-Type: text/plain; charset="utf-8"; x-unix-mode=0600; name="filename.txt" Content-Disposition: attachment; filename="filename.txt" Content-Transfer-Encoding: base64 base64code== --mixed-Custom::Email::Object-xxxxxxx-- 2022/10/21 19:07:22 TRACE xxx.xx.xxxx HTTP GET /xxxxxxxxxxxxxxxxxxxx/sse Sending keepalive message 2022/10/21 19:07:22 DEBUG xx.xx.xx.xx HTTP POST /xxxxx Dispatching request 2022/10/21 19:07:22 TRACE xx.xx.xx.xx HTTP POST /xxxxx Entire request (headers and body): POST /asgard HTTP/1.1 X-Forwarded-For: xx.xx.xx.xx Title: [To NTFY] TEST MESSAGE. i guess here is base64code ... (peeked 4096 bytes) 2022/10/21 19:07:22 DEBUG xxx.xxx.xxx.xxx/xxx/xxxxx Received message: event=message, body=29516 byte(s), delayed=false, firebase=true, cache=true, up=false, email= 2022/10/21 19:07:22 TRACE xxxxx.xxx.xxx.xx/xxx/xxxx Message body: { "id": "xxxxxxxx", "time": 1666379242, "event": "message", "topic": "xxxxx", "title": "[To NTFY] TEST MESSAGE.", "message": "Iguess is base64 code 2022/10/21 19:07:22 TRACE xxx.xx.xxx.x/xxxxx/xxxxx No stream or WebSocket subscribers, not forwarding 2022/10/21 19:07:22 DEBUG xxx.xx.xxx.x/xxxxx/xxxxx Publishing to Firebase 2022/10/21 19:07:22 TRACE xxx.xx.xxx.x/xxxxx/xxxxx Firebase message: { "topic": "xxxxx", "data": { "click": "", "encoding": "", "event": "message", "icon": "", "id": "xxxxx", "message": "i guess base64 code 2022/10/21 19:07:22 TRACE xxx.xx.xx.xx HTTP GET /xxxxxxxxxxxx/sse Sending keepalive message 2022/10/21 19:07:22 WARN xx.xx.xx.xx/xxxx/XxXXXXxxXX Unable to publish to Firebase: Request contains an invalid argument. ```
Author
Owner

@binwiederhier commented on GitHub (Oct 21, 2022):

So the title says you want the base64, but the excerpt here implies that you'll want the text/plain that's quoted-printable, i.e. this:

--alternative-Custom::Email::Object-xxxxxxx
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable

Teste Message =E2=80=9Cto ntfy=E2=80=9D test test test.

Text text textText text textText text textText te =E2=80=9Ctexttexttexttext=E2=80=9D texttexttext.

mre text text text text text text =
text.
.....
.....
...............
.....

Is this accurate? The base64-encoded multipart parts are attachments.

I gotta say, this multipart parsing is quite annoying and infinitely complex. I am not sure how deep I want to go with this, though I think I'd be able to pull of something that's practicable yet not too annoying to parse.

<!-- gh-comment-id:1287463603 --> @binwiederhier commented on GitHub (Oct 21, 2022): So the title says you want the base64, but the excerpt here implies that you'll want the `text/plain` that's `quoted-printable`, i.e. this: ``` --alternative-Custom::Email::Object-xxxxxxx Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Teste Message =E2=80=9Cto ntfy=E2=80=9D test test test. Text text textText text textText text textText te =E2=80=9Ctexttexttexttext=E2=80=9D texttexttext. mre text text text text text text = text. ..... ..... ............... ..... ``` Is this accurate? The base64-encoded multipart parts are attachments. I gotta say, this multipart parsing is quite annoying and infinitely complex. I am not sure how deep I want to go with this, though I think I'd be able to pull of something that's practicable yet not too annoying to parse.
Author
Owner

@binwiederhier commented on GitHub (Nov 7, 2022):

Closing this due to inactivity. Feel free to reopen.

<!-- gh-comment-id:1305497576 --> @binwiederhier commented on GitHub (Nov 7, 2022): Closing this due to inactivity. Feel free to reopen.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/ntfy#340
No description provided.