カテゴリー
【AWS Lambda使い方ガイド】NodemailerのAWS SESクライアントを使ってLambdaからEmailを送信してみる
※ 当ページには【広告/PR】を含む場合があります。
2024/10/26
クライアント側からSESでメール送信
.env
AWS_ACCESS_KEY_ID="....";
AWS_SECRET_ACCESS_KEY="....";
const nodemailer = require("nodemailer");
const aws = require("@aws-sdk/client-ses");
const ses = new aws.SES({
apiVersion: "2010-12-01",
region: "us-east-1",
});
const transporter = nodemailer.createTransport({
SES: { ses, aws },
});
Lambdaハンドラにnodemailer-SESクライアントを組み込む
import nodemailer from 'nodemailer';
import * as aws from "@aws-sdk/client-ses";
const ses = new aws.SES({
apiVersion: "2010-12-01",
region: "us-east-1", //👈自身のSESの設定済みリージョンであることを確認
});
export function sendEmail() {
//👇送信先のアドレス
const email = 'okurisaki@oaite.jp';
//👇送信する内容
const mail = {
from: 'hogehoge@piyopiyo.com',
to: email,
subject: 'SESからのメールです',
text: 'こんにちは!',
html: `<p>こんにちは!</p>`,
};
try {
const transport = nodemailer.createTransport({
SES: { ses, aws },
});
const result = await transport.sendMail(mail);
return JSON.stringfy(result);
} catch (err) {
return JSON.stringfy(err);
}
}
sendEmail
Lambdaに直接AWSクレデンシャル情報を環境変数としてセットできない
.env
AWS_ACCESS_KEY_ID="....";
AWS_SECRET_ACCESS_KEY="....";
import {
Stack,
StackProps,
aws_lambda,
//...中略
} from 'aws-cdk-lib';
import { Construct } from 'constructs';
export class CdkTacokinShopStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
//...いろいろ中略
const lambda = new aws_lambda.Function(this, 'Server', {
runtime: aws_lambda.Runtime.NODEJS_20_X,
code: aws_lambda.Code.fromAsset(join(__dirname, '../../build/lambda')),
handler: 'index.handler',
architecture: aws_lambda.Architecture.ARM_64,
memorySize: 128,
timeout: Duration.seconds(30),
environment: {
//☆👇クレデンシャル変数は直接Lambdaへ注入できない!
"AWS_ACCESS_KEY_ID": process.env.AWS_ACCESS_KEY_ID,
"AWS_SECRET_ACCESS_KEY": process.env.AWS_SECRET_ACCESS_KEY,
}
}).addFunctionUrl({
authType: aws_lambda.FunctionUrlAuthType.NONE,
invokeMode: aws_lambda.InvokeMode.RESPONSE_STREAM
});
//...以下略
envirnoment
SES用のLamboda実行ロールを作成
@aws-sdk/ses
import {
Stack,
StackProps,
aws_lambda,
aws_iam,
//...中略
} from 'aws-cdk-lib';
import { Construct } from 'constructs';
export class CdkTacokinShopStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
//...いろいろ中略
//👇Lambda用の基本ポリシー
const lambda_basic_policy = new aws_iam.ManagedPolicy(this, 'Lambda_basic_policy', {
managedPolicyName: 'lambda_basic_policy',
statements: [
new aws_iam.PolicyStatement({
effect: aws_iam.Effect.ALLOW,
actions: [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
resources: [
'arn:aws:logs:*:*:*'
],
}),
],
});
//☆👇SES用のメール送信ポリシー
const ses_sender_policy = new aws_iam.ManagedPolicy(this, 'Ses_sender_policy', {
managedPolicyName: 'ses_sender_policy',
statements: [
new aws_iam.PolicyStatement({
effect: aws_iam.Effect.ALLOW,
actions: [
"ses:SendEmail",
"ses:SendRawEmail"
],
resources: [
'*'
],
}),
],
});
//👇カスタムロールの作成
const ses_role = new aws_iam.Role(this, 'ses_sender_role', {
roleName: 'ses_sender_role',
assumedBy: new aws_iam.ServicePrincipal('lambda.amazonaws.com'),
});
//👇先ほど作成した2つのポリシーをアタッチ
ses_role.addManagedPolicy(lambda_basic_policy);
ses_role.addManagedPolicy(ses_sender_policy);
const lambda = new aws_lambda.Function(this, 'Server', {
runtime: aws_lambda.Runtime.NODEJS_20_X,
code: aws_lambda.Code.fromAsset(join(__dirname, '../../build/lambda')),
handler: 'index.handler',
architecture: aws_lambda.Architecture.ARM_64,
memorySize: 128,
timeout: Duration.seconds(30),
//☆👇カスタム実行ロールを指定
role: ses_role
}).addFunctionUrl({
authType: aws_lambda.FunctionUrlAuthType.NONE,
invokeMode: aws_lambda.InvokeMode.RESPONSE_STREAM
});
//...以下略
まとめ
記事を書いた人
ナンデモ系エンジニア
主にAngularでフロントエンド開発することが多いです。 開発環境はLinuxメインで進めているので、シェルコマンドも多用しております。 コツコツとプログラミングするのが好きな人間です。
カテゴリー