![](https://www.kuretom.com/wp-content/uploads/2024/03/b6aec8b6998f5de9bdf868d07e751af7.png)
色々なサイトを見に行かなくていいから便利だね。
AWS LambdaやAPI Gatewayを利用し、ChatGPTやNEWS API、LINE APIを組み合わせて、最新ニュースをLINEで受け取れるアプリを作ります。
AWSでの設定や実装のステップ、APIのコードもご紹介するので、ぜひ最後までご覧ください!
Contents
アプリの概要
![](https://www.kuretom.com/wp-content/uploads/2024/06/architecture-1024x567.jpg)
まずユーザーがLINEにメッセージを送ると、Lambda関数がトリガーされます。
Lambda関数はAPI Gatewayを通じてリクエストを受け取ります。
次にNEWS APIから最新ニュースを取得し、その内容をOpenAIのGPTで要約します。
最後に、要約した内容をLINEに送り返すという流れです。
- ユーザーがLINEでメッセージを送信
ユーザーがLINEアプリで特定のキーワードを含むメッセージを送信します。 - LINE APIがWebhookにメッセージを送信
LINEプラットフォームは、送信されたメッセージをWebhook URLに設定されたAPI Gatewayエンドポイントに送信します。 - API Gatewayがリクエストを受け取る
API GatewayがWebhookからのリクエストを受け取り、設定されたLambda関数を呼び出します。 - Lambda関数がリクエストを処理
Lambda関数が起動し、受け取ったイベントデータをFlaskアプリケーションに渡します。 - Flaskアプリケーションがメッセージを解析
Flaskアプリケーションは、LINEからのメッセージを解析し、ユーザーの入力を取得します。 - NEWS APIを呼び出してニュースを取得
FlaskアプリケーションがNEWS APIを呼び出して、ユーザーが指定したキーワードに基づいて最新のニュース記事を取得します。 - ChatGPT APIを呼び出して記事を要約
取得したニュース記事の内容をChatGPT APIに送り、記事の要約を生成します。 - LINE APIを呼び出して要約をユーザーに送信
要約されたニュース記事をLINE APIを使って、ユーザーに返信メッセージとして送信します。 - レスポンスをLINEに返す
Flaskアプリケーションが処理完了のステータスをLINEに返し、Lambda関数もAPI Gatewayに成功ステータスを返します。 - ユーザーがLINEで要約されたニュースを受信
ユーザーはLINEアプリ上で、要約されたニュース記事のメッセージを受け取ります。
以下のGithubに、本アプリのソースコードを格納しています。
必要に応じて、ご参照下さい。
Githubソースコード格納先
主な構成要素
主な構成要素は以下の通りです。
- AWSアカウント
- EC2(Python3.12のライブラリのzipファイル作成用)
- AWS Lambda
- API Gateway
- LINE Developerアカウント
- OpenAI APIアカウント(ChatGPT用)
- NEWS APIアカウント
これらのツールを使って、各種APIを組み合わせてアプリを作ります。
AWSアカウントの作成
![](https://www.kuretom.com/wp-content/uploads/2024/06/image-2.png)
本記事で紹介するアプリは、AWSサービスを使います。
アカウントを持っていない方は、AWSアカウント作成画面から作成しましょう。
OpenAI APIキー取得(ChatGPT用)
GPTのAPIを使用するためには、OpenAIのAPIキーが必要です。
APIキーを取得されていない方は、まずOpenAIのAPI発行画面からAPIキーを発行しましょう。
Create new secret keyを押下します。
![](https://www.kuretom.com/wp-content/uploads/2024/03/7bd690889c3abe40c548b87fd2254679.png)
「Create secret key」を押下します。
![](https://www.kuretom.com/wp-content/uploads/2024/03/b3af09bfe59bb4329dc3b1bc53db095b.png)
作成されたキーをコピーしておきます。
画面を閉じてしまうとキーがコピーできなくなるため、注意してください。
![](https://www.kuretom.com/wp-content/uploads/2024/03/4aff9a2829233c4003514c3472e0cb0e.png)
項目 | 内容 | Pythonコードの記載例 |
---|---|---|
API名 | OpenAI API | |
APIエンドポイント | https://api.openai.com/v1/chat/completions | |
リクエストメソッド | POST | response = requests.post(url, headers=headers, json=data) |
パラメータ | model: 使用するモデルの名前 messages: 会話のメッセージリスト max_tokens: 生成するトークンの最大数temperature: 生成するテキストの多様性 | model = 'gpt-4' messages = [{"role": "user", "content": "こんにちは"}] max_tokens = 100 temperature = 0.7 |
レスポンス形式 | JSON | response.json() |
主要フィールド | id: 応答の一意のID object: 応答のオブジェクトタイプ created: 応答が生成されたタイムスタンプchoices: 生成されたテキストのリスト | id = response.json()['id'] object = response.json()['object'] created = response.json()['created'] choices = response.json()['choices'] |
choicesフィールド | index: 応答のインデックス message: 応答のメッセージ finish_reason: 応答が終了した理由 | index = choice['index'] message = choice['message']['content'] finish_reason = choice['finish_reason'] |
import requests
import os
OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')
def get_summary_from_chatgpt(text):
url = 'https://api.openai.com/v1/chat/completions'
headers = {
'Authorization': f'Bearer {OPENAI_API_KEY}',
'Content-Type': 'application/json'
}
data = {
'model': 'gpt-4',
"messages": [{"role": "user", "content": f'次の英語の文章を日本語で要約してください:\n\n{text}'}],
'max_tokens': 500,
'temperature': 0.7
}
response = requests.post(url, headers=headers, json=data)
if response.status_code == 200:
response_json = response.json()
return response_json['choices'][0]['message']['content'].strip()
else:
print(f'Error summarizing text: {response.status_code}')
return ''
NEWS APIキーの取得
![](https://www.kuretom.com/wp-content/uploads/2024/06/image.png)
最新のニュース記事はをNews APIを用いて取得します。
以下の手順でNEWS APIから記事を取得しましょう。
ニュースAPIの取得
以下のコードを使って、NEWS APIから最新のニュース記事を取得します。
項目 | 内容 | Pythonコードの記載例 |
---|---|---|
API名 | News API | |
APIエンドポイント | https://newsapi.org/v2/everything | |
リクエストメソッド | GET | response = requests.get(url) |
パラメータ | q: 検索クエリ pageSize: 取得する記事の数 apiKey: 認証用APIキー | query = 'technology' page_size = 3 NEWS_API_KEY = os.getenv('NEWS_API_KEY') |
レスポンス形式 | JSON | response.json() |
主要フィールド | status: APIリクエストのステータスtotalResults: 検索結果の総数 articles: 記事のリスト | status = response.json()['status'] total_results = response.json()['totalResults'] articles = response.json().get('articles', []) |
記事フィールド | source: 記事のソース author: 著者 title: タイトル description: 記事の説明 url: 記事のURL urlToImage: 記事の画像URL publishedAt: 公開日時 content: 記事の内容 | source = article['source']['name'] author = article['author'] title = article['title'] description = article['description'] url = article['url'] url_to_image = article['urlToImage'] published_at = article['publishedAt'] content = article['content'] |
import requests
import os
NEWS_API_KEY = os.getenv('NEWS_API_KEY')
def get_latest_news(query, page_size=3):
url = f'https://newsapi.org/v2/everything?q={query}&pageSize={page_size}&apiKey={NEWS_API_KEY}'
response = requests.get(url)
if response.status_code == 200:
articles = response.json().get('articles', [])
for article in articles:
article['content'] = fetch_full_article(article['url'])
return articles
else:
return []
また、今回はNEWS APIで取得したURLを元に、スクレイピングを実施します。
これにより、記事の本文を取得することができます。
def fetch_full_article(url):
try:
response = requests.get(url)
if response.status_code == 200:
soup = BeautifulSoup(response.content, 'html.parser')
paragraphs = soup.find_all('p')
full_text = ' '.join([para.get_text() for para in paragraphs])
return full_text
else:
print(f'Error fetching full article: {response.status_code}')
return ''
except Exception as e:
print(f'An error occurred: {e}')
return ''
LINE APIの設定
- LINE Developersアカウントの作成
- 新しいチャネルの作成
- チャネルアクセストークンの取得
- Webhookの設定
LINE Developersアカウントの作成
まず、LINE Developersの公式サイト(https://developers.line.biz/ja/?status=success)にアクセスして、LINE Developersアカウントを作成します。
既にアカウントを持っている場合は、ログインします。
![](https://www.kuretom.com/wp-content/uploads/2024/06/a1217081256e7d8f21d57ea746556500-1024x383.jpg)
新しいチャネルの作成
LINE Developersコンソールにログインしたら、「プロバイダーを作成」をクリックし、プロバイダー名を入力して作成します。
![](https://www.kuretom.com/wp-content/uploads/2024/06/4fc5df079b1cb4ca9900cc43e1511b19.png)
![](https://www.kuretom.com/wp-content/uploads/2024/06/139c3adda843496f7bc493265036a057.png)
次に、「Messaging API」を選択し、新しいチャネルを作成します。
![](https://www.kuretom.com/wp-content/uploads/2024/06/4bd4e00f5716cacc1cec8053f359d2b8.png)
チャネルの作成画面で必要な情報(アプリ名、説明、プロフィール画像など)を入力します。
利用規約に同意して「作成」ボタンをクリックします。
![](https://www.kuretom.com/wp-content/uploads/2024/06/148cb8d0e77c6e022be09f1abf3c51f6.png)
チャネルアクセストークンの取得
チャネルが作成されたら、そのチャネルの設定画面に移動します。
![](https://www.kuretom.com/wp-content/uploads/2024/06/77b1dde9e36692d1660cb47608868fe1.png)
「Messaging API設定」タブに移動し、「チャネルアクセストークン」セクションにある「発行」ボタンをクリックして、チャネルアクセストークンを発行します。
![](https://www.kuretom.com/wp-content/uploads/2024/06/d8cd0ca2708fd790e5154f0f7a4959b4.png)
発行されたアクセストークンをメモしておきます。
これは、LINEと通信するために必要になります。
Webhookの設定
「Messaging API」タブの「Webhook設定」セクションに移動します。
「Webhookの利用」をONにします。
![](https://www.kuretom.com/wp-content/uploads/2024/06/9e76ad4518b19368abad5155aea79847.png)
WebhookのURLはAPI Gatewayの設定時に記載します。
LINE API用のソースコード作成
以下のコードを使って、ニュース記事をLINEに送信するために使います。
import requests
import os
LINE_ACCESS_TOKEN=os.getenv('LINE_ACCESS_TOKEN')
user_id = os.getenv('USER_ID')
def send_news_to_line(reply_token, message):
url = 'https://api.line.me/v2/bot/message/push'
headers = {
'Content-Type': 'application/json',
'Authorization': f'Bearer {LINE_ACCESS_TOKEN}'
}
data = {
'to': user_id,
'messages': [{'type': 'text', 'text': message}]
}
response = requests.post(url, headers=headers, json=data)
if response.status_code == 200:
print('Message sent')
else:
print(f'Error sending message: {response.status_code}')
これで、LINE APIを使ってユーザーにニュースを送信できるようになりました。
項目 | 内容 | Pythonコードの記載例 |
---|---|---|
API名 | LINE Messaging API | |
APIエンドポイント | https://api.line.me/v2/bot/message/push | |
リクエストメソッド | POST | response = requests.post(url, headers=headers, json=data) |
dataパラメータ | to: メッセージを送信するユーザーID messages: 送信するメッセージのリスト | to = 'USER_ID' messages = [{"type": "text", "text": "Hello, world"}] |
ヘッダー | Content-Type: application/json Authorization: Bearer {LINE_ACCESS_TOKEN} | headers = {'Content-Type': 'application/json', 'Authorization': f'Bearer {LINE_ACCESS_TOKEN}'} |
レスポンス形式 | JSON | response.json() |
主要フィールド | messageId: メッセージの一意のID statusCode: リクエストのステータスコード | message_id = response.json()['messageId'] status_code = response.status_code |
LINE APIは無料版(コミュニケーション)だと、メッセージ数は200/月の制限有りです。
それを超えると、レート制限(429エラー)となり、送信が不可になるようです。
![](https://www.kuretom.com/wp-content/uploads/2024/06/c57087ec8003cad5aab26b1267d8b15b-1024x245.png)
↓↓
メッセージ数が200を超えた場合
↓↓
![](https://www.kuretom.com/wp-content/uploads/2024/06/0729e0cca4313b90643cbfe4610d513c.png)
AWS Lambdaの設定
![](https://www.kuretom.com/wp-content/uploads/2024/03/image-1.png)
Lambda関数では、実際の処理を実装します。
今回はLINEのテキストを入力として、API Gateway経由でリクエストを受け取り、Lambda(Flask、NEWS API、ChatGPT API)経由でニュース記事の要約したものをLINEに応答として返す処理をPythonにて実装します。
- Lambda関数の作成
- Pythonコード作成
- レイヤーの設定(Python3.12ライブラリ)
- 環境変数を設定
以下のGithubに、本アプリのソースコードを格納しています。
必要に応じて、ご参照下さい。
Githubソースコード格納先
Lambda関数の作成
Lambdaのコンソール画面から、「関数の作成」ボタンを押下します。
![](https://www.kuretom.com/wp-content/uploads/2024/03/4f6f25accdca3ff8418a77eac659eac3.png)
以下の値で作成します。
- 関数名:任意
- ランタイム:Python3.12
- アーキテクチャ:x86_64
![](https://www.kuretom.com/wp-content/uploads/2024/03/10531b60eb37890c36a2c4f44417951f.png)
「関数の作成」ボタンを押下し、Lambda関数を作成します。
以下のように、関数が作成できていることを確認します。
![](https://www.kuretom.com/wp-content/uploads/2024/06/a752987df1ba09790c70516c7c619ecc.png)
Lambdaレイヤーにライブラリのzipファイルをアップロード
Lambdaのコンソール画面から、レイヤーを選択します。
(Python3.12の環境用にライブラリをzip化したものをアップロードします。)
![](https://www.kuretom.com/wp-content/uploads/2024/03/fe498820680a82083eb27c24f9782be1.png)
「レイヤーの作成」を押下し、作成したzipファイルをアップロードしてください。
この時、ランタイムはPython3.12としてください。
![](https://www.kuretom.com/wp-content/uploads/2024/03/ea9eaa1895c0346cbcffb0d9c5a62189-1.png)
対象のlambda関数にて、「レイヤーを追加」を押下します。
先ほどアップロードしたカスタムレイヤーを選択して、「追加」を押下します。
![](https://www.kuretom.com/wp-content/uploads/2024/06/23429c69a56902c91e897546c0f6e780.png)
APIキーを環境変数として設定
Lambdaの「設定」から、「環境変数」を選択します。
以下のように、OpenAIのAPIキー、NEWS APIキーなどを環境変数として追加します。
![](https://www.kuretom.com/wp-content/uploads/2024/06/9f40697b3380102cc994437314839a05.png)
これでLambda関数の設定は完了です。
次はAPI Gatewayの設定を行います。
API Gatewayの設定
![](https://www.kuretom.com/wp-content/uploads/2024/06/image-1-1024x578.png)
API Gatewayの設定を始めます。
- REST APIを作成
- /webhookリソースを作成し、POSTメソッドを追加
- Lambda統合を設定し、先ほど作成したLambda関数を選択
REST APIを作成
API Gatewayコンソールに移動し、新しいAPIを作成します。
「HTTP API」または「REST API」のどちらかを選択します(この例ではREST APIを使用します)。
![](https://www.kuretom.com/wp-content/uploads/2024/06/952db77e2e6761c734f6df47c042b92f.png)
![](https://www.kuretom.com/wp-content/uploads/2024/06/9d928b9e94d620f9ac6dbf5ac957a939.png)
/webhookリソースを作成し、POSTメソッドを追加
APIに/webhook
という名称でリソースを作成し、そのリソースに対してPOSTメソッドを追加します。
![](https://www.kuretom.com/wp-content/uploads/2024/06/b117eab8c49deae395e650b4453a8711.png)
Lambda統合を設定し、先ほど作成したLambda関数を選択
作成したPOSTメソッドの統合タイプを「Lambda関数」に設定し、先ほど作成したLambda関数を選択します。
![](https://www.kuretom.com/wp-content/uploads/2024/06/6c1253d4128f3f921d9eb72db3169300-1.png)
Webhook URLの設定
API Gatewayでデプロイを行い、エンドポイントURLを取得します。
このURLをLINE DevelopersコンソールのWebhook URLに設定します。
![](https://www.kuretom.com/wp-content/uploads/2024/06/adbda7d5fa9e0056b0e84bc478edfebf.png)
![](https://www.kuretom.com/wp-content/uploads/2024/06/0cb89069db95897bd2df40091710d896.png)
![](https://www.kuretom.com/wp-content/uploads/2024/06/d75819514490392fa452e65073871846-1.png)
これで、API GatewayがLINEからのリクエストをLambda関数に渡す準備が整いました。
デプロイとテスト
最後にデプロイとテストを実施し、実際の動作確認を行います。
- Lambda関数をデプロイ
- API GatewayのエンドポイントURLをLINE DevelopersコンソールのWebhook URLに設定
- LINEでメッセージを送信してテスト
Lambda関数からDeployを実行する
![](https://www.kuretom.com/wp-content/uploads/2024/06/5937b37b598766006fe025e83947e5fb.png)
LINEからの動作確認
作成したLINEアカウントにて、メッセージを送信します。
キーワードに応じたニュース記事が返答されれば成功です!
![](https://www.kuretom.com/wp-content/uploads/2024/06/a8d3873c37a87c6e1db8819354deba7f-1024x474.png)
返答されたニュース記事は、URLから本文を確認することもできます。
![](https://www.kuretom.com/wp-content/uploads/2024/06/d38f290d8512e8ef96d81529f49d7e52-1024x506.jpg)
まとめ
今回は、AWSを使ってLINEニュースボットを構築する方法を紹介しました。
いろいろなAPIを組み合わせて、一つの便利なツールを作ることができました。
次のステップとして、ボットの機能を拡張したり、他のAPIを組み合わせたりすることが考えられます。
便利な機能が思いつけば、また実装を試みてみようと思います。
最後まで読んでいただきありがとうございました。
ではでは。
海外のニュース記事をLINEから簡単に見れるようにしてみたよ。