@@ -35,9 +35,73 @@ defmodule TempMail.SMTPServer do
35
35
36
36
def handle_DATA ( from , to , data , state ) do
37
37
Logger . info ( "handle_DATA, Received email from #{ from } to #{ Enum . join ( to , ", " ) } " )
38
- TempMail.EmailStore . store_email ( from , to , data )
39
- { :ok , "250 ok" , state }
38
+
39
+ case :mimemail . decode ( data ) do
40
+ { "text" , subtype , headers , params , body } ->
41
+ # Simple text email without attachments
42
+ email_content = % {
43
+ from: from ,
44
+ to: to ,
45
+ subject: get_subject ( { nil , nil , headers , params , nil } ) ,
46
+ body: body ,
47
+ attachments: [ ]
48
+ }
49
+ Logger . debug ( "email_content: #{ inspect ( email_content ) } " )
50
+ TempMail.EmailStore . store_email ( from , to , data , email_content . subject , email_content . body )
51
+ { :ok , "250 ok" , state }
52
+
53
+ { _type , _subtype , headers , params , parts } = email ->
54
+ # Email with potential attachments
55
+ attachments = extract_attachments ( email )
56
+ email_content = % {
57
+ from: from ,
58
+ to: to ,
59
+ subject: get_subject ( email ) ,
60
+ body: get_text_body ( email ) ,
61
+ attachments: attachments
62
+ }
63
+ { :ok , "250 ok" , state }
64
+
65
+ error ->
66
+ { :error , "554 Error: Unable to process email" , state }
67
+ end
68
+ end
69
+
70
+ defp extract_attachments ( { _type , _subtype , _headers , _params , parts } ) when is_list ( parts ) do
71
+ Enum . flat_map ( parts , fn
72
+ { "text" , _subtype , _headers , _params , _content } ->
73
+ [ ]
74
+ { _type , _subtype , headers , params , content } ->
75
+ case :proplists . get_value ( "Content-Disposition" , headers ) do
76
+ disposition when is_binary ( disposition ) ->
77
+ if String . starts_with? ( disposition , "attachment" ) do
78
+ [ % {
79
+ filename: :proplists . get_value ( "filename" , params ) ,
80
+ content: Base . encode64 ( content ) ,
81
+ content_type: :proplists . get_value ( "Content-Type" , headers )
82
+ } ]
83
+ else
84
+ [ ]
85
+ end
86
+ _ ->
87
+ [ ]
88
+ end
89
+ end )
90
+ end
91
+ defp extract_attachments ( _ ) , do: [ ]
92
+
93
+ defp get_subject ( { _type , _subtype , headers , _params , _parts } ) do
94
+ :proplists . get_value ( "Subject" , headers , "" )
95
+ end
96
+
97
+ defp get_text_body ( { _type , _subtype , _headers , _params , parts } ) when is_list ( parts ) do
98
+ Enum . find_value ( parts , fn
99
+ { "text" , "plain" , _headers , _params , content } -> content
100
+ _ -> nil
101
+ end ) || ""
40
102
end
103
+ defp get_text_body ( { "text" , "plain" , _headers , _params , content } ) , do: content
104
+ defp get_text_body ( _ ) , do: ""
41
105
42
106
def handle_RSET ( state ) do
43
107
{ :ok , state }
0 commit comments