はじめに
aws-sdk-rust の sesv2 を使いたくて、ローカルでメールの動作確認をしたかったのですが、localstackを使おうとしたらno provider exists for service sesv2
とのエラーが出てしまいました。
しばらくググっているとaws-ses-v2-localを見つけたので、こちらを使って動作確認してみます。
aws-ses-v2-local を dockerコンテナ内で動かす
version: "3.7"
services:
local_ses:
image: node:18.1.0
working_dir: /app
ports:
- 8005:8005
volumes:
- ./local_ses:/local_ses
tty: true
package.json を作成し, node_modules を生成します。
docker-compose run local_ses bash
npm init # 対話形式でいろいろ聞かれるので答える
npm install aws-ses-v2-local
のちのち実行するとSyntaxError: Cannot use import statement outside a module
エラーがでるので、指示通り"type": "module"
を package.json に追記します。ついでに、npm start
で実行できるように scripts に追記します。
(略)
"name": "app",
"version": "1.0.0",
"description": "",
"main": "index.js",
+ "type": "module",
"scripts": {
+ "start": "node index.js"
},
(略)
実行するjsファイルを作成します。aws-ses-v2-localの Usage の通りですが、TypeError: server is not a function
とのエラーが出てしまったのでそこだけ変えています。
import server from 'aws-ses-v2-local'
- server({ port: 8005 })
+ let s = await server.default({ port: 8005 })
console.log('aws-ses-v2-local: server up and running')
docker-compose up
で立ち上がるようにします。
version: "3.7"
services:
local_ses:
image: node:18.1.0
working_dir: /app
ports:
- 8005:8005
volumes:
- ./local_ses:/local_ses
tty: true
+ command: "npm start"
立ち上げると以下のようにログが出力されます。
$ docker-compose up
local_ses_1 |
local_ses_1 | > app@1.0.0 start
local_ses_1 | > node index.js
local_ses_1 |
local_ses_1 | aws-ses-v2-local: server up and running
aws-sdk-rust sesv2 でメールを送信する
Rustのコンテナを追加します。
version: "3.7"
services:
+ app:
+ image: rust:1.60
+ working_dir: /app
+ volumes:
+ - ./app:/app
+ environment:
+ - AWS_ACCESS_KEY_ID=xxx
+ - AWS_SECRET_ACCESS_KEY=xxx
+ - AWS_REGION=ap-northeast-1
+ tty: true
local-ses:
build: ./local_ses
ports:
- 8005:8005
command: "npm start"
volumes:
- ./local_ses:/app
tty: true
[package]
name = "app"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
aws-config = "0.13.0"
aws-sdk-sesv2 = "0.13.0"
tokio = { version = "1", features = ["full"] }
http = "0.2.8"
main.rs
はaws-sdk-rustのgithubのReadme と ses v2のコード例を参考にして書きました。
use aws_sdk_sesv2::{Client, Error, Endpoint};
use aws_sdk_sesv2::model::{Body, Content, Destination, EmailContent, Message};
use http::Uri;
#[tokio::main]
async fn main() -> Result<(), Error> {
let shared_config = aws_config::load_from_env().await;
// let client = Client::new(&shared_config);
// ローカルで動作確認するときは、以下のようにエンドポイントを指定して client をつくる
let ses_local_config = aws_sdk_sesv2::config::Builder::from(&shared_config)
.endpoint_resolver(
Endpoint::immutable(Uri::from_static("http://local_ses:8005")),
).build();
let client = Client::from_conf(ses_local_config);
let dest = Destination::builder().to_addresses("user@example.com").build();
let subject_content = Content::builder().data("テストです").charset("UTF-8").build();
let body_content = Content::builder().data("テストの内容です").charset("UTF-8").build();
let body = Body::builder().text(body_content).build();
let msg = Message::builder()
.subject(subject_content)
.body(body)
.build();
let email_content = EmailContent::builder().simple(msg).build();
let req = client
.send_email()
.from_email_address("sender@example.com")
.destination(dest)
.content(email_content)
;
let resp = req.send().await;
println!("response: {:?}", resp);
Ok(())
}
app コンテナ内で cargo run
を実行すると、成功のレスポンスが返ってきます。
$ cargo run
response: Ok(SendEmailOutput { message_id: Some("ses-351447512") })
http://localhost:8005 にアクセスすると、メールの内容を確認することができます。