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]:
-
/callback
エンドポイントでwebhookを受け取ります。 -
受信したwebhookの署名を検証します。
-
イベントタイプに応じて適切なハンドラメソッドを呼び出します。
-
各イベントタイプ(メッセージ、フォロー、フォロー解除、アカウント連携)に対する基本的な処理を実装しています。
-
実際の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/