python-sparkpost icon indicating copy to clipboard operation
python-sparkpost copied to clipboard

SparkPost.transmissions.send is ignoring CC: and BCC: if recipient list ID is provided

Open dgoldenberg-audiomack opened this issue 2 years ago • 1 comments

My test code sends out email messages as intended to the given recipient list but appears to completely ignore the CC: and BCC: addresses. (Unless there's something wrong in the below invocation?)

SDK version: 1.3.10

Code:

from sparkpost import SparkPost
sp = SparkPost("1234..........6789")
response = sp.transmissions.send(
    use_sandbox=False,
    recipient_list="acme-test-recipient-list",
    html="<html><body><p>This is a test email notif; please ignore.</p></body></html>",
    from_email="[email protected]",
    subject="Test email message; please ignore",
    bcc=["[email protected]", "[email protected]"],
    reply_to="[email protected]",
)
print(response)

From debugging, I can tell the field is making it into the payload but doesn't appear to be used (email doesn't get sent to the CC: or BCC: addresses)

{
	"bcc": ["[email protected]", "[email protected]"],
	"content": {
		"from": {
			"email": "[email protected]"
		},
		"reply_to": "[email protected]",
		"subject": "Test email message; please ignore",
		"html": "<html><body><p>This is a test email notif; please ignore.</p></body></html>"
	},
	"options": {
		"sandbox": false
	},
	"recipients": {
		"list_id": "acme-test-recipient-list"
	}
}

Responses look like this:

{
	'total_rejected_recipients': 0,
	'total_accepted_recipients': 2,
	'id': '7204854351104320440'
}

(Of note: I have tried supplying CC or BCC as a string vs. list, and a single value vs. multiple values, to no avail so far)

Any idea as to why this is happening? A workaround? Thanks.

dgoldenberg-audiomack avatar Feb 27 '23 15:02 dgoldenberg-audiomack

I can tell that the SparkPost SDK only looks at CC and BCC if it's being given a dictionary of recipients; if it's given a recipient list ID, it'll ignore the CC and the BCC.

        :param list|dict recipients: List of email addresses, or a dict:
            ``{'address': {'name': 'Kyla', 'email': '[email protected]' }}``
        :param str recipient_list: ID of recipient list. If this is set,
            the `recipients` param will be ignored
.......
        if recipients and not isinstance(recipients, dict):
            model['recipients'] = self._extract_recipients(recipients)
            recipients = model['recipients']

            cc = model.pop('cc', None)
            if cc:
                headers = content.setdefault('headers', {})
                headers['CC'] = ','.join(cc)
                cc_copies = self._format_copies(recipients, cc)
                recipients.extend(cc_copies)

            bcc = model.pop('bcc', None)
            if bcc:
                bcc_copies = self._format_copies(recipients, bcc)
                recipients.extend(bcc_copies)

These lines of code aren't executed b/c recipient list ID is treated as a dict so they bypass that chunk of code. The CC/BCC are still part of the payload but is apparently ignored.

dgoldenberg-audiomack avatar Feb 27 '23 15:02 dgoldenberg-audiomack