LambdaでGoogleスプレッドシートを扱う

概要

awsのLambdaからGoogleスプレッドシートを使いたい。

ローカル環境では、スプレッドシートを使う際にはアクセス用のjsonファイルを呼び出していたが、Lambdaにjsonファイルをそのままアップロードするのにはセキュリティ的に懸念がある。ググってみるとみんなその方式っぽい...のでメモ。

Secrets Managerでログイン情報を管理

ログイン情報等を管理するツールが用意されているのでそちらで管理する。

Lambdaからの呼び出し方

def get_gc():
    client = boto3.client(service_name='secretsmanager')
    get_secret_value_response = client.get_secret_value(SecretId="<登録した際のSecretID>")

    secret_string =  get_secret_value_response['SecretString']
    credential_dic = json.loads(secret_string)    
    credentials = Credentials.from_service_account_info(credential_dic)
    credentials._scopes = 'https://spreadsheets.google.com/feeds','https://www.googleapis.com/auth/drive'

    gc = gspread.authorize(credentials)

    return gc


def lambda_handler(event, context):    
    gc = get_gc()

[正規表現]twitterのアカウント名とハッシュタグ

概要

自動フォローするためにツイートに記載されているアカウント名の取得をしたかったのと、ツイートに記載されているハッシュタグ情報をLINEに送付したく該当する正規表現を下記に記載。

正規表現

# アカウント名
m = re.findall(r'@[0-9a-zA-Z_]{3,15}', text)

# ハッシュタグ
m = re.findall(r'#[^#\s]*', text)

短すぎアカウント名を検知する可能性より、誤検知の方が可能性が高いので、アカウント名の取得は3文字以上にしている。

【サービス > CloudWatch > Log Insights】特定文字のフィルタリング

概要

実行しているスクリプトがそれなりの量のログを吐き出すため、ロググループで特定の文字列を見つけるためにいくつかのログを開く必要がでてきてしまった。Log Insights で探したい文字列のフィルタリングして一発で見つけるための方法。

やり方

文字列hogehogeを探したいとき

fields @timestamp, @message
| filter @message like /hogehoge/

【サービス > CloudWatch】 引数を渡して関数実行

概要

前の記事で、 【サービス > CloudWatch】 は直感でわかるから、やり方は(略)とかしてしまったが、複数のTwitterアカウントを区別して動作するスクリプトを作成してた後、関数を事項するトリガーとして準備するCloudWatchのルールから引数としてアカウント名を渡す方法がパッとわからなかったので追記。

やり方

【サービス > CloudWatch > ルール】
"ターゲット"を指定する際に、定数 (JSON テキスト)を選択して、下記を入力。

 { "accountName": "hoge" }

#hogeのところはTwitterのアカウント名を指定

実際のプログラムでは下記で呼び出せる。

def lambda_handler(event, context):
    print(str(event["accountName"]))

#出力: hoge

f:id:orcafamiliar:20210911095447p:plain
定数の指定

Lambdaで自動フォローとリツイート

概要

awsのEC2無料枠で、件名のスクリプトを定期実行していたが、無料期間が終わったので、永続無料のLambdaを使用することにした。 「パラメータストア(Parameter Store)」や「シークレットマネージャー(Secrets Manager)」との連携で手こずったので、メモとして記載。

※ 重要 ※
Twitterにおける自動フォローとリツイートについては自動化ルールの規約に反しない範囲での使用が必要。

パラメータストア(Parameter Store) との連携

【サービス > AWS Systems Manager > パラメータストア 】

  • パラメータを作成(略)

【サービス > Identity and Access Management (IAM) > ロール】

  • パラメータを使用する関数を選択する
    • 事前に関数がある前提、なければ新規作成のハズ
  • アクセス権限tabの[ポリシーをアタッチします]を選択
  • [ポリシーの作成] を選択
  • [JSON]tabを選択して下記を追加 "ssm:PutParameter" がパラメータに書き込むための権限
    "ssm:GetParameters" がパラメータを読み込むための権限
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "ssm:PutParameter",
                "ssm:GetParameter"
                "ssm:GetParameters"
            ],
            "Resource": "*"
        }
    ]
}
  • 適切なポリシー名を設定して保存。

【Lambda > 関数 > パラメータを使用する関数】

  • 読み取り(1つのみ。複数ある時は get_parameters を使用)
    import boto3

    ssm = boto3.client('ssm', 'ap-northeast-1')
    response = ssm.get_parameter(Name="パラメータ名",WithDecryption=False)
    print(response['Parameter']['Value'])
  • 書き込み
    import boto3

    ssm = boto3.client('ssm', 'ap-northeast-1')
    response_put = ssm.put_parameter(
        Name = "パラメータ名",
        Value = str(lastid),  #書き込む値。Typeに合わせること
        Type = 'String',      #パラメータのYype
        Overwrite = True
    )


シークレットマネージャー(Secrets Manager)との連携

AWS Secrets Manager】

  • シークレットの作成

【サービス > Identity and Access Management (IAM) > ロール】

  • シークレットを使用する関数を選択する
    • 事前に関数がある前提、なければ新規作成のハズ
  • アクセス権限tabの[ポリシーをアタッチします]を選択
  • [ポリシーの作成] を選択
  • [JSON]tabを選択して下記を追加
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "secretsmanager:GetSecretValue",
            "Resource": "*"
        }
    ]
}
  • 適切なポリシー名を設定して保存。

【Lambda > 関数 > シークレットを使用する関数】

  • 読み取り
    import boto3
    import json

    client = boto3.client(service_name='secretsmanager')
    get_secret_value_response = client.get_secret_value(SecretId="シークレット名")

    #ディクショナリ型として読み込む
    secret = json.loads(get_secret_value_response['SecretString'])

    secret['呼び出したいシークレットキー']

自動化

【サービス > CloudWatch】
(略:直観的)

定数を渡して関数を実行するのに手間取ったので、下記に記事を追加。

【サービス > CloudWatch】 引数を渡して関数実行

CORNE CHERRYを使ってみた。

購入したもの

購入したものについては、下記記事を参照。 CORNE CHERRYを買ってみた - orcafamiliarのブログ

使ってみて

一番の目的である、肩をすくめないで作業ができることについては、問題はなくできるようになった。
ただ、両手を今回購入したキーボードにすると、ThinkPadの赤ポチが使えなくなるので、右手はThinkPadのキーボードを引き続き使用。
会社に持ち運ぶことを考えても実は片手だけのほうが良い気がするので、一旦は左手だけの運用でキー配列を考えていきたい。

f:id:orcafamiliar:20201126221650p:plain