fix(email): use RFC to save inbound attachments into execution runtime
linuztx committed
Mar 23, 2026 at 13:03 UTC
42487055f3907720acfbb79e93608fba589f0f9e
2 files changed
+50
-2
plugins/_email_integration/helpers/attachment_writer.py
new
+36
@@ -0,0 +1,36 @@
1
+"""
2
+Write attachment files into execution runtime.
3
+
4
+No agent/tool dependencies.
5
+"""
6
+
7
+import base64
8
+import os
9
+from typing import TypedDict
10
+
11
+
12
+# ------------------------------------------------------------------
13
+# Data models
14
+# ------------------------------------------------------------------
15
+
16
+class WriteResult(TypedDict):
17
+ path: str
18
+ error: str
19
+
20
+
21
+# ------------------------------------------------------------------
22
+# File writer
23
+# ------------------------------------------------------------------
24
+
25
+def write_attachment(rel_path: str, content_b64: str) -> WriteResult:
26
+ try:
27
+ from helpers import files
28
+ abs_path = files.get_abs_path(rel_path)
29
+ files.make_dirs(abs_path)
30
+
31
+ content = base64.b64decode(content_b64)
32
+ files.write_file_bin(abs_path, content)
33
+
34
+ return WriteResult(path=abs_path, error="")
35
+ except Exception as e:
36
+ return WriteResult(path="", error=str(e))
\ No newline at end of file
plugins/_email_integration/helpers/imap_client.py
+14
-2
@@ -412,8 +412,20 @@ async def _save_attachment(filename: str, content: bytes, download_folder: str)
412
name, ext = os.path.splitext(filename)
413
unique = f"{name}_{uuid.uuid4().hex[:8]}{ext}"
414
rel_path = os.path.join(download_folder, unique)
415
- files.write_file_bin(rel_path, content)
416
- return files.get_abs_path(rel_path)
415
+ from helpers import runtime
416
+ from plugins._email_integration.helpers.attachment_writer import write_attachment
417
+
418
+ import base64
419
+ content_b64 = base64.b64encode(content).decode()
420
+
421
+ result = await runtime.call_development_function(
422
+ write_attachment, rel_path, content_b64
423
+ )
424
+ if result.get("error"):
425
+ from helpers.print_style import PrintStyle
426
+ PrintStyle.error(f"Failed to save attachment {filename}: {result['error']}")
427
+
428
+ return result.get("path", files.get_abs_path(rel_path))
429
430
431
def _decode_header(header: str) -> str: