I am testing Amazon SES through boto3 python library. When i send emails i see all the recipient addresses. How to hide these ToAddresses of multiple email via Amazon SES ?
Following is the part of the code
import boto3
client=boto3.client('ses')
to_addresses=["**#**","**#**","**#**",...]
response = client.send_email(
Source=source_email,
Destination={
'ToAddresses': to_addresses
},
Message={
'Subject': {
'Data': subject,
'Charset': encoding
},
'Body': {
'Text': {
'Data': body ,
'Charset': encoding
},
'Html': {
'Data': html_text,
'Charset': encoding
}
}
},
ReplyToAddresses=reply_to_addresses
)
We use the send_raw_email function instead which gives more control over the make up of your message. You could easily add Bcc headers this way.
An example of the code that generates the message and how to send it
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
msg = MIMEMultipart('alternative')
msg['Subject'] = 'Testing BCC'
msg['From'] = 'no-reply#example.com'
msg['To'] = 'user#otherdomain.com'
msg['Bcc'] = 'hidden#otherdomain.com'
We use templating and MIMEText to add the message content (templating part not shown).
part1 = MIMEText(text, 'plain', 'utf-8')
part2 = MIMEText(html, 'html', 'utf-8')
msg.attach(part1)
msg.attach(part2)
Then send using the SES send_raw_email().
ses_conn.send_raw_email(msg.as_string())
Related
How can I put multiple email recipient addresses in my ses instead of
RECIPIENT = "recipient#example.com"
or how to make it read an email list txt file line by line using this:
mylist = open(list.txt,r)
read_me = mylist.readlines()
for i in read_me:
mailist = i.strip()
import boto3
from botocore.exceptions import ClientError
SENDER = "Sender Name <sender#example.com>"
RECIPIENT = "recipient#example.com"
AWS_REGION = "us-west-2"
SUBJECT = "Amazon SES Test (SDK for Python)"
BODY_TEXT = ("Amazon SES Test (Python)\r\n"
"This email was sent with Amazon SES using the "
"AWS SDK for Python (Boto)."
)
BODY_HTML = """<html>
<head></head>
<body>
<h1>Amazon SES Test (SDK for Python)</h1>
<p>This email was sent with
<a href='https://aws.amazon.com/ses/'>Amazon SES</a> using the
<a href='https://aws.amazon.com/sdk-for-python/'>
AWS SDK for Python (Boto)</a>.</p>
</body>
</html>
"""
CHARSET = "UTF-8"
# Create a new SES resource and specify a region.
client = boto3.client('ses',region_name=AWS_REGION)
# Try to send the email.
try:
#Provide the contents of the email.
response = client.send_email(
Destination={
'ToAddresses': [
RECIPIENT,
],
},
Message={
'Body': {
'Html': {
'Charset': CHARSET,
'Data': BODY_HTML,
},
'Text': {
'Charset': CHARSET,
'Data': BODY_TEXT,
},
},
'Subject': {
'Charset': CHARSET,
'Data': SUBJECT,
},
},
Source=SENDER,
# If you are not using a configuration set, comment or delete the
# following line
ConfigurationSetName=CONFIGURATION_SET,
)
# Display an error if something goes wrong.
except ClientError as e:
print(e.response['Error']['Message'])
else:
print("Email sent! Message ID:"),
print(response['MessageId'])
Try passing in array like this:
Recipients = ['Recipient One <recipient_1#email.com>', 'recipient_2#email.com']
or more specifically:
Destination={'ToAddresses': ['recipient_1#email.com', 'recipient_2#email.com']},
I'm trying to set up the gmail api to send emails automatically using google's sample code. When trying to send an email, I receive a 401 error.
I've set up quickstart and given it access to my gmail for all purposes. I can access my account through the API for other purposes, such as retrieving labels, but not sending emails. I've tried deleting and remaking my token several times, and I have set SCOPES to include sending emails and that shows up in my google account.
def create_message(sender, to, subject, message_text):
message = MIMEText(message_text)
message['to'] = to
message['from'] = sender
message['subject'] = subject
return {'raw': base64.urlsafe_b64encode(message.as_bytes())}
with open('token.pickle', 'wb') as token:
creds=pickle.load(token)
service = build('gmail', 'v1', credentials=creds)
results = service.users().labels().list(userId='me').execute()
labels = results.get('labels', [])
print(labels)
#this script works up to here
message = service.users().messages().send(userId='me', body=create_message('myemail#gmail.com', 'testemail#gmail.com', 'Test', '')).execute()
print('Message Id: %s' % message['id'])
print(message)
As expected, the labels print correctly, but I receive the following error for trying to send the message:
HttpError: <HttpError 400 when requesting
https‍://www.googleapis.com/gmail/v1/users/me/messages/send?alt=json returned "'raw' RFC822 payload message string or uploading message via /upload/* URL required">
which leads to:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "required",
"message": "Login Required",
"locationType": "header",
"location": "Authorization"
}
],
"code": 401,
"message": "Login Required"
}
}
I want use multiple aws ses account in one django project...
for some customers, the email must sent from one account and the remaining users must get emails from another account..
You can use boto3 and connect to AWS using different credentials.
Install the boto3 package.
pip install boto3
Then connect to your AWS account and send an email (or more).
import boto3
from botocore.exceptions import ClientError
SENDER = "Sender Name <sender#example.com>"
RECIPIENT = "recipient#example.com"
CONFIGURATION_SET = "ConfigSet"
SUBJECT = "Amazon SES Test (SDK for Python)"
BODY_TEXT = ("Test")
BODY_HTML = """<html><head></head><body><h1>Test</h1></body></html>"""
CHARSET = "UTF-8"
ACCESS_KEY = 'foo'
SECRET_KEY = 'foo'
SESSION_TOKEN = 'foo'
client = boto3.client(
'ses',
region_name="us-west-2",
aws_access_key_id=ACCESS_KEY,
aws_secret_access_key=SECRET_KEY,
aws_session_token=SESSION_TOKEN,
)
try:
response = client.send_email(
Destination={
'ToAddresses': [
RECIPIENT,
],
},
Message={
'Body': {
'Html': {
'Charset': CHARSET,
'Data': BODY_HTML,
},
'Text': {
'Charset': CHARSET,
'Data': BODY_TEXT,
},
},
'Subject': {
'Charset': CHARSET,
'Data': SUBJECT,
},
},
Source=SENDER,
# If you are not using a configuration set, comment or delete the
# following line
ConfigurationSetName=CONFIGURATION_SET,
)
# Display an error if something goes wrong.
except ClientError as e:
print(e.response['Error']['Message'])
else:
print("Email sent! Message ID:"),
print(response['MessageId'])
Sources:
https://docs.aws.amazon.com/ses/latest/DeveloperGuide/send-using-sdk-python.html
https://boto3.readthedocs.io/en/latest/guide/quickstart.html#installation
I'm trying to send an image with a facebook bot. I can send text fine, but whenever I try to send a message I get an error: TypeError: open file 'plot.jpg', mode 'rb' at 0x7f34a2fe8b70 is not JSON serializable. I'm using flask and heroku for the bot if that makes a difference.
This is my code:
def send_message(recipient_id, message_text):
log("sending message to {recipient}: {text}".format(recipient=recipient_id, text=message_text))
params = {
"access_token": os.environ["PAGE_ACCESS_TOKEN"]
}
headers = {
"Content-Type": "application/json"
}
log(os.getcwd())
data = json.dumps({
'recipient': {
'id': recipient_id
},
'message': {
'attachment': {
'type': 'image',
'payload': {}
}
},
'filedata': (os.path.basename('plot.jpg'), open('plot.jpg', 'rb'))
})
r = requests.post("https://graph.facebook.com/v2.6/me/messages", params=params, headers=headers, data=data)
if r.status_code != 200:
log(r.status_code)
log(r.text)
I got the same issue and i solved it by using multipart/form-data, instead of encoding the entire payload using json.dumps() you can use the MultipartEncoder from requests-toolbelt-0.8.0 to multipart encode the payload.
Note - Facebook's Graph API is accepting only png images for some unknown reasons, in the below example i've used a png file.
*Edited the code(redundant end parenthesis)
import json
import requests
from requests_toolbelt import MultipartEncoder
def send_message(recipient_id, message_text):
log("sending message to {recipient}: {text}".format(recipient=recipient_id, text=message_text))
params = {
"access_token": os.environ["PAGE_ACCESS_TOKEN"]
}
log(os.getcwd())
data = {
# encode nested json to avoid errors during multipart encoding process
'recipient': json.dumps({
'id': recipient_id
}),
# encode nested json to avoid errors during multipart encoding process
'message': json.dumps({
'attachment': {
'type': 'image',
'payload': {}
}
}),
'filedata': (os.path.basename('plot.png'), open('plot.png', 'rb'), 'image/png')
}
# multipart encode the entire payload
multipart_data = MultipartEncoder(data)
# multipart header from multipart_data
multipart_header = {
'Content-Type': multipart_data.content_type
}
r = requests.post("https://graph.facebook.com/v2.6/me/messages", params=params, headers=multipart_header, data=multipart_data)
if r.status_code != 200:
log(r.status_code)
log(r.text)
I am trying to use Outlook's REST API in my python code to send an email in behalf of a user who already gives me his consent.
I was able to successfully send text emails using their /me/sendmail node with the following payload:
email_payload = {
"Message": {
"Subject": email_subject,
"Body": {
"ContentType": "Text",
"Content": email_body
},
"ToRecipients": [
{
"EmailAddress": {
"Address": to
}
}
]
}
}
However, when trying to add attachments (based on their documentation), I encounter some issues:
email_payload["Message"]["Attachments"] = [
{
"ContentType": "application/pdf",
"Name": "{0}".format("something.pdf"),
"ContentBytes": base64.b64encode(attachment.read())
}
]
Issues consist in 415 response status code with the following content:
{u'error': {u'message': u'A missing or empty content type header was found when trying to read a message. The content type header is required.', u'code': u'RequestBodyRead'}}
Couldn't find anything regarding this in their documentation. Hope somebody can enlighten me :)
For anyone else having such issues, here's the context and fix:
Initially, since I was sending only plain-text emails, my request header looked like this:
request_headers = {
'Authorization': "Bearer {0}".format(token),
}
And the actual request:
api_response = requests.post(
request_url,
json.dumps(body),
headers=request_headers
)
As you might have noticed I wasn't sending any content-type in my headers (not sure why), but everything went well so far up until when I decided to add attachments too.
Seems like if my request_headers would contain Content-Type too, everything would go well:
request_headers = {
'Authorization': 'Bearer {0}'.format(refreshed_token),
'Content-Type': 'application/json'
}