2
0

AWS+Lambda+API+GOでオウム返しLine Bot

Last updated at Posted at 2024-02-22

はじめに

  • 「AWSとGoを勉強したい!」ということで、オウム返しをするLine Botを作成しようと思いました。
  • AWSを使ったサーバーレスの基本の勉強にもなってよかったです!

目標

  • 以下の感じでオウム返ししてくれるbotを作成します。
    oumu_kansei.png

全体の構造

  • Lineにメッセージを送ると、LINEプラットフォームは設定されたWebhook URLに対してPOSTリクエストを送信する。
  • API Gatewayは、このリクエストをトリガーにLambda関数を実行する。
  • Lambda関数はGo言語で書かれたコードを実行する。

line_bot_aws_oumu.drawio.png

作成手順

手順1:LINE Developersの作成とログイン

  • 以下のサイトからDevelopersの作成とログインが行えます。

  • 作り方がわからない人は以下が参考になります。
  • 作成したボットを友達追加しとくと便利です!

手順2:IAMロールの作成

  • Lambdaを使う際には、IAMロールを作成して、権限を設定する必要があります。
  • 作成しなくてもデフォルトロールが割り振られますが、デフォルトロールに権限のない操作(データベースの読み書きなど)を行うとエラーが出るので、IAMロールをあらかじめ作っておくのがおすすめです。

作成方法

  • 「IAM>ロール」からロールを作成する
  • 信頼されたエンティティタイプ:AWSのサービス
  • サービスまたはユースケース:Lambda
  • AWSLambdaBasicExecutionRoleを検索して付与
  • ロール名を任意に設定して作成します。

lambdaの作成

作成方法

  • lambda>関数の作成
  • 「一から作成」を選択
  • 関数名:「EchoLineBotHandler」に設定します。
  • ランタイム:「Amazon Linux 2023」に設定します。
  • デフォルトの実行ロール変更>既存のロールを使用から、先ほど作成したIAMロールを指定します。

Untitled (8).png

Goコードを作成

  • 次にGoでオウム返しするコードを書きます。以下がコードになります。
package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"os"

	"github.com/aws/aws-lambda-go/events"
	"github.com/aws/aws-lambda-go/lambda"
	"github.com/line/line-bot-sdk-go/linebot"
)

type Webhook struct {
	Destination string           `json:"destination"`
	Events      []*linebot.Event `json:"events"`
}

func handler(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
	// LINE Botの初期化
	bot, err := linebot.New(
		os.Getenv("LINE_CHANNEL_SECRET"),
		os.Getenv("LINE_CHANNEL_ACCESS_TOKEN"),
	)
	if err != nil {
		log.Print(err)
		return events.APIGatewayProxyResponse{
			StatusCode: http.StatusInternalServerError,
			Body:       fmt.Sprintf(`{"message":"%s"}`, http.StatusText(http.StatusInternalServerError)),
		}, nil
	}

	// リクエストボディを解析
	var webhook Webhook
	if err := json.Unmarshal([]byte(request.Body), &webhook); err != nil {
		log.Print(err)
		return events.APIGatewayProxyResponse{
			StatusCode: http.StatusBadRequest,
			Body:       fmt.Sprintf(`{"message":"%s"}`, http.StatusText(http.StatusBadRequest)),
		}, nil
	}

	// イベント処理
	for _, event := range webhook.Events {
		// イベントが一般的なメッセージイベントの場合
		if event.Type == linebot.EventTypeMessage {
			switch message := event.Message.(type) {
			// メッセージイベントの中身がテキストの場合(画像とかではなく)
			case *linebot.TextMessage:
				//オウム返し
				if _, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(message.Text)).Do(); err != nil {
					log.Print(err)
					return events.APIGatewayProxyResponse{
						StatusCode: http.StatusInternalServerError,
						Body:       fmt.Sprintf(`{"message":"%s"}`, http.StatusText(http.StatusInternalServerError)),
					}, nil
				}
			}
		}
	}

	return events.APIGatewayProxyResponse{
		StatusCode: 200,
		Body:       `{"message":"Success"}`,
	}, nil
}

func main() {
	lambda.Start(handler)
}

手順3:Goコードをzip化

  • LambdaにGoコードをアップロードするにはzipファイルである必要があります。
  • Goコードをzipファイルにするやり方は環境によって違い、以下のリンクを参考に行うことができます。

私は、windowsでPowerShelです。人によって違うので参考程度に!
# lambdaパッケージをインストール。
# Lambdaと関数コードの間の相互作用を管理するランタイムインターフェイスの実装を提供
go get github.com/aws/aws-lambda-go/lambda

# 実行可能ファイルと必要なファイル群を正しくZIP形式でパッケージングしてくれるツール
go install github.com/aws/aws-lambda-go/cmd/build-lambda-zip@latest

# power shellでビルドした
# このコードの開設は、GPTがしてくれたよ!
$env:GOOS = "linux"
$env:GOARCH = "amd64"
$env:CGO_ENABLED = "0"
go build -tags lambda.norpc -o bootstrap main.go
~\Go\Bin\build-lambda-zip.exe -o myFunction.zip bootstrap

GPTのお言葉

  1. 環境変数の設定:
    • $env:GOOS = "linux": Goのコンパイルターゲットのオペレーティングシステム(OS)をLinuxに設定します。AWS Lambdaの実行環境はLinuxであるため、これに合わせてコンパイルする必要があります。
    • $env:GOARCH = "amd64": コンパイルターゲットのアーキテクチャをamd64(x86_64)に設定します。これは現在のところ、AWS Lambdaでサポートされている主なアーキテクチャです。
    • $env:CGO_ENABLED = "0": CGOを無効にします。CGOはC言語のコードをGoコードに組み込むために使用されますが、Lambda環境ではC言語のライブラリを利用することが推奨されていません。これにより、ポータビリティと互換性を高めることができます。
  2. コンパイルコマンド:
    • go build -tags lambda.norpc -o bootstrap main.go: Goのビルドコマンドを使用して、**main.goファイルから実行可能ファイルをコンパイルします。ビルドタグlambda.norpcを使用して、特定のLambdaの最適化を有効にする場合があります。出力ファイル名はbootstrapと指定されています。AWS Lambdaでは、カスタムランタイムを使用する場合、実行ファイルの名前をbootstrap**にする必要があります。
  3. パッケージングコマンド:
    • ~\Go\Bin\build-lambda-zip.exe -o myFunction.zip bootstrap: 事前にインストールした**build-lambda-zipツールを使用して、bootstrap実行ファイルを含むZIPファイルを作成します。このZIPファイルは、Lambdaへのアップロードに使用され、myFunction.zip**という名前で出力されます。
  • 「lambda>関数>コード」から、zipファイル化出来たらLambda関数に作成したzipファイルをアップロードします。

upload.png

手順4:Lambda関数で環境変数を設定

  • Goコード内には環境変数を使っているので、環境変数を設定する必要があります。
  • 具体的には以下のコード部分です。
os.Getenv("LINE_CHANNEL_SECRET"),
os.Getenv("LINE_CHANNEL_ACCESS_TOKEN"),
  • 「lambda>関数>設定>環境変数」から、設定します。
  • それぞれの値に関しては、Line Debeloppersから確認できます。
    • キー:LINE_CHANNEL_SECRET 値:Line Debeloppersから確認
    • キー:LINE_CHANNEL_ACCESS_TOKEN 値:Line Debeloppersから確認

手順5:APIの作成

  • 「API Gateway>API」からAPIを作成します。
    • APIタイプ:「Rest API」
    • API名:「LineEchoAPI」

rest_api.png

  • 次は「API Gateway>API>リソース」から、リソースを作成します。
    • リソース名:「echo」
    • CORSにチェックを入れる

resosu.png

  • 「API Gateway>API>リソース」から、メソッドを作成します。
    • メソッドタイプ:「POST」
    • 統合タイプ:「Lambda関数」
    • Lambdaプロキシ統合にチェックを入れる
    • Lambda関数を、先ほど作った関数に指定

mesod-new.png

  • 「APIデプロイ」を押してデプロイします。
  • ステージ名は、開発フェーズならdev、本番ならprodとかおすすめです。
    • ステージ:「新しいステージ」
    • ステージ名:「dev」

deploy.png

  • 最後に、「API Gateway>API>ステージ」から、作成したAPIのURLをコピーしておきます。

Untitled (9).png

手順6:Line DeveloperのWebhookを設定

  • 自身のLine Developerから、「Messaging API設定>Webhook設定」を開きます。
    • Webhook URL:先ほどコピーしたURL/リソース名
    • Webhookの利用にチェックを入れる

Untitled (10).png

手順7:完成!!

  • 結構大変でした。。。

oumu_kansei.png

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0