Twitter APIを使って自動でTweetする（２）

[前回の投稿](https://qiita.com/jnakanaka1/items/bf4f450bd9dd3bd5005f)ではTwitterのAPIからRequest Tokenの取得をするテストコードを作成した。
今回は、そのコードをAWSのLambdaにデプロイし、API Gatewayを設定してAPI Gateway経由でRequest Tokenを取得できるようにする。

##Lambda用のコードに修正

Lambdaで実行するために、ハンドラ関数を加える必要がある。ハンドラ関数がAPI Gatewayから呼ばれ、コードが実行される。その際にeventを受け取ることができ、eventには接続元からのリクエストなどが含まれる（今回は使っていないが）。
ハンドラ関数は任意だが、Lambdaの設定と合わせる必要があり、今回は「lambda_handler」としている。

```python:get_request_token.py
import json
import time
import base64
import os
import uuid
import hashlib
import hmac
import urllib.parse
import requests

REQUEST_URL = 'https://api.twitter.com/oauth/request_token'
REQUEST_METHOD = 'POST'
API_KEY = os.environ.get('API_KEY')
API_SECRET = os.environ.get('API_SECRET')
TOKEN_SECRET = ''
CALLBACK_URL = os.environ.get('CALLBACK_URL')
SIGNATURE_METHOD = 'HMAC-SHA1'

def _create_timestamp():
    return str(int(time.time()))

def _create_nonce():
    return str(uuid.uuid4())

def _create_base_string(params: dict):
    string = ''
    for key, val in sorted(params.items()):
        string += key + '=' + val + '&'

    return string.rstrip('&')

def _convert_dict(dict_: dict):
    string = ''
    for key, val in dict_.items():
        string += key + '="' + val + '", '

    return string.rstrip(', ')

def _create_signature(base_string: str):
    base_string = REQUEST_METHOD + '&' + urllib.parse.quote(REQUEST_URL, safe='') + '&' + urllib.parse.quote(base_string, safe='')
    key = API_SECRET + '&' + TOKEN_SECRET
    hashed_string = hmac.new(key.encode(), base_string.encode(), hashlib.sha1)
    return urllib.parse.quote(base64.standard_b64encode(hashed_string.digest()), safe='')
    
def _create_authorization_params():
    authorization_params = {}
    authorization_params['oauth_timestamp'] = _create_timestamp()
    authorization_params['oauth_consumer_key'] = urllib.parse.quote(API_KEY, safe='')
    authorization_params['oauth_nonce'] = _create_nonce()
    authorization_params['oauth_callback'] = urllib.parse.quote(CALLBACK_URL, safe='')
    authorization_params['oauth_signature_method'] = SIGNATURE_METHOD
    authorization_params['oauth_version'] = '1.0'
    authorization_params['oauth_signature'] = _create_signature(_create_base_string(authorization_params))

    return authorization_params

def _create_authorization_header():
    authorization_header_val = 'OAuth '
    params = _create_authorization_params()
    authorization_header_val += _convert_dict(params)
    
    return {'Authorization': authorization_header_val}

def _execute():
    headers = _create_authorization_header()

    return requests.post(REQUEST_URL, headers=headers)

def lambda_handler(event, context):
    
    response_data = _execute()
    return {
        'statusCode': 200,
        'body': response_data.text
    }
```


##Lambda
[Lambdaコンソール](https://console.aws.amazon.com/lambda/)

- **Lambdaの作成**

コンソールにアクセスし、「一から作成」を選択し、適当な関数名を入力し、ランタイム「Python 3.7」を選択して「関数の作成」をクリックする。

<img width="531" alt="lambda-1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407848/21c8c02c-dea1-71d6-abd8-90c8a717c2de.png">

- **コードとハンドラの設定**

コードエントリタイプで「zipファイルをアップロード」を選択し、アップロードボタンをクリックしてデプロイパッケージをアップロードする。
※デプロイパッケージの作成方法は別に説明します。
ハンドラは、「get_request_token.lambda_handler」に設定する。
設定後、右上の「保存」ボタンをクリックし、保存する。

<img width="813" alt="lambda-2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407848/653506cf-fe8d-595c-4460-23236f451aaf.png">

- **環境変数の設定**

API_KEY・API_SECRET・CALLBACK_URLは環境変数から取得するようにコーディングしているので、Lambdaの環境変数に設定する必要がある。
これも設定後、右上の「保存ボタン」で保存する。

<img width="839" alt="lambda-3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407848/a70e60aa-15a3-6ecf-982d-1fe92dcf6b38.png">

- **デプロイパッケージの作成**

今回はサードパーティのrequestsパッケージが必要なため、それを含んだデプロイパッケージを作成する必要がある。作成方法は以下の通り。

```
mkdir package
cp get_request_token.py package/.
pip install requests -t package/.
cd package
zip -r package.zip *
```

##API Gateway
[API Gatewayコンソール](https://console.aws.amazon.com/apigateway/)

- **API Gatewayの作成**

コンソールにアクセスし、「REST」「新しいAPI」を選択し、適当なAPIを入力して「APIの作成」をクリックする。

<img width="595" alt="apigateway-1.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407848/60b40b0f-ca25-c616-97ab-4cda0fd856c2.png">

- **リソースの作成**

左のペインから「リソース」を選択し、アクションで「リソースの作成」をクリックする。

<img width="579" alt="apigateway-3.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407848/b3c70021-20ac-f7c7-a4e1-809b5ae11ca7.png">

「リソース名」「パス名」を入力し、「リソースの作成」をクリックする。
※ここで設定したパス名がこのAPIにアクセスするためのパスになる。

<img width="525" alt="apigateway-4.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407848/0d02a8e1-b601-db39-800c-446d66e1ff95.png">

- **メソッドの作成**

作成した「リソース」を選択し、アクションで「メソッドの作成」をクリックする。

<img width="567" alt="apigateway-5.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407848/5012f3ba-004e-d8ca-88ef-e16e4249b123.png">

今回はPOSTメソッドでアクセスするので「POST」を選択し、☑をクリックして保存する。

<img width="545" alt="apigateway-7.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407848/092904b7-dc93-65ef-9190-70cd8f7f7f42.png">

統合タイプで「Lambda統合」を選択し、「Lambdaプロキシ統合の使用」にチェックを入れ、Lambda関数は作成したものを指定し、「保存」をクリックする。

<img width="519" alt="apigateway-8.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407848/b24838ed-4aca-fd6a-b243-036be1bb92ce.png">

- **デプロイ**

アクションで「APIのデプロイ」を選択し、「デプロイされるステージ」を設定し、「デプロイ」をクリックする。

<img width="641" alt="apigateway-9.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407848/a26ee5ad-c698-af6d-bb00-b1c1243c5c2f.png">
<img width="297" alt="apigateway-10.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407848/08adf776-b82d-2add-b4c5-7745e7708a2a.png">

デプロイ後、「URL の呼び出し: https://xxxxx.execute-api.<リージョン>.amazonaws.com/<ステージ>」の形式でURLが表示される。
これにパスを付け加えた「https://xxxxx.execute-api.<リージョン>.amazonaws.com/<ステージ>/<パス>」で今回作成したAPIにアクセスできる。

続編で取得したRequest Tokenを使って[Twitterの認証/認可を取得するVueアプリを作成した記事](https://qiita.com/jnakanaka1/items/94c342e6e2a46f4ae64c)をアップしました。

前回の[Request Token取得についてはこちら](https://qiita.com/jnakanaka1/items/bf4f450bd9dd3bd5005f)