1
Help us understand the problem. What are the problem?

posted at

updated at

【Node.js】AWS SNSを使ってSMS(ショートメッセージ)を送る【Typescript】

ここでいうSNSは、Twitterみたいなソーシャルネットワーキングサービス・・・ではなく、
AWSの SimpleNotificationService のことです。
SNSでSMSを送る(噛みそう)機能を触ったので、設定方法などを記録します。

IAMユーザの追加

まずはユーザを作成。
SNSのフルアクセス権限を付与します。

ユーザー詳細の設定

このページの右上にある「ユーザを追加」ボタンを押下
https://us-east-1.console.aws.amazon.com/iamv2/home?region=us-east-1#/users

image.png

  • ユーザ名: 適当なユーザ名
  • SWS認証情報タイプ: アクセスキー -プログラムによるアクセス

ユーザ名は会社のルールに則るのがいいと思います。
うちでは プロジェクト名_環境名にしています。

例: my_web_project_staging

アクセス許可の設定

image.png

  • 既存のポリシーを直接アタッチ選択
  • AmazonSNSFullAccess✅

タグの追加 (オプション)

なし

確認

image.png

これで「ユーザの登録」ボタンを押せば設定完了です。

アクセスキーIDとシークレットアクセスキーをメモしておく

登録ボタン押下後、アクセスキーIDシークレットアクセスキーが表示されます
例えばNode.jsでSNSを使う場合は、この2つのキーを.envファイルなどに記載することでプロジェクトからSNSを実行することが可能になります。

このキーを公開すると悪用されてしまう恐れがあるので取扱注意です。

Node.jsから扱う

Node.jsから動かせるようにする設定例です。

パッケージのインストール

aws-sdkをインストールします

npm i aws-sdk

ディレクトリ構成

- .env
- aws
  - config.ts
  - sns_client.ts

.env

  • .envファイルに先ほど取得したアクセスキーIDとシークレットアクセスキーを記載します
AWS_ACCESS_KEY_ID=XXXXXXXXXXXXXXXXXXXXX
AWS_SECRET_ACCESS_KEY=xxxxxxxxX/XxxXxxxxxX+XXxxxXX/XxXXX
AWS_DEFAULT_REGION=ap-northeast-1

aws/config.ts

aws-sdkの初期処理をします。

import aws from 'aws-sdk'

const credential =
  process.env.NODE_ENV === 'local'
    ? new aws.SharedIniFileCredentials()
    : new aws.Credentials({
        accessKeyId: process.env.AWS_ACCESS_KEY_ID as string,
        secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY as string,
      })
console.log('[debug] AWS credential: ', credential)
aws.config.credentials = credential
aws.config.region = process.env.AWS_DEFAULT_REGION
export default aws

  • NODE_ENVが local の場合は、 aws.SharedIniFileCredentials()で初期化します。
    これは自分の端末の ~/.aws/credentials に書いてあるアクセスキーIDとシークレットアクセスキーを参照してくれます。

  • NODE_ENVが development の場合は、 aws.Credentials()で初期化します。
    ローカル開発以外の場合(開発環境や検証環境で動く場合)は、.envに書いたアクセスキーIDとシークレットアクセスキーを設定します。

  • export default awsと書くことで、このクレデンシャルが設定されたawsを別ファイルから呼び出せるようにしています。

aws/sns_client.ts

実際にSNS送信するコードはこちらです。
(Typescriptを使っています)

import aws from './config'

export class SnsClient {
  public publish(message: string, phone: string) {
    const params = {
      Message: message,
      PhoneNumber: phone,
    }
    const publishTextPromise = new aws.SNS({ apiVersion: '2010-03-31' }).publish(params).promise()

    publishTextPromise
      .then(function (data) {
        console.log(`Message ${params.Message} sent to the topic ${params.PhoneNumber}`)
        console.log('MessageID is ' + data.MessageId)
        console.log(data)
        return data?.MessageId
      })
      .catch(function (err) {
        console.error(err, err.stack)
      })
    return true
  }
}

AWS公式のサンプルを元に書いています。
結構シンプルです。

  • import aws from '../config' で、先ほど初期設定したawsファイルを読み込んでいます。

  • public publish(message: string, phone: string) でメッセージを電話番号を引数にした関数を定義しています。

  • new aws.SNS({ apiVersion: '2010-03-31' }).publish(params).promise()でSMS送信promiseを用意し、実行しています。

実行結果

成功すれば以下のメッセージが出ます。

Message メッセージ内容 sent to the topic 080XXXXXXXX
MessageID is XxXXX000X-x0xxx-00XX-x0xx-x0000000xxx00x

権限がちゃんと設定されていないと以下のエラーが出ます。

User: arn:aws:iam::1234567890:user/xxx_xxx is not authorized to perform: SNS:Publish on resource: 080XXXXXXXX because no identity-based policy allows the SNS:Publish action

以上です。
MessageIDやRequestIDはメッセージの配信ログを見るために使うと思われます。
機会があれば試してみようかな。

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
1
Help us understand the problem. What are the problem?