javascriptでプロトコル、ポート、ホスト名を取得

プロトコル+ポート+ホスト名をなんと呼ぶのかわかりませんが、 https://xxx.com:3000 みたいなものを出力する。

80番ポートの時は、ポート番号はつけないようにしている。

const protocol = window.location.protocol
const port = window.location.port
const host_name = window.location.hostname
const protocol_and_fqdn = `${protocol}//${host_name}${port!=80?':'+port:''}`
console.log(protocol_and_fqdn)

API Gatewayで Authorizer が動かない

オーソライザーが動かない

API Gatewayでオーソライザーが動かなかったのメモ。

動かないというより、そこまで到達していなかった、というだけの話だが、HTTPリクエストヘッダに Authorization を付与すればオーソラーザーが実行される。

Authorization に入れるあたいは、以下のAWSコマンドの戻り値の Session の値。

aws cognito-idp admin-initiate-auth \
--region ap-northeast-1 \
--user-pool-id XXXXX \
--client-id XXXXX \
--auth-flow ADMIN_NO_SRP_AUTH \
--auth-parameters USERNAME=XXXXX,PASSWORD=XXXXX

curlコマンドは以下。

curl -H "Authorization: XXX” https://XXX.com

Cognitoで Invalid phone number format. と言われる

Invalid phone number format.と言われる

Cognitoでユーザを作成する際、電話番号を 00000000000000-0000-0000 で入力しても、エラーが返ってくる。

電話番号の正しい(?)フォーマットは、+15555555555 だった。日本だと +81 かな。

参考

stackoverflow.com

jsでテキストをclipboardにcopyする

javascriptで外部モジュールなしに、クリップボードへコピーする方法を紹介する。

以下の関数で動く。

  copyToClipboard(text){
    navigator.clipboard.writeText(text).then(function() {
      /* clipboard successfully set */
    }, function() {
      /* clipboard write failed */
    });
  },

そのため、Nuxtjs(Vuejs)を利用する場合は、method内に上記の関数を追記し、以下のようにすることで、ボタン押下時にクリップボードへコピーすることができる。

<button @click="copyToClipboard('aaa')">Copy</button>

AWSSESのSMTPを利用するとmessageIDが書き換わる

AWSSESのSMTPを利用してメール送信をすると、messageIDが上書きされてしまう。

そのため、以下のようなシステムは破綻することになる。

  • message_header_id を生成する
  • 生成した message_header_id をDBに保存
  • 返信メールの in_reply_to と突き合わせてどのメールに対する返信か紐づける

messageIDが上書きされてしまうのは避けられないとして、送信前のmessageIDと送信後のmessageIDさえ何かしらの方法で紐づけることができれば、一応、何とかはなるので、紐づける方法を紹介する。

  • SMTP送信の時にSNSトピックにメッセージを送る
  • SNSトピックでLambda関数を購読状態にする
  • lambda関数で送信前と送信後のmessageIDを取得
  • lambda関数でよしなにする(私の場合は、DBの送信前の message_header_id を 送信後の message_header_id に更新するクエリを実行)

さて、肝心のLambda関数の中身は以下である。

event 変数にメールの情報が入ってくるので、関数の通りに取得していくと、送信前と送信後のmessageIDを取得できる。

sns_obj['Message']JSON.parse している理由は、なぜかこの項目は文字列で値が返ってくるからである。

オブジェクトの中身の詳細は、公式ドキュメントを参照。

exports.handler = async (event) => {
    // TODO implement
    const response = {
        statusCode: 200,
        body: JSON.stringify('Hello from Lambda!'),
    };

    const sns_obj = event['Records'][0]['Sns']
    console.log(sns_obj)
    const message_obj = JSON.parse(sns_obj['Message'])
    console.log(message_obj)
    const mail_obj = message_obj['mail']
    console.log(mail_obj)
    const new_message_id = `<${mail_obj['messageId']}@email.amazonses.com>`
    const original_message_id = mail_obj['headers'].find(x=>x['name']=='Message-ID')['value']

    // result
    console.log(original_message_id)
    console.log(new_message_id)

    return response;
};

Lambda関数が実行されない

Lambdaが実行されない

検証環境でLambdaの実行を確認したし、このロールを本番でも流用しちゃおう、と思って検証用のソースと本番用のソースで同じロールを利用すると、Lambdaが実行されなかった。

原因は、検証用のソースを作った時に作成されたロールに与えられているポリシーは、 AWSLambdaBasicExecutionRole-XXXXX となっており、現在アタッチされているロールは、特定のLambdaしか実行することが許されていない。

そのため、ロールの AWSLambdaBasicExecutionRole-XXXXX というポリシーを削除して AWSLambdaBasicExecutionRole を与えることで、すべてのLambdaが実行できるようになる。

ロールは適切に管理するべきだが、それほどクリティカルなことをしない場合は、これでよいだろう。