お役立ち Twitter Bot を作りながら学ぶ AWS ドリル
~第 5 回 皆さまの代わりに英語でツイートしておくよ Bot 編
Author : 金澤 圭
ソリューションアーキテクト(SA)の金澤 (@ketancho) です。5 月になりましたが、皆さまいかがお過ごしでしょうか ? 先月は、AWS ドリルに加えて、動画ハンズオンシリーズをご紹介する記事 も書かせていただきました。builders.flash に月に 2 回寄稿するのは初めてで、締切も近かったので実は裏でヒーヒー言っていたのですが、多くの方に読んでいただけたようで嬉しい限りです。
AWS ドリルも動画ハンズオンも、実際に手を動かすことを通して AWS を学ぶコンテンツです。ぜひ、お手元の環境で実験していただきたいです。お試しいただいた際には、#AWSウェブマガジン ハッシュタグをつけてご感想や、フィードバックをもらえると嬉しいです🙏今後の励みにさせていただきます。
この連載記事のその他の記事はこちら
- 選択
- 第 1 回 おはよう Bot 編
- 第 2 回 昔書いた記事の宣伝 Bot 編
- 第 3 回 リファクタリング & 曜日ごとのツイート 編
- 第 4 回 新章突入 ! 気になるワード検索 & 通知 Bot 編
- 第 5 回 皆さまの代わりに英語でツイートしておくよ Bot 編
- 第 6 回 AWS Step Functions を使って Well-being Bot を作ろう ! (前編)
- 第 7 回 AWS Step Functions を使って Well-being Bot を作ろう ! (後編)
- 第 8 回 - 総集編 & 夏休みの自由研究のすすめ
- 第 9 回 - IaC 入門しながら作るリマインダー Bot (前編)
- 第 10 回 - IaC 入門しながら作るリマインダー Bot (中編)
- 完結回 - IaC & CI/CD 入門しながら作るリマインダー Bot (後編)
目次
1. この記事で作る Bot の機能と、とりあげる AWS サービス・機能
3. 新しい Lambda 関数 twitter-bot-translate を作成し、お試しツイートする
3-1. Lambda 関数を新規で作成する
3-2. Lambda 関数に紐づく IAM ロールの修正
3-3. Lambda 関数のコードを修正する
3-4. Lambda 関数の Deploy およびテスト実行
4. Amazon Translate を使い、翻訳メソッドを作成する
4-1. マネジメントコンソールで翻訳機能を使ってみる
4-2. Lambda 関数 twitter-bot-translate を修正する
ご注意
本記事で紹介する AWS サービスを起動する際には、料金がかかります。builders.flash メールメンバー特典の、クラウドレシピ向けクレジットコードプレゼントの入手をお勧めします。
このクラウドレシピ (ハンズオン記事) を無料でお試しいただけます »
毎月提供されるクラウドレシピのアップデート情報とともに、クレジットコードを受け取ることができます。
1. この記事で作る Bot の機能と、とりあげる AWS サービス・機能
さて、今回のドリルのお題は、皆さまの代わりに英語でツイートしておくよ Bot (以下、翻訳 Bot) です。皆さまが日々行っている (日本語の) ツイートをよしなに英語に翻訳してくれる、そんな Twitter Bot を作ります。
私の今年の目標のひとつが「英語をペラペラ喋れるようになる」です。毎年同じことを言っているのですが、日々一進一退を繰り返し、進捗は芳しくありません。私自身が英語堪能になるにはまだまだ時間がかかりそうなので、先に自分の Twitter だけでもグローバルに打って出てもらいたいなと思っています。今回はこんな私と同じく「英語力アップ」を目標を掲げている方向けに、自分が書いたツイートを定期的に取得し、英語に翻訳して発信してくれる Bot を作っていきます。
構成図にも記載しましたが、前提として日頃ツイートしている「普段づかいの」アカウントと「Bot 用の」アカウントが必要になります。前者の日本語ツイートを定期的に検索し、後者から英語に翻訳してツイートするという流れです。
もう少し詳細に翻訳 Bot の要件をお伝えすると、
- 毎時 1 分に下記の処理を実行する
- 対象となるアカウント (私でいうと @ketancho) の直近1時間のツイートを検索する
- ただし、リプライやリツイート (公式・引用) は、この対象から除外する (翻訳した際に別の方に通知が飛ぶおそれがあるので)
- 厳密に書くと、仮に 8 時 01 分にこの Bot が動いたときの検索対象は「7 時 00 分 00 秒 から 7 時 59 分 59 秒にされたツイート」とします
- それらを英語に翻訳し、Bot アカウント (私でいうと @ketancho_bot) からツイートする
- ツイートする際は @ や # を違う文字に置換する (通知が飛んだり、ハッシュタグ検索を汚したりするので)
となります。(なお、処理のタイミングを「毎時 0 分に」としない理由は、最後の落ち穂拾いのセクションで後述します。)
今回新しく利用する AWS サービスは、翻訳サービスである Amazon Translate です。ドリルを通して Amazon Translate の使い勝手・使いどころのイメージをぜひ掴んでいただければと思います。
2. 今回から AWS ドリルを始める方の作業
さて、具体的な作業を始める前に前提を揃えたいと思います。今回も、この記事で完結するので、この記事から読み始めていただいても問題なくドリルを進められるかと思います。ただ、この記事では取り扱わない前提作業を AWS ドリル #4 の「2. 今回から AWS ドリルを始める方の作業」 にまとめています。今回から手を動かすぞ ! という方は、こちらを先にご確認いただければと思います。
また、ツイートする部分やツイートを検索する部分の実装は、これまでのドリルの内容をそのまま使ったり、ベースにしたりしています。実装の意図などは過去の記事をあわせてご参照いただくことで、より理解が深まると思います。
3. 新しい Lambda 関数 twitter-bot-translate を作成し、お試しツイートする
それでは今回の AWS ドリルを進めていきましょう。まずはいつも通り、お試しツイートするまでを最初の作業としています。
3-1. Lambda 関数を新規で作成する
翻訳 Bot 用に新しい Lambda 関数を作ります。AWS Lambda のサービス画面 に遷移し、右上の「関数の作成」をクリックしてください。
関数の基本的な情報には、
- 関数名 : twitter-bot-translate
- ランタイム : Python 3.9
- アーキテクチャ : x86_64
を設定し、「関数の作成」をクリックしてください。
クリックすると拡大します
また、これまでの AWS ドリルでは行っていなかった設定変更をひとつだけ行います
AWS Lambda は Lambda 関数ごとにタイムアウト時間を決めることができます。これまではデフォルトの 3 秒のままにしていたのですが、今回はこの値を 5 秒に変更します。今回のドリルは「1 時間ごとのツイート」を検索して、翻訳する形になりますので、ツイート数が多い方だと、デフォルトの 3 秒では終わらないこともあるかもしれません。私もこの翻訳 Bot を少し運用したのですが、3 秒を超えることはなかったのですが、何度か心もとないことがありました。ドリルでは決め打ちで 5 秒としますが、ツイートの数が多い人は調整が必要かもしれません。
現在、Lambda 関数のソースコードが表示されている画面になっていると思うのですが、こちらを少し上部にスクロールすると、幾つかタブがあると思います。こちらの「設定」タブを選択後、左側にある「一般設定」をクリックしてみてください。現在のタイムアウト値 3 秒が表示されるので、右上の「編集」ボタンをクリックして編集しましょう。
クリックすると拡大します
遷移後の画面で、タイムアウト値を変更できるので、こちらを 5 秒に変更してください。変更したら、右下の「保存」ボタンから元の画面に戻りましょう。
このあとはコードを修正していくので上部の「コード」タブをクリックし、エディタ画面に戻しておいてください。
クリックすると拡大します
続いて、requests_oauthlib という Python モジュールをインストールします。こちらはこれまでのドリルで何度もやっている作業ですね。Twitter API を呼び出すときにこのモジュールを利用するのですが、標準の Lambda 関数には含まれておりません。そのため、requests_oauthlib をインストールし、それを .zip ファイルにまとめ、Lambda 関数にソースコードとしてアップロードします。
今回も AWS CloudShell 上で、作業をします。マネジメントコンソールの右上のコンソールマークをクリックしてください。
クリックすると拡大します
CloudShell のコンソールが起動したら、下記のコマンドを実行してください。(最後のコマンドの後にもエンターを押すのを忘れないように気をつけてください。)
mkdir twitter-bot-translate
cd twitter-bot-translate/
pip3 install -U pip
pip install requests_oauthlib -t ./
touch lambda_function.py
zip -r twitter-bot-translate.zip ./
aws lambda update-function-code --function-name twitter-bot-translate --zip-file fileb://twitter-bot-translate.zip
無事にコマンドが流れ終わったら、先ほど作成した Lambda 関数 twitter-bot-translate を再度表示 (既に表示している人はブラウザをリロード) してください。
エディタの左側に依存パッケージ群が配置され、一番下には lambda_function.py があるはずです。こちらの Python ファイルをダブルクリックして開いてみると、中身が空のファイルが右側に表示されます (現時点で中身は空で大丈夫です)。
クリックすると拡大します
3-2. Lambda 関数に紐づく IAM ロールの修正
続いて、Lambda 関数に紐づく IAM ロールの修正を行います。この作業も前回のドリルと同じ作業で、デフォルトで用意されている IAM ポリシー「AmazonSSMReadOnlyAccess」を Lambda 関数の IAM ロールにアタッチします。ドリル #4 の「3-2. Lambda 関数に紐づく IAM ロールの修正」を参照していただき、ご実施をお願いします。
3-3. Lambda 関数のコードを修正する
IAM ロールの修正が終わったら、先ほど開いた lambda_function.py に下記のプログラムをコピー & ペーストしてみてください。こちらが今回のコードのひな形となります。
import json
import os
from requests_oauthlib import OAuth1Session
from datetime import datetime, timedelta, timezone
import boto3
ssm_client = boto3.client('ssm')
oauth = None
def lambda_handler(event, context):
init()
tweet_text_ja = 'おはようございます、今日は翻訳 Bot を作っていきます。'
tweet(tweet_text_ja)
def init():
response = ssm_client.get_parameter(
Name='/credentials/twitter',
WithDecryption=True
)
twitter_parameters = json.loads(response['Parameter']['Value'])
consumer_key = twitter_parameters['consumer_key']
client_secret = twitter_parameters['client_secret']
access_token = twitter_parameters['access_token']
access_token_secret = twitter_parameters['access_token_secret']
global oauth
oauth = OAuth1Session(consumer_key, client_secret, access_token, access_token_secret)
def tweet(text):
payload = {'text': text}
response = oauth.post(
'https://api.twitter.com/2/tweets',
json=payload,
)
if response.status_code != 201:
raise Exception(
'[Error] {} {}'.format(response.status_code, response.text)
)
今回からドリルを始めた方向けの補足として、ひな形の各メソッドの役割をクイックにお伝えします。
- init メソッド - Twitter API を呼び出す準備を担う
- tweet メソッド - Twitter API のツイート API の呼び出しを担う
前回のドリル #4 で詳細に説明しているので、よければあわせてご覧ください。
3-4. Lambda 関数の Deploy およびテスト実行
コードの更新が終わりましたら、Deploy を忘れずに行いましょう。その後、Test ボタンを押してテスト実行を行うと、「テストイベントの設定」というポップアップが出てくるはずです。これまでのドリルでも触れましたが、lambda_handler メソッドに渡す event を、テスト実行用に設定することができます。今回も、この event は特に利用しないので、イベントの名前を Test としていただき、他は何も変えずに保存してください。
保存後、もう一度 Test ボタンをクリックし、Lambda 関数を実行してみましょう。Bot からこちらのツイートできていれば、下準備が完了です🎉
クリックすると拡大します
4. Amazon Translate を使い、翻訳メソッドを作成する
それでは本題の翻訳部分の実装を進めます。実際のツイートを翻訳する前に、まずは Amazon Translate に慣れていきましょう。
Amazon Translate は高速で高品質かつカスタマイズ可能な言語翻訳を手ごろな料金で提供するニューラル機械翻訳サービスです。(Amazon Translate の料金は、標準翻訳という機能を使う場合は 100 万文字あたり 15.00 USD です。また、最初の翻訳リクエストを作成した日から 12 か月間の無料利用枠がございます。詳細は、Amazon Translate の料金ページ をご覧ください。)
4-1. マネジメントコンソールで翻訳機能を使ってみる
まずはマネジメントコンソールで動きを確認していただき、イメージを掴んでみてください。こちらの Amazon Translate の画面 に遷移してみましょう。
こちらは、リアルタイムに翻訳を行う画面です。この画面で、
- ソース言語 : 日本語 (ja)
- ターゲット言語 : 英語 (en)
と設定し、左下に日本語の文章を入力してみてください。入力が終わると、右側に英語の翻訳結果が出てくるはずです。
クリックすると拡大します
4-2. Lambda 関数 twitter-bot-translate を修正する
続いて、Lambda 関数から Amazon Translate を呼び出す実装を進めます。コードの修正の前に、Amazon Translate を操作する権限を Lambda 関数 twitter-bot-translate に付与します。手順は、本記事の「3-2. Lambda 関数に紐づく IAM ロールの修正」と同じ流れなのですが、
- IAM ポリシーの検索窓には「Translate」と入力する
- 検索にヒットした IAM ポリシーの中から「TranslateReadOnly」を選択する
ようにしてください。(本来は必要最低限の IAM ポリシーを定義し、IAM ロールにアタッチするべきですが、このドリルでは標準で用意されている IAM ポリシーを利用します。)
IAM ロールの修正ができましたら、Lambda 関数のコードを修正し、プログラムから Amazon Translate の機能を呼び出す形にします。これまでのドリルと同じく、AWS SDK for Python のドキュメント を確認し、Python コードから Amazon Translate を利用する方法を確認しながら進めていっていただきたいです。今回は こちらの Amazon Translate に関する部分 が該当箇所となりますので、まずはご一読いただければと思います。
今回やりたいことは、
- translate_ja_to_en メソッドを作成する
- このメソッドには引数 text_ja で日本語の文字列 (ツイート) が渡される
- text_ja を Amazon Translate で英語に翻訳し、翻訳後の文字列を返却する
- lambda_handler メソッド内では下記の修正を行う
- tweet_text_ja に格納されているテキストを引数に、translate_ja_to_en メソッドを呼び出す
- 返却された英語の文字列を、既に用意している tweet メソッドの引数に渡し、ツイートする
になります。こちらの作業ですが、AWS ドリルに慣れてきたよ ! という方は、ぜひ時間を取って、腕試し的にご自身で実装を進めてみてください。
うまく実装できましたでしょうか ? 私は下記のようなコードにしてみました。
import json
import os
from requests_oauthlib import OAuth1Session
from datetime import datetime, timedelta, timezone
import boto3
ssm_client = boto3.client('ssm')
translate_client = boto3.client('translate') # 追加
oauth = None
def lambda_handler(event, context):
init()
tweet_text_ja = 'おはようございます、今日は翻訳 Bot を作っていきます。'
# 修正(ここから)
translated_text_en = translate_ja_to_en(tweet_text_ja)
tweet(translated_text_en)
# 修正(ここまで)
def init():
# 変更なしなので記載を省略
def tweet(text):
# 変更なしなので記載を省略
# 以下を追加
def translate_ja_to_en(text_ja):
response = translate_client.translate_text(
Text=text_ja,
SourceLanguageCode='ja',
TargetLanguageCode='en',
)
return response['TranslatedText']
こちらを Deploy し、Test をしてみてください。このように英語でツイートされましたでしょうか ?
5. Twitter の検索 API を使い過去ツイートを取得し、それらを翻訳ツイートする
さて、翻訳部分のパーツが完成したので、元々のお題に合うように Bot を仕上げていきましょう。冒頭で示したお題を改めて提示します。少しだけ分かりやすいように整理し、この後の実装順に並び替えてあります。
- 対象となるアカウント (私でいうと @ketancho) の直近1時間のツイートを検索する
- ただし、リプライやリツイート (公式・引用) の場合は、この対象から除外する (通知が飛んでしまうので)
- Bot が 8 時 01 分 に動いたときの検索対象は「7 時 0 分 0 秒 から 7 時 59 分 59 秒 にされたツイート」とする
- 取得できたツイートを順番に英語に翻訳し、Bot (私でいうと @ketancho_bot) からツイートする
- ツイートする際は @ や # を違う文字に置換する (通知が飛んだり、ハッシュタグ検索を汚してしまうので)
- 毎時 1 分にこれらの処理を実行する
5-1. 対象となるアカウントの直近1時間のツイートを検索する
まずは対象のアカウントの直近のツイートを取得します。実は、大まかな流れは、前回の AWS ドリル #4 の「4. Twitter の検索 API を使ってみる」と同じなので、まずはこちらをご参照いただければと思います。ただし、前回とは少し異なる実装にする部分があるので、変更点だけ共有します。
- 検索に該当した「ツイートの件数」ではなく、検索に該当した「ツイート情報全て」を JSON 形式で return するようにします。それに伴い、メソッド名を get_matching_tweets に変更します。
- 検索 API の query に渡す情報を from:<対象アカウント名> とし、「対象のアカウントのツイートを検索」する形にします。あわせて引数名も search_query に変更します。
- また、他の人の迷惑にならないよう「リプライやリツイート (公式・引用)」は除外して検索します。例えばリプライを除外して検索するには -is:reply を付けてあげる必要があります。リツイート (公式・引用) も除外する形にすると、最終的な query は、 from:<対象アカウント名> -is:reply -is:retweet -is:quote となります。
こちらを踏まえて、先程までの Lambda 関数のコードを下記のように変更し、Deploy、実行してみてください。
import json
import os
from requests_oauthlib import OAuth1Session
from datetime import datetime, timedelta, timezone
import boto3
ssm_client = boto3.client('ssm')
translate_client = boto3.client('translate')
oauth = None
def lambda_handler(event, context):
init()
# 以下を追加(元々のテストツイート用の3行は削除)
# reply, retweet, 引用 retweet を除外して検索する
search_query = 'from:ketancho -is:reply -is:retweet -is:quote'
now = datetime.now()
start_time = (datetime.now() + timedelta(hours=-1)).strftime('%Y-%m-%dT%H:00:00Z')
end_time = datetime.now().strftime('%Y-%m-%dT%H:00:00Z')
json_response = get_matching_tweets(search_query, start_time, end_time)
print(json_response)
# 追加(ここまで)
def init():
# 変更なしなので記載を省略
def tweet(text):
# 変更なしなので記載を省略
def translate_ja_to_en(text_ja):
# 変更なしなので記載を省略
# 以下を追加
def get_matching_tweets(search_query, start_time, end_time):
url = 'https://api.twitter.com/2/tweets/search/recent'
params = {
'query': search_query,
'max_results': 20,
'start_time': start_time,
'end_time': end_time,
}
response = oauth.get(
url, params=params
)
if response.status_code != 200:
raise Exception(
'[Error] {} {}'.format(response.status_code, response.text)
)
return response.json()
この時点では、tweet メソッドを呼び出していないので、Bot から何かがツイートされるわけではありません。代わりに、直近で何かしらツイートをされている方は print(json_response) の部分で下記のようなログが残るはずです。
{
'data':
[
{'id': '1513050379105497089', 'text': '半ズボンとハンズオンって響きが似ている。'},
{'id': '1513050323317047298', 'text': '半袖、半ズボンで出かけたいくらいには暑い。'},
{'id': '1513050241679097857', 'text': '公園に行くぜ👧👧👶'}
],
'meta':
{
'newest_id': '1513050379105497089',
'oldest_id': '1513050241679097857',
'result_count': 3
}
}
data には、条件に該当したツイート (直近、私のアカウントからされたツイート) が配列で表示されます。この data 部分の各ツイート (text の部分) を、ひとつずつ翻訳していくと、期待する Bot の動きにできそうです。
なお、もし直近にツイートしておらず、該当するツイートがない場合は、下記のように data が含まれない形になります。
{'meta': {'result_count': 0}}
どんな JSON が返ってくるかは、このタイミングで実際に見ていただく方がいいと思うので、普段づかいのアカウントからツイートしていただき、少し待ってからこちらの Lambda 関数を再実行する、あるいは、start_time の + timedelta(hours=-1) の -1 の部分を変更し (例えば -24 にしていただくと 24 時間分が取得できます)、最後にツイートした日時まで検索範囲を広げていただく (検索 API の仕様で、遡れる範囲には限界があることにご注意ください) などで、ぜひ実際のツイートが取得できることをお確かめください。
なお、検索 API の仕様で、
- start_time : 指定した日時ぴったりのツイートは含まれる
- end_time : 指定した日時ぴったりのツイートは含まれない
となります。そのため、N 時 00 分 00 秒ぴったりにツイートした場合でも、2 度翻訳されることはありません。詳細は こちらの Twitter API Doc をご確認いただければと思います。
5-2. 英語に翻訳し、Bot からツイートするようにする
Lambda 関数を仕上げていきましょう。先程 print(json_response) した部分を下記のように変更します。
- 検索にひとつもツイートがヒットしない (検索結果 json_response に data が含まれない) 場合は、何もせず Lambda 関数の処理を終える
- ヒットしたツイートがあれば、下記のルールで翻訳し、Bot からツイートしていく。
- ツイートは降順 (最近のツイートが先) に取得できるので、昇順 (古いツイートが先) に変更し、普段づかいのアカウントと同じ順番で翻訳するようにする
- 通知が飛ぶ、あるいはハッシュタグ検索を汚すことを避けるために、@ は * に、# は + に変換する。
が基本方針になります。よろしければこちらも一度皆さまの力でトライしてみてください。
私は下記のような実装を追加しました。ここでは変更点を細かく分けてお伝えし、最後にコード全体を示す形にします。まず、@ と # を他の文字に置換するメソッドを用意します。
def replace_at_and_sharp_char(text):
return text.replace('@','*').replace('#','+')
そして、先程 print(json_response) していた部分で、ヒットしたツイートの有無の確認とソート順の変更を行います。
if('data' not in json_response):
return
matched_tweets = json_response['data']
matched_tweets.reverse()
こちらで準備が整ったので、ひとつずつ翻訳とツイートを行います。先程作成した @ と # を他の文字に置換するメソッドを呼び出してから、ツイートしていることにご注意ください。
for matched_tweet in matched_tweets:
tweet_text_ja = matched_tweet['text']
translated_text_en = translate_ja_to_en(tweet_text_ja)
tweet(replace_at_and_sharp_char(translated_text_en))
最後に、Lambda 関数全体のコードを示します。もしうまく実装できない場合は、ご参考にしていただければと思います。
import json
import os
from requests_oauthlib import OAuth1Session
from datetime import datetime, timedelta, timezone
import boto3
ssm_client = boto3.client('ssm')
translate_client = boto3.client('translate')
oauth = None
def lambda_handler(event, context):
init()
search_query = 'from:ketancho -is:reply -is:retweet -is:quote'
now = datetime.now()
start_time = (datetime.now() + timedelta(hours=-1)).strftime('%Y-%m-%dT%H:00:00Z')
end_time = datetime.now().strftime('%Y-%m-%dT%H:00:00Z')
json_response = get_matching_tweets(search_query, start_time, end_time)
# 修正・追加(ここから)
if('data' not in json_response):
return
matched_tweets = json_response['data']
matched_tweets.reverse()
for matched_tweet in matched_tweets:
tweet_text_ja = matched_tweet['text']
translated_text_en = translate_ja_to_en(tweet_text_ja)
tweet(replace_at_and_sharp_char(translated_text_en))
# 修正・追加(ここまで)
def init():
response = ssm_client.get_parameter(
Name='/credentials/twitter',
WithDecryption=True
)
twitter_parameters = json.loads(response['Parameter']['Value'])
consumer_key = twitter_parameters['consumer_key']
client_secret = twitter_parameters['client_secret']
access_token = twitter_parameters['access_token']
access_token_secret = twitter_parameters['access_token_secret']
global oauth
oauth = OAuth1Session(consumer_key, client_secret, access_token, access_token_secret)
def tweet(text):
payload = {'text': text}
response = oauth.post(
'https://api.twitter.com/2/tweets',
json=payload,
)
if response.status_code != 201:
raise Exception(
'[Error] {} {}'.format(response.status_code, response.text)
)
def translate_ja_to_en(text_ja):
response = translate_client.translate_text(
Text=text_ja,
SourceLanguageCode='ja',
TargetLanguageCode='en',
)
return response['TranslatedText']
def get_matching_tweets(search_query, start_time, end_time):
url = 'https://api.twitter.com/2/tweets/search/recent'
params = {
'query': search_query,
'max_results': 20,
'start_time': start_time,
'end_time': end_time,
}
response = oauth.get(
url, params=params
)
if response.status_code != 200:
raise Exception(
'[Error] {} {}'.format(response.status_code, response.text)
)
return response.json()
# 以下を追加
def replace_at_and_sharp_char(text):
return text.replace('@','*').replace('#','+')
6. 毎時 1 分に Lambda 関数を実行するように設定し、定期的に翻訳ツイートする
ここまでで Lambda 関数の実装としては完了です。最後に、Amazon EventBridge を使って、1 時間に 1 回、この Lambda 関数が実行されるようにしましょう。
こちらの EventBridge の設定も、AWS ドリル #4 の「5-2. Amazon EventBridge の設定」と基本的には変わりません。ただし、1 点だけ変更点があり、前回は「毎日 1 回、6:01 に」だったのが、今回は「1 時間に 1 回、毎時 1 分に」にする必要があります。こちらもぜひご自身でドキュメントをご確認いただき、試行錯誤しながら設定を進めてみてください。(参考情報 : 『Rate または Cron を使用したスケジュール式』)
私は、下記のように設定を行いました。
- ルール名 : exec-twitter-bot-translate-every-hour-HH01
- ルールタイプ : スケジュール式
- スケジュール式 : cron(1 * ? * * *)
こちらの設定を行った上で、
- 普段づかいのアカウントで、何かしらのツイート (リプライやリツイート (公式・引用) ではない) を行う
- 次の HH:01 を待つ
と、Bot から英訳されたツイートがされるはずです。
例えば、先ほどログとしてご紹介したツイートはこちらなのですが、
このように Bot 側でツイートされていれば成功です🎉
7. 落ち穂拾い & 参考情報
今月も AWS ドリルお疲れ様でした ! この翻訳 Bot の力を借りて、世界に打って出られそうでしょうか ? 落ち穂拾いとして実装しきれていない部分や、お伝えできていない考えをご紹介したいと思います。
実はこれまでの AWS ドリルも同じなのですが、この Bot 開発では、Twitter の文字数制限に配慮していません。Twitter では全角 140 文字、半角 280 文字の制限があることは有名だと思うのですが、今回は「日本語だと文字数制限内におさまるが、英語にすると制限を超えてしまう」ということが往々にしてあると思います。この場合、Your Tweet text is too long. という例外が発生するのですが、今回はそれに対する処理を特にしていません。例えば、「制限文字数に入らない部分は削除する」といった実装にすることもできるかと思います。
今回のドリルを通して「何でこのツイートは翻訳されなかったんだろう ?」と思うことがあれば、Lambda 関数のログをご確認いただければと思います。Lambda 関数のログは、上部の「モニタリング」タブ > 「ログ」ボタン > LogStream から確認できます。
クリックすると拡大します
また、今回のドリルでは、普段づかいのアカウントで「日本語でツイートしている」ことを前提としています。そのため、例えば「今日はフランス語でツイートしちゃうぞ !」ということがある方は、上手く英語に翻訳されないことがあることにご留意ください。(英語ツイートは基本的にはそのまま英語でツイートされる形になります。)
そして、冒頭でも触れた「毎時 0 分に実行」としない理由についてですが、こちらは Twitter 検索 API の仕様のうちのひとつ「end_time は API リクエスト時間より 10 秒以上前であること」に対応するためです。例えば、8 時 00 分に今回の Lambda 関数を動かした場合、end_time に 8 時 00 分 00 秒 が指定されます。EventBridge の実行タイミングによっては、10 秒以内、例えば 8 時 00 分 05 秒に検索 API が実行される可能性があり、その際は API 呼び出しがエラーになってしまうというわけです。これを回避するために、1 分ずらして翻訳 Bot に動いてもらっています。
以上が、今回のドリルの落ち穂拾いになります。最後に、今回の AWS ドリルの Next Action としてオススメのハンズオンを紹介したいと思います。Amazon Translate は AWS の AI サービスのひとつです。AWS には Amazon Translate 以外にも、機械学習の深い知識がなくとも「機能」として機械学習をご利用いただける AI サービス群がございます。例えば、レコメンデーションサービスである Amazon Personalize、時系列予測サービスである Amazon Forecast がこちらに該当します。このような AI サービスを学んでいただける動画ハンズオンを用意していますので、よければあわせてご覧いただければと思います。
Hands-on for Beginners - AWS Managed AI/ML サービス はじめの一歩編 »
こちらは 5 つの AI サービスを実際に試しながらクイックに学んでいただくハンズオンです。こちらのハンズオンでは、下記の AWS サービスを対象にしています。
- Amazon Personalize (レコメンデーション)
- Amazon Forecast (時系列予測)
- Amazon Transcribe (音声データのテキスト変換)
- Amazon Comprehend (自然言語処理)
- Amazon Rekognition (画像・動画分析)
気になるものがありましたら、ぜひお試しいただければと思います。
8. まとめ
「お役立ち Twitter Bot を作りながら学ぶ AWS ドリル」連載の第 5 弾として、皆さまの普段づかいのアカウントのツイートを自動的に翻訳する Twitter Bot を作りました。皆さまの普段づかいのアカウントのツイートを自動的に翻訳する Twitter Bot を作りました。前回同様、実用度が高い Bot にできたのではないかなと思っています。この Bot をきっかけに「英語圏の方からフォローしてもらえた」「英語圏の方から連絡をもらえた」「海外で働くきっかけになった」などなどありましたら、ぜひご報告いただければ嬉しいです🙌
また、今回は Amazon Translate を使ってこの翻訳 Bot の実装を進めました。何か「翻訳」に関する案件がございましたら、ぜひ Amazon Translate をお試しいただければ嬉しいです。
最後に改めてのお願いなのですが、皆さまのご感想・ご要望を #AWSウェブマガジン タグをつけて呟いていただけたら嬉しいです🙏 この記事に +α して、こんなものを作ってみました ! という共有も大歓迎です。今後の連載の参考にさせてもらいたいと思っておりますので、ぜひよろしくお願いしますー !
それでは次回の記事でまたお会いしましょう !
この連載記事のその他の記事はこちら
- 選択
- 第 1 回 おはよう Bot 編
- 第 2 回 昔書いた記事の宣伝 Bot 編
- 第 3 回 リファクタリング & 曜日ごとのツイート 編
- 第 4 回 新章突入 ! 気になるワード検索 & 通知 Bot 編
- 第 5 回 皆さまの代わりに英語でツイートしておくよ Bot 編
- 第 6 回 AWS Step Functions を使って Well-being Bot を作ろう ! (前編)
- 第 7 回 AWS Step Functions を使って Well-being Bot を作ろう ! (後編)
- 第 8 回 - 総集編 & 夏休みの自由研究のすすめ
- 第 9 回 - IaC 入門しながら作るリマインダー Bot (前編)
- 第 10 回 - IaC 入門しながら作るリマインダー Bot (中編)
- 完結回 - IaC & CI/CD 入門しながら作るリマインダー Bot (後編)
筆者プロフィール
金澤 圭 @ketancho
アマゾン ウェブ サービス ジャパン合同会社
技術統括本部 ソリューションアーキテクト
サーバーレスが好きなソリューションアーキテクト。業種業界問わず、お客様のプロダクト開発をサポートさせていただいています。オンデマンドで視聴できるハンズオン「AWS Hands-on for Beginners」、実際にものづくりをしながら AWS を学ぶ「AWS ドリルシリーズ」を企画・推進しており、楽しく学べるコンテンツを日々考えています。好きなサービスは AWS Lambda、AWS Step Functions、Amazon Personalize で、好きな休日の過ごし方は娘ふたりと川の字になって昼寝👧👧と赤ん坊を抱っこしながらの散歩です👶
AWS を無料でお試しいただけます