Il est nécessaire d'envoyer régulièrement des e-mails à plusieurs destinataires dans l'entreprise, et jusqu'à présent, Gmail était envoyé de manière pacifique avec tableur + GAS. Mais! Les spécifications ont changé dans le système d'envoi de courrier interne! (Système de prévention de transmission d'erreur) En conséquence, la feuille de calcul + GAS Gmail ne fonctionne parfois pas: sanglot: Wow Gmail n'est pas bon, envoyez un autre e-mail ... OK, allons à Amazon SES!
Tout d'abord, SES du Boto3 Official Document Vérifiez /latest/reference/services/ses.html).
Hmmm, ce serait bien d'utiliser send_email (** kwargs)
ou send_raw_email (** kwargs)
.
La différence est que send_raw_email (** kwargs)
vous permet de spécifier des en-têtes et de joindre des fichiers.
Au contraire, send_email (** kwargs)
ne correspond pas à ce côté, mais c'est simple.
Je veux joindre un fichier, mais cette fois je veux l'implémenter rapidement pour que je puisse envoyer du courrier rapidement, alors allons-y avec send_email (** kwargs)
.
Tout d'abord, lisez ses avec Boto3
import boto3
client = boto3.client('ses',
aws_access_key_id = accesskey,
aws_secret_access_key = secretkey,
region_name = region
)
Envoyer avec send_email (** kwargs)
client.send_email(
Source = '[email protected]',
Destination = {
'ToAddresses': [
'[email protected]',
]
},
Message = {
'Subject': {
'Data': 'E-mail test',
'Charset': 'UTF-8'
},
'Body': {
'Text': {
'Data': 'Corps de test',
'Charset': 'UTF-8'
}
}
}
)
Très bien, les bases sont OK. Ensuite, je vais le réécrire en quelque chose qui peut réellement être utilisé.
Remarque: Amazon SES nouvellement créé a des fonctions limitées et vous devez enregistrer l'adresse e-mail à utiliser à l'avance.
Pour plus d'informations, consultez la [Foire aux questions sur Amazon SES] officielle (https://aws.amazon.com/jp/ses/faqs/) Q: Qu'est-ce que Amazon SES Sandbox?
S'il te plait donne moi.
J'ai confirmé qu'il peut être envoyé avec succès avec send_email (** kwargs)
, donc je vais l'implémenter afin qu'il puisse être utilisé en production.
Tout d'abord, je ne veux pas intégrer les informations d'identification AWS dans le code, je l'ai donc lu à partir d'un fichier CSV (un fichier téléchargé depuis IAM).
import csv
def get_credentials():
with open('Fichier CSV d'identification') as f:
credentials_file = csv.reader(f)
#Lisez la deuxième ligne car la première ligne du fichier CSV d'informations d'identification AWS est le nom de l'élément
next(credentials_file)
for credentials_array in credentials_file:
return credentials_array
Ensuite, je pense que le contenu du courrier devrait être facile à mettre à jour, alors lisez-le à partir d'un fichier texte externe.
Puisque je veux séparer le titre du courrier et le corps du courrier, je vais définir une cible appropriée dans le fichier texte comme ----- corps du courrier -----
à partir d'ici.
Image du fichier de contenu de messagerie
Objet de l'e-mail de test
-----Corps de l'e-mail à partir d'ici-----
Testez le corps de l'e-mail.
def get_mail_content():
with open('Fichier texte du contenu de l'e-mail') as f:
mail_content_all = f.read()
mail_content_splitted = mail_content_all.split('\n-----Corps de l'e-mail à partir d'ici-----\n')
return mail_content_splitted
Assurez-vous que l'adresse e-mail du destinataire est également lue à partir du fichier CSV externe afin qu'elle puisse être facilement mise à jour.
def get_addresses():
with open('Fichier CSV d'adresse e-mail') as f:
addresses_file = csv.reader(f)
for addresses_array in addresses_file:
return addresses_array
Maintenant que vous avez toutes les informations dont vous avez besoin pour votre e-mail, collectez les informations dont vous avez besoin à partir de la fonction que vous avez créée et envoyez-les avec send_email (** kwargs)
.
#Obtenez les informations d'identification AWS
access_key = get_credentials()[0]
secret_key = get_credentials()[1]
client = boto3.client('ses',
aws_access_key_id = access_key,
aws_secret_access_key = secret_key,
region_name = 'Région utilisée par Amazon SES (pas encore de Japon)'
)
#Obtenir le contenu des e-mails
mail_title = get_mail_content()[0]
mail_body = get_mail_content()[1]
#Obtenir une adresse e-mail
to_addresses = get_addresses()
#Puisque l'adresse e-mail doit être transmise dans un tableau[ ]Entourez de
cc_addresses = ['Adresse e-mail de destination CC']
#envoyer un e-mail
client.send_email(
Source = 'Adresse e-mail de l'expéditeur',
Destination = {
'ToAddresses': to_addresses,
'CcAddresses': cc_addresses
},
Message = {
'Subject': {
'Data': mail_title,
'Charset': 'UTF-8'
},
'Body': {
'Text': {
'Data': mail_body,
'Charset': 'UTF-8'
}
}
}
)
C'est acceptable! J'ai pensé, mais la [Foire aux questions sur Amazon SES] officielle (https://aws.amazon.com/jp/ses/faqs/) a cette explication.
Q: Y a-t-il une limite au nombre de destinataires pouvant être spécifiés dans un seul e-mail?
Vous pouvez spécifier jusqu'à 50 destinataires pour chaque message que vous envoyez à l'aide d'Amazon SES. Toutes les adresses des champs «À:», «CC:» et «BCC:» sont incluses dans cette limite. Si vous souhaitez envoyer un e-mail à plus de 50 destinataires, vous devez diviser la liste des destinataires en groupes de 50 ou moins et envoyer les messages dans chaque groupe.
En passant, si vous dépassez 50 personnes, le message d'erreur suivant sera renvoyé.
botocore.exceptions.ClientError: An error occurred (InvalidParameterValue) when calling the SendEmail operation: Recipient count exceeds 50.
Je vois. Il est nécessaire de traiter le nombre de destinataires à envoyer à la fois à 50 ou moins. Tout d'abord, faites de la partie d'envoi de courrier une fonction.
def send_email(client, to_addresses, cc_addresses, mail_title, mail_body):
#Processus d'envoi d'e-mails
client.send_email(
Source = 'Adresse e-mail de l'expéditeur',
Destination = {
'ToAddresses': to_addresses,
'CcAddresses': cc_addresses
},
Message = {
'Subject': {
'Data': mail_title,
'Charset': 'UTF-8'
},
'Body': {
'Text': {
'Data': mail_body,
'Charset': 'UTF-8'
}
}
}
)
Si vous appelez ce send_email pour 50 destinataires
cc_addresses = ['Adresse e-mail de destination CC']
to_addresses = get_addresses()
to_addresses_splitted = []
#Bouclez le nombre d'ensembles tous les 50_Attribuer pour compter
loop_count = len(to_addresses) // 50 + 1
for i in range(loop_count):
#Obtenez 50 éléments (y compris l'adresse e-mail CC) dans l'ensemble un par un
for j in range(50 - len(cc_addresses)):
# send_À de la liste des adresses e-mail à transmettre à l'e-mail_addresses_Entrez l'adresse e-mail dans l'ordre divisé
try:
to_addresses_splitted.append(to_addresses[i * 50 + j])
#Gestion des exceptions lorsqu'un index inexistant est spécifié
except:
pass
send_email(client, to_addresses_splitted, cc_addresses, mail_title, mail_body)
#Effacer chaque ensemble
to_addresses_splitted = []
Oups, tous les e-mails fractionnés seront envoyés à l'adresse e-mail CC. Je ne veux pas envoyer un e-mail à l'adresse e-mail CC à la fois, je l'enverrai donc à l'adresse e-mail CC uniquement pour la première transmission fractionnée.
def send_email(client, to_addresses, cc_addresses, mail_title, mail_body, i):
#Envoyer à l'adresse CC uniquement pour le premier fractionnement
if 0 == i:
destination_value = {
'ToAddresses': to_addresses,
'CcAddresses': cc_addresses
}
else:
destination_value = {
'ToAddresses': to_addresses
}
#Processus d'envoi d'e-mails
client.send_email(
Source = 'Adresse e-mail de l'expéditeur',
Destination = destination_value,
Message = {
'Subject': {
'Data': mail_title,
'Charset': 'UTF-8'
},
'Body': {
'Text': {
'Data': mail_body,
'Charset': 'UTF-8'
}
}
}
)
import boto3
import csv
def main():
#Informations AWS
access_key = get_credentials()[0]
secret_key = get_credentials()[1]
client = boto3.client('ses',
aws_access_key_id = access_key,
aws_secret_access_key = secret_key,
region_name = 'us-east-1'
)
#Obtenir le contenu des e-mails
mail_title = get_mail_content()[0]
mail_body = get_mail_content()[1]
#Obtenir une adresse e-mail
cc_addresses = ['Adresse e-mail de destination CC']
to_addresses = get_addresses()
to_addresses_splitted = []
#Bouclez le nombre d'ensembles tous les 50_Attribuer pour compter
loop_count = len(to_addresses) // 50 + 1
for i in range(loop_count):
#Obtenez 50 articles (y compris l'adresse e-mail CC) dans l'ensemble un par un
for j in range(50 - len(cc_addresses)):
# send_À de la liste des adresses e-mail à transmettre à l'e-mail_addresses_Entrez l'adresse e-mail dans l'ordre divisé
try:
to_addresses_splitted.append(to_addresses[i * 50 + j])
#Gestion des exceptions lorsqu'un index inexistant est spécifié
except:
pass
send_email(client, to_addresses_splitted, cc_addresses, mail_title, mail_body, i)
#Effacer chaque ensemble
to_addresses_splitted = []
def get_credentials():
with open('credentials.csv') as f:
credentials_file = csv.reader(f)
#Lisez la deuxième ligne car la première ligne du fichier CSV d'informations d'identification AWS est le nom de l'élément
next(credentials_file)
for credentials_array in credentials_file:
return credentials_array
def get_addresses():
with open('addresses.csv') as f:
addresses_file = csv.reader(f)
for addresses_array in addresses_file:
return addresses_array
def get_mail_content():
with open('mail_content.txt') as f:
mail_content_all = f.read()
mail_content_splitted = mail_content_all.split('\n---------------------Corps de l'e-mail à partir d'ici---------------------\n')
return mail_content_splitted
def send_email(client, to_addresses, cc_addresses, mail_title, mail_body, i):
#Envoyer à l'adresse CC uniquement pour le premier fractionnement
if 0 == i:
destination_value = {
'ToAddresses': to_addresses,
'CcAddresses': cc_addresses
}
else:
destination_value = {
'ToAddresses': to_addresses
}
#Processus d'envoi d'e-mails
client.send_email(
Source = 'Adresse e-mail de l'expéditeur',
Destination = destination_value,
Message = {
'Subject': {
'Data': mail_title,
'Charset': 'UTF-8'
},
'Body': {
'Text': {
'Data': mail_body,
'Charset': 'UTF-8'
}
}
}
)
if __name__ == "__main__":
main()
Vous pouvez désormais envoyer des e-mails localement sans souci. Cependant, s'il provient du local, d'autres personnes ne peuvent pas l'envoyer (= je serai en charge de l'envoi du courrier), donc je me demande si ce sera AWS Lambda bientôt.
We're hiring! Nous développons un chatbot IA. Si vous êtes intéressé, n'hésitez pas à nous contacter depuis la page Wantedly!
Documentation officielle Boto3 Questions fréquentes sur Amazon SES
Recommended Posts