Closed5
linebot作りを試す

dockerfile
FROM golang:1.22 AS builder
WORKDIR /workspace
# Go Modules のキャッシュを利用
COPY go.mod go.sum ./
RUN go mod download
# ソースコードをコピーしてビルド
COPY lambda_function.go lambda_function.go
RUN go build -tags lambda.norpc -o main lambda_function.go
# Runtime stage: AWS Lambda 用の Go ランタイムイメージを利用
FROM public.ecr.aws/lambda/provided:al2023
# ビルド済みバイナリを配置
COPY /workspace/main ./main
# Lambda のハンドラとして main バイナリを指定
ENTRYPOINT [ "./main" ]

terraformのlambda部分
# lambda
resource "aws_lambda_function" "main" {
function_name = "example-lambda"
package_type = "Image"
image_uri = "xxx:latest"
timeout = 30
role = aws_iam_role.main.arn
environment {
variables = {
LINE_CHANNEL_SECRET = "xxx"
CHANNEL_ACCESS_TOKEN = "xxx"
}
}
}
# lambda function url
resource "aws_lambda_function_url" "main" {
function_name = aws_lambda_function.main.function_name
authorization_type = "NONE"
}

line設定
- チャネルを作る
- チャネルシークレット、チャネルアクセストークンを取得しLambdaへ環境変数登録
- terraform apply
- lambdaの関数URLをline側webhookで登録、有効化

goコード
package main
import (
"context"
"log"
"net/http"
"os"
"strings"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
"github.com/line/line-bot-sdk-go/linebot"
)
var bot *linebot.Client
func init() {
// LINE の Channel Secret は環境変数 "LINE_CHANNEL_SECRET" から取得
secret := os.Getenv("LINE_CHANNEL_SECRET")
// Channel Access Token は環境変数 "CHANNEL_ACCESS_TOKEN" から取得
accessToken := os.Getenv("CHANNEL_ACCESS_TOKEN")
var err error
bot, err = linebot.New(secret, accessToken)
if err != nil {
log.Fatalf("Error initializing LINE bot: %v", err)
}
}
func handler(ctx context.Context, req events.LambdaFunctionURLRequest) (events.LambdaFunctionURLResponse, error) {
// Lambda Function URL のイベントから http.Request を生成
r, err := http.NewRequest("POST", "/", strings.NewReader(req.Body))
if err != nil {
log.Printf("Error creating HTTP request: %v", err)
return events.LambdaFunctionURLResponse{StatusCode: 500}, nil
}
// リクエストヘッダーを設定
for key, value := range req.Headers {
r.Header.Set(key, value)
}
// LINE の Webhook リクエストをパース
eventsList, err := bot.ParseRequest(r)
if err != nil {
// 署名エラーの場合は 400 を返す
if err == linebot.ErrInvalidSignature {
return events.LambdaFunctionURLResponse{StatusCode: 400}, nil
}
log.Printf("Error parsing request: %v", err)
return events.LambdaFunctionURLResponse{StatusCode: 500}, nil
}
// 各イベントに対してオウム返しの返信を実行
for _, event := range eventsList {
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.Printf("Error replying to message: %v", err)
}
}
}
}
return events.LambdaFunctionURLResponse{
StatusCode: 200,
Body: "OK",
Headers: map[string]string{
"Content-Type": "text/plain",
},
}, nil
}
func main() {
lambda.Start(handler)
}

オウム返しされたらOK
このスクラップは6ヶ月前にクローズされました