一つ前の記事の続きっぽいやつです。今回はAWS SDK for JavaScriptからAWS SNSのメッセージを発行します。

目標


最終ゴールはLambdaからSNSメッセージを発行するというところなのですが、とりあえず手元のNode.js環境からSNSのメッセージを発行したいと思います。

実行環境


SNSの設定


本当はSMSでやろうかと思ったのですがSMSが飛ばなかったのでメールでやりました。適当にトピックとサブスクリプション作成します。

確認のメールが届くのでメール本文のConfirm subscriptionを押します。

確認済みのページに遷移します。この時に勢いで右下のclick here to unsubscribeを押してはいけません。もっかいサブスクリプションを作り直しになります。

認証を設定する


手元から実行する場合にアクセスキーとシークレットアクセスキーが必要になります。まず、そいつを設定します。テストとはいえ、怖いのでIAMは分けました。

方法は下記の通りいろいろあります。もちろんハードコードは非推奨です。

Node.js で認証情報を設定する

今回は 「共有認証情報ファイル (~/.aws/credentials) からロードする」でやることにしました。

共有認証情報ファイルから Node.js に認証情報をロードする

やり方は上記に書かれている通り.aws/credentialsに下記のように記述するだけです。詳しいのは上のドキュメント見てください。

1
2
3
[default]
aws_access_key_id=<YOUR_ACCESS_KEY_ID>
aws_secret_access_key=<YOUR_SECRET_ACCESS_KEY>

プログラム書く


とりあえず、勢いでマッハでコードを書いていきます。まず、aws-sdkをインストールします。

1
npm install aws-sdk

次に公式のサンプルを参考にしながら雑にコードを書きます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const aws = require('aws-sdk');
aws.config.update({region: 'ap-northeast-1'}); //リージョン指定します

const params = {
Message: 'test message hogegege', //ここにメッセージ書きます
TopicArn: 'arn:aws:sns:ap-northeast-1:1234567890abcdefghijk' //AWS SNSのトピックのARNを指定します
};

const publishTextPromise = new aws.SNS({apiVersion: '2010-03-31'}).publish(params).promise();
publishTextPromise.then((data) => {
console.log("Message ${params.Message} send sent to the topic ${params.TopicArn}");
console.log("MessageID is " + data.MessageId);
}).catch((err) => {
console.error(err, err.stack);
});

こいつをindex.jsとかで適当に保存します。

動かして確認する


後は動かすだけです。

1
node index.js

メールを確認するとメッセージが届いています。

ちなみに認証してなかったら下記のようなエラーが返ってきます。Missing credentials in configって書いてますね。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{ Error: connect ETIMEDOUT xxx.xxx.xxx.xxx:80
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1083:14)
message: 'Missing credentials in config',
errno: 'ETIMEDOUT',
code: 'CredentialsError',
syscall: 'connect',
address: 'xxx.xxx.xxx.xxx',
port: 80,
time: 2019-04-16T13:43:24.189Z,
originalError:
{ message: 'Could not load credentials from any providers',
errno: 'ETIMEDOUT',
code: 'CredentialsError',
syscall: 'connect',
address: 'xxx.xxx.xxx.xxx',
port: 80,
time: 2019-04-16T13:43:24.189Z,
originalError:
{ errno: 'ETIMEDOUT',
code: 'ETIMEDOUT',
syscall: 'connect',
address: 'xxx.xxx.xxx.xxx',
port: 80,
message: 'connect ETIMEDOUT xxx.xxx.xxx.xxx:80' } } }
'Error: connect ETIMEDOUT xxx.xxx.xxx.xxx:80
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1083:14)'

感想


なにこれチョロすぎワロタァァァ…数十分でできてしまうやんけ…この記事の方が時間かかってるょ…

その他


もう我慢できないのでAnno1800をやります。Lambdaからサーバの定期監視するだけの実装なら明日マッハでできると思うのでマッハでAnno1800をやります。

おわり