AWSとTwitter API v2を利用して、自動ツイートシステムを作る方法

Twitter APIのV2への移行により、APIの認証フローやトークンの管理をAWS上で行う方法が紹介されています。SSMリソースをIaCで定義することで、OAuthクライアントシークレットを取得する方法、ツイートのリクエスト内容についての解説、Secrets Storeの使用方法が紹介されています。個人利用で廉価に利用したい場合、Systems Manager Parameter Storeを利用し、GetParameterCommandとPutParameterCommandを利用した処理をすることが推奨されています。また、2つのクラスを利用するOAuthで認証してAPIを利用する方法も紹介されています。

広告ここから
広告ここまで

目次

    Twitter APiがV2に変わりましたが、少量のツイートであれば引き続き無料で使うことができます。

    APIの認証フローやトークンの管理をAWS上で行う方法を簡単にまとめました。

    紹介しないこと

    この辺りの内容は今回紹介しません。

    • generateAuthURLrequestAccessTokenを利用した、OAuthクライアントシークレットの取得方法
    • SSMリソースをIaCで定義する方法
    • ツイートのリクエスト内容の解説

    Systems ManagerのParameter Storeで手軽に管理する

    Secrets Storeを使う方が良いとは思いますが、個人利用で廉価に使いたいため、Systems Manager Parameter Storeを利用します。

    使うコマンドは、GetParameterCommandPutParameterCommandの二つで良さそうです。

    serverless.tsの場合は、こんな感じでIAMロールを設定しましょう。

        iam: {
          role: {
            statements: [{
              Effect: 'Allow',
              Action: [
                'ssm:GetParameter',
                'ssm:PutParameter'
              ],
              Resource: [
                "arn:aws:ssm:us-west-2:123456:parameter/TWITTER_OAUTH*",
                "arn:aws:ssm:us-west-2:123456:parameter/TWITTER_TOKEN*"
              ]
            }]
          }
        }
      }

    取得と更新処理は、次のようなクラスを作りました。

    実際にはTypeScriptの型が付いていますが、抽象化させている部分が説明には冗長なので削りました。

    import { GetParameterCommand, PutParameterCommand, SSMClient } from "@aws-sdk/client-ssm";
    
    export class SSMSecretManager{
        private readonly client
        constructor(config) {
            this.client = new SSMClient(config)
        }
        public async getSecretsByName(keyName) {
            const getParameterCommand = new GetParameterCommand({
                Name: keyName,
                WithDecryption: true
            })
            const response = await this.client.send(getParameterCommand)
            if (!response.Parameter || !response.Parameter.Value) {
                return null;
            }
            const value = JSON.parse(response.Parameter.Value)
            return value
        }
        public async updateSecrets(keyName, value) {
            const updateSecretCommand = new PutParameterCommand({
                Name: keyName,
                Overwrite: true,
                Type: "SecureString",
                DataType: 'text',
                Value: JSON.stringify(value),
            })
            await this.client.send(updateSecretCommand)
        }
    }

    2つの秘密情報を取得する

    SSMには2つのデータを保存しています。

    1つはOAuth用のクライアントシークレットなどの情報、もう1つはアクセストークン・リフレッシュトークンなどです。

    const client = new SSMSecretManager({ region: 'us-west-2' })
    const clientSecrets = await client.getSecretsByName('TWITTER_OAUTH_CLIENT_SECRETS')
    const token = await client.getSecretsByName('TWITTER_TOKEN')

    また、取得したトークンが期限切れしている場合は、更新処理が必要です。

    const diffFromTheExpiresAt = new Date(token.expires_at).getTime() - new Date().getTime()
    if (diffFromTheExpiresAt < 0) {
        // Refresh access token
    }

    Twitter API v2では、2つのクラスを利用する

    OAuthで認証してAPIを利用するため、auth.OAuth2UserClientの2クラスを利用しました。

    const authClient = new auth.OAuth2User({
        ...clientSecrets,
        token,
    })
    const client = new Client(authClient)

    クライアントシークレットとアクセストークンの両方を利用しますので、SSMの戻り値を合成して利用しましょう。

    アクセストークンを更新する場合、更新後のレスポンスをtokenに再設定します。

    const newToken = await authClient.refreshAccessToken()
    const client = new Client(new auth.OAuth2User({
        ...clientSecrets,
        token: newToken.token,
    }))

    SSMでリフレッシュしたアクセストークンを保存する

    リフレッシュすると、以前のアクセストークンは利用できません。SSMの値も更新しましょう。

    SSMのパラメーターストアには「更新操作」はなく、「上書き」になることに注意が必要です。

    上のサンプルコードを再掲しますが、暗号化などの設定も明示的に行うことをお勧めします。

    
        public async updateSecrets(keyName, value) {
            const updateSecretCommand = new PutParameterCommand({
                Name: keyName,
                Overwrite: true,
                Type: "SecureString",
                DataType: 'text',
                Value: JSON.stringify(value),
            })
            await this.client.send(updateSecretCommand)
        }

    関連

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark