1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

LINE Messaging APIをSDKを使わずにSpring Bootで実装

Posted at

LINE Messaging APIを使用したwebhookベースのbotを、SDKを使わずにSpring BootとJavaで実装する方法が注目されています。このアプローチでは、メッセージ、フォロー、フォロー解除、アカウント連携などの主要なイベントを処理するカスタムコードを作成し、より柔軟で制御可能なボット開発が可能になります。

以下は、LINE Messaging APIのwebhookを受け取るSpring Bootアプリケーションのサンプルコードです。このコードは、メッセージイベント、フォローイベント、フォロー解除イベント、アカウント連携イベントを処理します。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

@SpringBootApplication
@RestController
public class LineBotApplication {

    private static final String CHANNEL_SECRET = "YOUR_CHANNEL_SECRET";

    public static void main(String[] args) {
        SpringApplication.run(LineBotApplication.class, args);
    }

    @PostMapping("/callback")
    public String handleCallback(@RequestBody String requestBody, @RequestHeader("X-Line-Signature") String signature) {
        if (verifySignature(requestBody, signature)) {
            try {
                ObjectMapper objectMapper = new ObjectMapper();
                JsonNode jsonNode = objectMapper.readTree(requestBody);
                JsonNode events = jsonNode.get("events");
                for (JsonNode event : events) {
                    String eventType = event.get("type").asText();
                    switch (eventType) {
                        case "message":
                            handleMessageEvent(event);
                            break;
                        case "follow":
                            handleFollowEvent(event);
                            break;
                        case "unfollow":
                            handleUnfollowEvent(event);
                            break;
                        case "accountLink":
                            handleAccountLinkEvent(event);
                            break;
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return "OK";
    }

    private void handleMessageEvent(JsonNode event) {
        String messageType = event.get("message").get("type").asText();
        String userId = event.get("source").get("userId").asText();
        System.out.println("Received message from user: " + userId);
        // メッセージタイプに応じた処理を実装
    }

    private void handleFollowEvent(JsonNode event) {
        String userId = event.get("source").get("userId").asText();
        System.out.println("User followed: " + userId);
        // フォロー時の処理を実装
    }

    private void handleUnfollowEvent(JsonNode event) {
        String userId = event.get("source").get("userId").asText();
        System.out.println("User unfollowed: " + userId);
        // フォロー解除時の処理を実装
    }

    private void handleAccountLinkEvent(JsonNode event) {
        String userId = event.get("source").get("userId").asText();
        String result = event.get("link").get("result").asText();
        System.out.println("Account link event for user: " + userId + ", result: " + result);
        // アカウント連携時の処理を実装
    }

    private boolean verifySignature(String requestBody, String signature) {
        try {
            Mac mac = Mac.getInstance("HmacSHA256");
            SecretKeySpec secret = new SecretKeySpec(CHANNEL_SECRET.getBytes(), "HmacSHA256");
            mac.init(secret);
            byte[] hash = mac.doFinal(requestBody.getBytes());
            String calculatedSignature = Base64.getEncoder().encodeToString(hash);
            return calculatedSignature.equals(signature);
        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
            e.printStackTrace();
            return false;
        }
    }
}

このサンプルコードでは、以下の処理を実装しています[1][3][6]:

  1. /callbackエンドポイントでwebhookを受け取ります。

  2. 受信したwebhookの署名を検証します。

  3. イベントタイプに応じて適切なハンドラメソッドを呼び出します。

  4. 各イベントタイプ(メッセージ、フォロー、フォロー解除、アカウント連携)に対する基本的な処理を実装しています。

  5. 実際のLINE Messaging APIの応答を実装するには、LINE PlatformへのHTTPリクエストを送信する必要があります。これはhandleMessageEventなどのメソッド内で実装します[11][14]。

このコードを使用するには、CHANNEL_SECRETを自分のLINEチャネルのシークレットに置き換える必要があります。また、実際のアプリケーションでは、セキュリティを強化し、エラー処理を追加し、LINE Platformへの応答を実装する必要があります[15][16]。

Citations:
[1] https://github.com/hunkim/Line-chatbot-for-COMP3111/blob/master/line-bot-spring-boot/README.md
[2] https://stackoverflow.com/questions/78526601/line-webhook-not-getting-active-programatically/78526649
[3] https://github.com/line/line-bot-sdk-java/
[4] https://syogo0417.hatenablog.com/entry/2017/08/23/130004
[5] https://developers.line.biz/ja/docs/messaging-api/receiving-messages/
[6] https://developers.line.biz/en/docs/messaging-api/receiving-messages/
[7] https://innovationm.co/line-messaging-api-integration-with-spring-boot/
[8] https://www.divx.co.jp/media/techblog-231220-02
[9] https://github.com/line/line-bot-sdk-java/
[10] https://qiita.com/blue_islands/items/582db1f8354aadea4f70
[11] https://developers.line.biz/ja/docs/messaging-api/nodejs-sample/
[12] https://kikutaro777.hatenablog.com/entry/2017/01/16/230122
[13] https://stackoverflow.com/questions/79021823/line-messaging-api-webhook-stuck-in-standby-mode-despite-being-set-to-active
[14] https://zenn.dev/otkshol/articles/52d2649c6fa4dc
[15] https://github.com/line/line-bot-sdk-java/issues/515
[16] https://developers.worksmobile.com/jp/docs/bot-callback
[17] https://qiita.com/shindo_ryo/items/54fccbe09ca904b4b9e8
[18] https://github.com/gishi-yama/linebot-java-handson/blob/master/doc/Basics/05.md
[19] https://udemy.benesse.co.jp/development/app/line-bot-making.html
[20] https://blog.socialplus.jp/knowledge/line-webhook/

1
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?