multiple recipients email list for AWS SES python sdk - python

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']},

Related

How to authenticate against an AWS Cognito User Pool in Python?

I have a static serverless website that allows authentication with Javascript using an AWS Cognito User Pool.
Now I'm trying to enable some programmatic access so I need to do this same authentication via a Python script. Is this possible? The docs don't provide any code examples for Python.
I'm just trying to find some way for Python to issue a GET or POST request against an AWS URL, passing it a username and login, and getting back the signed cookies verifying authentication.
The closest example I've found is this code, which references the cognito-idp API. I've modified to:
import boto3
client_id = '<my_app_client_id>'
region_name = 'us-east-1'
auth_data = { 'USERNAME':'myusername' , 'PASSWORD':'mypassword' }
provider_client = boto3.client('cognito-idp', region_name=region_name)
resp = provider_client.initiate_auth(AuthFlow='USER_PASSWORD_AUTH', AuthParameters=auth_data, ClientId=client_id)
print('resp:', resp)
However, even though I use the same credentials as through the Javascript API, this fails to authenticate and simply returns the error:
botocore.exceptions.NoCredentialsError: Unable to locate credentials
This this the correct Python equivalent as the Javascript Cognito API?
The following snippet shows a complete authentication workflow with Cognito using boto3.
def get_secret_hash(username):
msg = username + CLIENT_ID
dig = hmac.new(
str(CLIENT_SECRET).encode('utf-8'),
msg=str(msg).encode('utf-8'),
digestmod=hashlib.sha256
).digest()
d2 = base64.b64encode(dig).decode()
return d2
def initiate_auth(client, username, password):
secret_hash = get_secret_hash(username)
try:
resp = client.admin_initiate_auth(
UserPoolId=USER_POOL_ID,
ClientId=CLIENT_ID,
AuthFlow='ADMIN_NO_SRP_AUTH',
AuthParameters={
'USERNAME': username,
'SECRET_HASH': secret_hash,
'PASSWORD': password,
},
ClientMetadata={
'username': username,
'password': password, })
except client.exceptions.NotAuthorizedException:
return None, "The username or password is incorrect"
except client.exceptions.UserNotConfirmedException:
return None, "User is not confirmed"
except Exception as e:
return None, e.__str__()
return resp, None
#app.route('/auth/login', methods=['POST'])
def login():
event = auth.current_request.json_body
client = boto3.client('cognito-idp')
username = event['username']
password = event['password']
for field in ["username", "password"]:
if event.get(field) is None:
return {"error": True,
"success": False,
"message": f"{field} is required",
"data": None}
resp, msg = initiate_auth(client, username, password)
if msg != None:
return {'message': msg,
"error": True, "success": False, "data": None}
if resp.get("AuthenticationResult"):
return {'message': "success",
"error": False,
"success": True,
"data": {
"id_token": resp["AuthenticationResult"]["IdToken"],
"refresh_token": resp["AuthenticationResult"]["RefreshToken"],
"access_token": resp["AuthenticationResult"]["AccessToken"],
"expires_in": resp["AuthenticationResult"]["ExpiresIn"],
"token_type": resp["AuthenticationResult"]["TokenType"]
}}
else: # this code block is relevant only when MFA is enabled
return {"error": True,
"success": False,
"data": None, "message": None}
Here's the important part parsed from the functions.
resp = client.admin_initiate_auth(
UserPoolId=USER_POOL_ID,
ClientId=CLIENT_ID,
AuthFlow='ADMIN_NO_SRP_AUTH',
AuthParameters={
'USERNAME': username,
'SECRET_HASH': secret_hash,
'PASSWORD': password,
},
ClientMetadata={
'username': username,
'password': password, })
The examples were taken from a four part tutorial that unfortunately didn't help me integrate this with the Chalice CognitoUserPoolAuthorizer but otherwise seems to work well. Here are the tutorials if you can't find better code examples.
part 1
part 2
part 3
part 4
Pass the access and secret key to boto3 like this.
provider_client = boto3.client('cognito-idp', region_name=region_name, aws_access_key_id=AWS_ACCESS_KEY_ID,
aws_secret_access_key=AWS_SECRET_ACCESS_KEY)

Use twitter api to send direct messages using python

I am developing a python script to send direct messages to anyone on twitter using python.For that i am using twitter api but i dont know how to that.If anybody knows any method please help me.
See TwitterAPI
from TwitterAPI import TwitterAPI
import json
api = TwitterAPI(<consumer key>,
<consumer secret>,
<access token key>,
<access token secret>)
user_id = <user id of the recipient>
message_text = <the DM text>
event = {
"event": {
"type": "message_create",
"message_create": {
"target": {
"recipient_id": user_id
},
"message_data": {
"text": message_text
}
}
}
}
r = api.request('direct_messages/events/new', json.dumps(event))
print('SUCCESS' if r.status_code == 200 else 'PROBLEM: ' + r.text)

Gmail API throws 401: error login required only for sending emails

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"
}
}

Is it possible to use multiple aws ses account in django project?

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

Amazon SES - Hide recipient email addresses

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())

Categories

Resources