Plone api.portal.send_email outputs malformed subject

Hi Plone Community,

I am in the process of getting a custom addon collective.contentrules.mailtorole to work in Plone 6/Volto. I was able to display the email itself. The only issue is that the subject line seems not to display correctly and appears malformed.

Here is the output I am currently getting in the console:

2024-01-29 13:55:19,821 ERROR   [plone.dexterity.schema:186][waitress-0] Error resolving behavior plone.versionable for factory assessment_unit
YAMS Notification: New Items to Review Academic Advisement Center Assessment 
2024-01-29 13:55:19,930 INFO    [PrintingMailHost:101][waitress-0] 
 ---- sending mail ---- 
From: rbrown12@york.cuny.edu
To: ['jsmith@york.cuny.edu']
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Subject: =?utf-8?q?YAMS_Notification=3A_New_Items_to_Review_Academic_Advisement_Cente?=
 =?utf-8?q?r_Assessment_?=
To: jsmith@york.cuny.edu
From: rbrown12@york.cuny.edu
Date: Mon, 29 Jan 2024 13:55:19 -0500

Academic Advisement Center Assessment has been transitioned to Draft.
 ---- done ---- 

And here is the code I was using:

# Prepend interpolated message with \n to avoid interpretation
        # of first line as header.
        message = "\n%s" % interpolator(self.element.message)
        subject = interpolator(self.element.subject)
        print(subject)
        # subject = str(self.element.subject).encode('utf-8', 'ignore')
        for recipient in recipients_mail:
            # mailhost.send(
            #     message, recipient, source, subject=subject,
            #     charset='utf-8'
            # )
            api.portal.send_email(recipient=recipient, sender=source, subject=subject, body=message, immediate=False)
        return True

How can I fix this problem so that the output displays the subject attribute properly?

Thanks in advance,

rbrown12

What is interpolator()?

This is defined in the following line:

interpolator = IStringInterpolator(obj)

And is imported from the following:

from plone.stringinterp.interfaces import IStringInterpolator

Why do you need this?
The Python email package takes care about the proper encoding.

Thank you for your reply. I will take a look at the Python email package and use it instead of using the interpolator. I used this package initially to handle the encoding of the email message.

rbrown12 via Plone Community wrote at 2024-1-29 19:09 +0000:

...
I am in the process of getting a custom addon collective.contentrules.mailtorole to work in Plone 6/Volto. I was able to display the email itself. The only issue is that the subject line seems not to display correctly and appears malformed.
...
Subject: =?utf-8?q?YAMS_Notification=3A_New_Items_to_Review_Academic_Advisement_Cente?=
=?utf-8?q?r_Assessment_?=

This "Subject" is correct:
Unlike the mail body, the mail header lines must contain ASCII only.
To ensure this, mail header values can use an encoding.
The encoding spec is introduced by =?<charset>?<encoding>?
and termiated by ?=.

In the case above, the encoding uses the charset utf-8
and the encoding q (= "Quoted printable").

Mail readers will decode the header values and present the decoded
values.

Thank you for your reply. Is there a reference as to how to setup the correct headers? Thank you.

There is a working example

In general, there is no need to set any headers by yourself unless you have specific needs.

If you are sending mails with multiple parts (text and html), you have to use MIMEText() with a proper configuration. But as stated, there is zero need to encode subject or body text by yourself if the data is of type str aka unicode (in Python 2).