snoyberg / mime-mail Goto Github PK
View Code? Open in Web Editor NEWCompose MIME email messages.
Compose MIME email messages.
I install 0.3.0 successfully (and that is a satisfactory workaround for me). Here is the build failure I get on 0.3.0.1
Resolving dependencies...
Configuring mime-mail-0.3.0.1...
Preprocessing library mime-mail-0.3.0.1...
Building mime-mail-0.3.0.1...
[1 of 1] Compiling Network.Mail.Mime ( Network/Mail/Mime.hs, dist/build/Network/Mail/Mime.o )
Network/Mail/Mime.hs:312:13: Not in scope: `Base64.encodeInc'
Network/Mail/Mime.hs:314:38:
Not in scope: data constructor `Base64.EDone'
Network/Mail/Mime.hs:315:13:
Not in scope: data constructor `Base64.EFinal'
Network/Mail/Mime.hs:316:50:
Not in scope: data constructor `Base64.EChunk'
Network/Mail/Mime.hs:317:13:
Not in scope: data constructor `Base64.EPart'
cabal: Error: some packages failed to install:
mime-mail-0.3.0.1 failed during the building phase. The exception was:
ExitFailure 1
We've been running into issues where the 'to' header is incorrectly encoded. We create 'to' fields of the form 'Name ', but when Name contains 'special' characters, the address is transformed into something like this:
=?utf-8?Q?Danilo_H=C3=A4rtzer_?=: malformed address: ?= may not follow =?utf-8?Q?Danilo_H=C3=A4rtzer_
Reading the spec (RFC 2407), this should be turned into:
=?utf-8?Q?Danilo_H=C3=A4rtzer?=
So the email part should not be inside the =?...?= block. What would be a good way to fix this? Currently, there is no data type for mail messages separating the 'name' from the 'email address'. Introducing something like that seems like a good solution to me.
Is this an omission, or by design?
It's type signature would be like this:
sendMailSES' :: MonadIO m => SES -> ByteString -> m ()
It would be using global manager from the http-client-tls
package.
Motivation: I'm internally using this function in several of my Yesod apps.
I can send a PR if there is no objections.
it would be great, if there was a function that constructs a mail with only plain parts. i'd also like to expose the content type names, as well as the addAttachments
part simpleMail
.
would you incorporate a patch that adds the following functions (of course i am more than open for other names)?
-- | simpleMail' from to subject plainTextBody
simpleMail' :: Address -> Address -> Text -> Text -> Mail
addAttachment :: Text -> FilePath -> Mail -> IO Mail
addAttachments :: [(Text, FilePath)] -> Mail -> IO Mail
plainPart :: Text -> Part
htmlPart :: Text -> Part
addPart :: Alternative -> Mail -> Mail
Hi,
I had some issues with mail being truncated for what looked like no reason at all. Digging deeper I found the following problem.
Network.Mail.Mime
inserts newlines whenever lines are getting too long. This
however can results in a .
ending up on a single line signaling sendmail
the end of
the mail and discards whatever text might follow.
{-# LANGUAGE OverloadedStrings #-}
module Bug where
import Prelude hiding (putStrLn)
import Network.Mail.Mime
import Data.ByteString.Lazy.Char8 (putStrLn)
mail =
simpleMail'
(Address Nothing "[email protected]")
(Address Nothing "[email protected]")
"Subject"
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxöxxxxxxxxxxxxxxxxxxöxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxöxxxxxxxxxxxxxxxxxxxxxxxxxxxxöxxxxx.\n"
test :: IO ()
test = renderMail' mail >>= putStrLn
This code results in the following mail:
From: <[email protected]>
To: <[email protected]>
Subject: Subject
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=C3=B6xxxxxxxxxxxxxxxxxx=C3=B6xxxxxxxx=
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=C3=B6xxxxxxxxxxxxxxxxxxxxxxxxxxxx=C3=B6xxxxx=
.
In my case there was still text after the newline which then got cut off. As a current workaround I'm inserting newlines myself to suppress this effect but this is quite unfortunate since adding special characters like those above might lead to longer lines than expected, triggering this behavior in unexpected situations.
Kind regards,
raichoo
My emails are getting rerouted to the sender. Take a look:
Delivered-To: [email protected]
Received: by 10.194.82.198 with SMTP id k6csp25773wjy;
Sat, 20 Jul 2013 14:51:40 -0700 (PDT)
X-Received: by 10.236.174.199 with SMTP id x47mr11231340yhl.257.1374357100389;
Sat, 20 Jul 2013 14:51:40 -0700 (PDT)
Return-Path: <0000013ffe1112c2-31a3825e-b1a3-4b2c-a4b9-9b28aeca18d4-000000@amazonses.com>
Received: from a8-23.smtp-out.amazonses.com (a8-23.smtp-out.amazonses.com. [54.240.8.23])
by mx.google.com with ESMTP id 27si9112636yhd.334.2013.07.20.14.51.40
for <[email protected]>;
Sat, 20 Jul 2013 14:51:40 -0700 (PDT)
Received-SPF: pass (google.com: domain of 0000013ffe1112c2-31a3825e-b1a3-4b2c-a4b9-9b28aeca18d4-000000@amazonses.com designates 54.240.8.23 as permitted sender) client-ip=54.240.8.23;
Authentication-Results: mx.google.com;
spf=pass (google.com: domain of 0000013ffe1112c2-31a3825e-b1a3-4b2c-a4b9-9b28aeca18d4-000000@amazonses.com designates 54.240.8.23 as permitted sender) smtp.mail=0000013ffe1112c2-31a3825e-b1a3-4b2c-a4b9-9b28aeca18d4-000000@amazonses.com
Return-Path: 0000013ffe1112c2-31a3825e-b1a3-4b2c-a4b9-9b28aeca18d4-000000@amazonses.com
From: =?utf-8?Q?FromMitch?= <[email protected]>
To: <[email protected]>
Subject: test subject
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary="p1q987GPEX"
Date: Sat, 20 Jul 2013 21:51:39 +0000
Message-ID: <0000013ffe1112c2-31a3825e-b1a3-4b2c-a4b9-9b28aeca18d4-000000@email.amazonses.com>
X-SES-Outgoing: 2013.07.20-54.240.8.23
--p1q987GPEX
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
test plain body
--p1q987GPEX
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: quoted-printable
<h1>test body</h1>
--p1q987GPEX--
Notice the To and the Delivered-To are different. I can sen emails to other recipients fine using the SES console. Is this an issue with the library?
bcc is ignored by email server and is being instead sent in email header to main recipients.
Here's the part of the raw message:
To: [email protected]
Bcc: [email protected]
Subject: Test bcc 2
MIME-Version: 1.0
X-ASG-Orig-Subj: Test bcc 2
Content-Type: text/html; charset=utf-8
Quoted printed produces lines longer than 76 chars
Here's the header from the broken email:
X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.2.129166
Rule breakdown below
pts rule name description
---- ---------------------- --------------------------------------------------
0.00 NO_REAL_NAME From: does not include a real name
0.00 MIME_HTML_ONLY BODY: Message only has text/html MIME parts
0.00 HTML_MESSAGE BODY: HTML included in message
0.00 MIME_QP_LONG_LINE RAW: Quoted-printable line longer than 76 chars
0.82 MIME_QP_LONG_LINE_2 RAW: Quoted-printable line longer than 76 chars
Most of the lines in the broken email are 80 chars long with a few 79 or 82 chars long.
See the following cabal repl
session:
> renderMail' (emptyMail (Address Nothing "Hello")) { mailParts = [ [ plainPart "Hello" ] ] }
"From: <Hello>\nMIME-Version: 1.0\nContent-Type: text/plain; charset=utf-8\nContent-Transfer-Encoding: quoted-printable\n\nHello"
> renderMail' (emptyMail (Address Nothing "Hello")) { mailParts = [ [ htmlPart "Hello" ] ] }
"From: <Hello>\nMIME-Version: 1.0\nContent-Type: text/html; charset=utf-8\nContent-Transfer-Encoding: quoted-printable\n\nHello"
> renderMail' (emptyMail (Address Nothing "Hello")) { mailParts = [ [ plainPart "Hello", htmlPart "<html>" ] ] }
"*** Exception: renderParts called with null parts
Oddly this doesn't happen in our actual web server, which is happily sending multi-part emails
What is the proper way to set the Content-ID for an attachment using this library? I want to refer to the attachment from the html content of the mail.
I can do this by modifying the headers in the alternatives field of the Mail. But I am looking for a high level api for doing things like this.
It would be much nicer if we could get error handling "out of the box", rather than having to try/catch. It's also not documented that sendMailCustom
is partial.
The mime-mail-ses
package currently uses Signature Version 3, as can be seen by the string "AWS3-HTTPS" in the X-Amzn-Authorization
header [1]. Starting 1 October 2020, AWS SES will require clients to use Signature Version 4 [2].
Unless fixed until then, the sendMailSES
function will no longer work.
[1] https://www.stackage.org/haddock/lts-16.5/mime-mail-ses-0.4.1/src/Network.Mail.Mime.SES.html#sendMailSES
[2] https://docs.aws.amazon.com/ses/latest/DeveloperGuide/using-ses-api-authentication.html
It seems like the implementation doesn't respect the character limit on encoded-words
specified in RFC-2047.
The following example string is 139 characters:
"This \"encoded-word\" is longer than 75 characters which is not allowed according to RFC-2047 (https://tools.ietf.org/html/rfc2047#section-2)"
It results in the following encoded-word
representation:
=?utf-8?Q?This_=22encoded-word=22_is_longer_than_75_characters_which_is_not_allowed_according_to_RFC-2047_=28https=3A//tools=2Eietf=2Eorg/html/rfc2047#section-2=29?=
As I read it the RFC requires the following (I included a field identifier because I believe it's included in the count):
To: =?utf-8?Q?This_=22encoded-word=22_is_longer_than_75_characters_which_?=
=?utf-8?Q?is_not_allowed_according_to_RFC-2047_=28https=3A//tools=2Eietf?=
=?utf-8?Q?=2Eorg/html/rfc2047#section-2=29?=
causes malformed From:
and To:
headers:
From: =?utf-8?Q?help?=<[email protected]>\nTo: =?utf-8?Q?max_lev?=<[email protected]>
should be
From: =?utf-8?Q?help?= <[email protected]>\nTo: =?utf-8?Q?max_lev?= <[email protected]>
note the spaces after the Q encodings
I'm using the mime-mail-ses
package and I need to send mail from regions other than us-east-1
.
I have made a simple patch in my own fork and I wanted to get your thoughts:
diff --git a/mime-mail-ses/Network/Mail/Mime/SES.hs b/mime-mail-ses/Network/Mail/Mime/SES.hs
index 3018922..92bdf18 100644
--- a/mime-mail-ses/Network/Mail/Mime/SES.hs
+++ b/mime-mail-ses/Network/Mail/Mime/SES.hs
@@ -4,6 +4,7 @@ module Network.Mail.Mime.SES
( sendMailSES
, renderSendMailSES
, SES (..)
+ , SESRegion (..)
) where
import Control.Exception (Exception, throwIO)
@@ -37,8 +38,14 @@ data SES = SES
, sesTo :: [ByteString]
, sesAccessKey :: ByteString
, sesSecretKey :: ByteString
+ , sesRegion :: SESRegion
}
+data SESRegion = USEast -- * Virginia
+ | USWest -- * Oregon
+ | EUWest -- * Ireland
+ deriving Show
+
renderSendMailSES :: MonadIO m => Manager -> SES -> Mail -> m ()
renderSendMailSES m ses mail = liftIO (renderMail' mail) >>= sendMailSES m ses
@@ -47,7 +54,10 @@ sendMailSES manager ses msg = liftIO $ do
now <- getCurrentTime
let date = S8.pack $ format now
sig = makeSig date $ sesSecretKey ses
- req' <- parseUrl "https://email.us-east-1.amazonaws.com"
+ req' <- parseUrl $ case sesRegion ses of
+ USEast -> "https://email.us-east-1.amazonaws.com"
+ USWest -> "https://email.us-west-2.amazonaws.com"
+ EUWest -> "https://email.eu-west-1.amazonaws.com"
let auth = S8.concat
[ "AWS3-HTTPS AWSAccessKeyId="
, sesAccessKey ses
It would also make sense to add a simple Text field to SES
which would allows the user to manually enter the string of the region (e.g. 'sesRegion = '"us-east-1"')
Let me know if either of these solutions is acceptable and I can submit a pull request if this is something you want to support in mime-mail-ses
.
Thanks!
When sending an email with an attachment with the filename "test hello.txt"
I get the error:
*** Exception: SESException {seStatus = Status {statusCode = 400, statusMessage = "Bad Request"}, seCode = "InvalidParameterValue", seMessage = "Expected ';', got \"hello.txt\"", seRequestId = "a5b13731-300e-11e8-9a7a-a3641b570f3f"}
This is probably because the filename is not quoted when rendering the email. When I quote the filename myself "\"test hello.txt \""
it works.
I think it would make sense to quote the filename when rendering the mail. I can send a pull request if you agree?
Arch Linux just changed the exim package to move sendmail from /usr/sbin to /usr/bin
https://projects.archlinux.org/svntogit/community.git/commit/trunk?h=packages/exim&id=b5ba05c445f1f573af37487931b14c2b7d6cee37
This causes the sendmail function in mime-mail to error since it can't find the sendmail binary. I temporarilly fixed this by just passing "sendmail" to sendmailCustom since the proc function searches the path if no leading slash is found. But since usually /usr/sbin is not on the path, it means my code will break on other distributions.
One possibility is no change to mime-mail package; I could test /usr/sbin/sendmail to see if it existed and if not pass "sendmail" to sendmailCustom so my code works in all situtations. But this bug might bite other people using the package and maybe it should be fixed inside mime-mail. Thoughts?
The default for development mode should be to print the email message out to the logger. This works very well and lets you not worry about errantly sending email.
When this is done I will hook up the Yesod scaffolding to it.
Would it be possible to add the following IsString
instance for Address
:
instance IsString Address where
fromString str = Address Nothing (fromString str)
If the above instance is okay then I can submit a pull request to add this
Hey,
Thanks for maintaining Mime Mail! I think in the lines of #38, Mail
(https://hackage.haskell.org/package/mime-mail-0.5.0/docs/Network-Mail-Mime.html) should have an Eq instance. Primarily for testing purposes. Adding one via an orphan instance works as a work-around till then.
Thanks in advance!
I sent a mail by using this code.
But the received mail has wrong characters like as below.
文字化けについてのテス�ƒ ˆ.
^^^^^^^^^^^
here is wrong. corrent is "テスト"
use mime-mail-0.4.2
regards
This is more of a feature request/API change. For some reason, SES sometimes doesn't actually send emails out and presumably I actually get an error message back. sendMailSES
only returns m (), so I can't find out if something went wrong and make adjustments. So I simply copied this Network.Mime.Mail.SES source code and made the very small modification where I actually get a m (Response ByteString)
returned, and started using that file instead.
So I wonder why didn't you make it that way by default? One can always discard the result anyway. Thanks!
I think it would be very handy to have a function that does exactly the opposite action of the renderAddress
function. So you give the function an email address (format specified in RFC5322) and the function spits out an Address
value.
parseEmailAddress :: ByteString -> Maybe Address
parseEmailAddress email =
-- function body
Application:
parseEmailAddress "Jon Doe <jon.doe.mail.com>" -- Just (Address (Just "John Doe") "[email protected]")
parseEmailAddress "[email protected]" -- Just (Address Nothing "[email protected]")
parseEmailAddress "jon" -- Nothing
I can't write this function myself as I am new to Haskell.
I need embed images in an email, and it seems as if the proper way to do this is through a multipart/related
block; multipart/mixed
sort of works, except that the images get shown as attachments in some mail clients.
Before I start burning a bunch of time on this, let me ask the following questions:
Thanks
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.