From 853e6c81ae92c14e4aeaa800740079ac6390b513 Mon Sep 17 00:00:00 2001 From: Shion Ichikawa Date: Sat, 12 Oct 2024 02:12:36 +0900 Subject: [PATCH 1/4] =?UTF-8?q?=F0=9F=94=A7=20use=20panic=20for=20config?= =?UTF-8?q?=20load=20error?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/config/config.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/config/config.go b/pkg/config/config.go index 9a05f93..2bc4ca1 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -1,8 +1,8 @@ package config import ( + "fmt" "gopkg.in/yaml.v3" - "log/slog" "os" ) @@ -17,11 +17,11 @@ func init() { Config = config{} loc := os.Getenv("ENV_LOCATION") if loc == "" { - slog.Error("No ENV_LOCATION found") + panic("No ENV_LOCATION found") return } if err := yaml.Unmarshal([]byte(loc), &Config); err != nil { - slog.Error("Failed to unmarshal yaml", err) + panic(fmt.Errorf("failed to unmarshal yaml: %w", err)) return } } From eed9e9ba52fac99b1a32fe3965b732fcc9d4155c Mon Sep 17 00:00:00 2001 From: Shion Ichikawa Date: Sat, 12 Oct 2024 02:43:43 +0900 Subject: [PATCH 2/4] =?UTF-8?q?=E2=9C=A8=20pkg/service/line?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/service/line/line_bot.go | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 pkg/service/line/line_bot.go diff --git a/pkg/service/line/line_bot.go b/pkg/service/line/line_bot.go new file mode 100644 index 0000000..ed68136 --- /dev/null +++ b/pkg/service/line/line_bot.go @@ -0,0 +1,30 @@ +package line + +import ( + "fmt" + "github.com/a-company/yoriai-backend/pkg/config" + "github.com/line/line-bot-sdk-go/v7/linebot" + "log/slog" +) + +type LINEBotService struct { + client *linebot.Client +} + +func NewLINEBotService() (*LINEBotService, error) { + secret := config.Config.LineConfig.ChannelSecret + tkn := config.Config.LineConfig.AccessToken + bot, err := linebot.New(secret, tkn) + if err != nil { + return nil, fmt.Errorf("failed to create line bot: %w", err) + } + return &LINEBotService{ + client: bot, + }, nil +} + +func (l *LINEBotService) ReplyTextMessage(replyToken, message string) { + if _, err := l.client.ReplyMessage(replyToken, linebot.NewTextMessage(message)).Do(); err != nil { + slog.Error("failed to reply message", err) + } +} From dbf1ad128fffcb5814e9b78cc4dc1e51aa1b5f72 Mon Sep 17 00:00:00 2001 From: Shion Ichikawa Date: Sat, 12 Oct 2024 02:44:27 +0900 Subject: [PATCH 3/4] =?UTF-8?q?=E2=9C=A8=20handler/line?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/config/line.go | 2 +- pkg/handler/line.go | 77 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 pkg/handler/line.go diff --git a/pkg/config/line.go b/pkg/config/line.go index 226dc7d..8d34e43 100644 --- a/pkg/config/line.go +++ b/pkg/config/line.go @@ -3,5 +3,5 @@ package config type LineConfig struct { ClientID string `yaml:"channel_id"` ChannelSecret string `yaml:"channel_secret"` - ChannelToken string `yaml:"channel_access_token"` + AccessToken string `yaml:"channel_access_token"` } diff --git a/pkg/handler/line.go b/pkg/handler/line.go new file mode 100644 index 0000000..bbf114c --- /dev/null +++ b/pkg/handler/line.go @@ -0,0 +1,77 @@ +package handler + +import ( + "github.com/a-company/yoriai-backend/pkg/config" + "github.com/a-company/yoriai-backend/pkg/service/line" + "github.com/gin-gonic/gin" + "github.com/line/line-bot-sdk-go/v8/linebot/webhook" +) + +type LINEWebhookHandler struct { + lineBotSvc *line.LINEBotService +} + +func NewLINEWebhookHandler(lineBotSvc *line.LINEBotService) *LINEWebhookHandler { + return &LINEWebhookHandler{ + lineBotSvc: lineBotSvc, + } +} + +func (l *LINEWebhookHandler) Handle(c *gin.Context) { + req, err := webhook.ParseRequest(config.Config.LineConfig.ChannelSecret, c.Request) + if err != nil { + return + } + + for _, event := range req.Events { + switch event.GetType() { + case "join": + // join: When your LINE Official Account joins a group chat or multi-person chat. You can reply to this event. + case "accountLink": + // accountLink: When a user has linked their LINE account with a provider's service. You can reply to this event. + case "activated": + // activated: When a user has linked their LINE account with a provider's service. You can reply to this event. + case "beacon": + // beacon: When a user enters the range of a LINE Beacon. You can reply to this event. + case "botResumed": + // botResumed: When a LINE Official Account that was suspended is resumed. You can reply to this event. + case "botSuspended": + // botSuspended: When a LINE Official Account is suspended. You can reply to this event. + case "deactivated": + // deactivated: When a user has unlinked their LINE account from a provider's service. You can reply to this event. + case "delivery": + // delivery: When a message is successfully delivered to a user. You can't reply to this event. + case "follow": + // follow: When a user adds your LINE Official Account as a friend, or unblocks your LINE Official Account. You can reply to this event. + case "leave": + // leave: When a user deletes your LINE Official Account or your LINE Official Account leaves, from a group chat or multi-person chat. + case "memberJoined": + // memberJoined: When a user joins a group chat or multi-person chat that your LINE Official Account is a member of. You can reply to this event. + case "memberLeft": + // memberLeft: When a user leaves a group chat or multi-person chat that your LINE Official Account is a member of. + case "message": + // message: When a user sends a message. You can reply to this event. + case "module": + // module: When a user interacts with a module. You can reply to this event. + case "postback": + // postback: When a user triggers a postback action. You can reply to this event. + case "things": + // things: When a user interacts with a LINE Things-compatible device. You can reply to this event. + case "unfollow": + // unfollow: When a user blocks your LINE Official Account. + case "unsend": + // unsend: When a user unsends a message. For more information on handling this event, see Processing on receipt of unsend event. + case "videoPlayComplete": + // videoPlayComplete: When a user finishes watching a video message that has a trackingId specified sent from the LINE Official Account. You can reply to this event. + } + } +} + +func (l *LINEWebhookHandler) HandleJoinEvent(event *webhook.FollowEvent) { +} + +func (l *LINEWebhookHandler) HandleMessageEvent(event *webhook.MessageEvent) { +} + +func (l *LINEWebhookHandler) HandleLeaveEvent(event *webhook.UnfollowEvent) { +} From 9d4a95ac4a0af84acfa9936bed783a22f6159e90 Mon Sep 17 00:00:00 2001 From: Shion Ichikawa Date: Sat, 12 Oct 2024 02:46:23 +0900 Subject: [PATCH 4/4] =?UTF-8?q?=E2=9C=A8=20use=20/line/webhook=20in=20main?= =?UTF-8?q?.go?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.go | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/main.go b/main.go index d162fa2..1eec4a4 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,11 @@ package main -import "github.com/gin-gonic/gin" +import ( + "github.com/a-company/yoriai-backend/pkg/handler" + "github.com/a-company/yoriai-backend/pkg/service/line" + "github.com/gin-gonic/gin" + "log/slog" +) func main() { e := gin.Default() @@ -10,5 +15,14 @@ func main() { "message": "Hello World", }) }) + + lineBotSvc, err := line.NewLINEBotService() + if err != nil { + slog.Error("failed to initialize line bot service", err) + return + } + + lineWHandler := handler.NewLINEWebhookHandler(lineBotSvc) + e.Any("/line/webhook", lineWHandler.Handle) e.Run(":8080") }