EclipseでJava Servletを使用したLINE BOTの作成

# はじめに
今回は、Eclipseを使用してJava ServletベースのLINE BOTを作成する方法をご紹介します。このボットは、ユーザーからのメッセージに対して「Hello」と返信するシンプルなものです。

# バージョンアップに関する注意事項
今回のブログ記事はバージョンアップがあったため、新たにまとめ直すことを目的としています。

## From version 7.x
LINEのSDK開発チームはOpenAPI仕様に基づいてSDKコードを生成することを決定しました。その結果、LINE BOTSDK 7.xは6.xとは互換性がありませんが、今後のAPI変更には迅速に対応できるようになります。

- `line-bot-model`と`line-bot-api-client`は`line-bot-webhook`と`clients`モジュールに分割されました。
- `line-bot-servlet`はサポートされなくなりました。
- `line-bot-cli`はサポートされなくなりました。
- `line-bot-spring-boot`は以下のモジュールに分割されました。
  - `line-bot-spring-boot-client`はクライアントのBean設定モジュールです。
  - `line-bot-spring-boot-handler`はハンドラー設定モジュールです。明示的に依存する必要はありません。
  - `line-bot-spring-boot-web`はSpring-Webのバインディングです。明示的に依存する必要はありません。
  - `line-bot-spring-boot-webmvc`はSpring-WebMVCのバインディングです。通常、このモジュールに依存します。

# 必要な準備
- Eclipse IDE
- Java開発環境 (Java 17)
- LINE Developersアカウント
- LINE Messaging APIのチャネル

# プロジェクトの作成
1. **Eclipseで新規Mavenプロジェクトを作成**
    - 「File」→「New」→「Maven Project」
    - 適切なプロジェクト名とグループIDを設定

2. **必要な依存関係を追加**
    ```xml
    <dependencies>
        <dependency>
            <groupId>jakarta.servlet</groupId>
            <artifactId>jakarta.servlet-api</artifactId>
            <version>6.0.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.linecorp.bot</groupId>
            <artifactId>line-bot-messaging-api-client</artifactId>
            <version>8.0.0</version>
        </dependency>
        <dependency>
            <groupId>com.linecorp.bot</groupId>
            <artifactId>line-bot-parser</artifactId>
            <version>8.0.0</version>
        </dependency>
        <dependency>
            <groupId>com.linecorp.bot</groupId>
            <artifactId>line-bot-webhook</artifactId>
            <version>8.0.0</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.16.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.14.0</version>
        </dependency>
    </dependencies>
    ```

# サーブレットの作成
プロジェクトに以下のクラスを追加します。

```java
package jp.livlog.explore.now.servlet;

import java.io.IOException;
import java.util.List;

import org.apache.commons.io.IOUtils;

import com.linecorp.bot.messaging.client.MessagingApiClient;
import com.linecorp.bot.messaging.model.ReplyMessageRequest;
import com.linecorp.bot.messaging.model.TextMessage;
import com.linecorp.bot.parser.LineSignatureValidator;
import com.linecorp.bot.parser.WebhookParser;
import com.linecorp.bot.webhook.model.Event;
import com.linecorp.bot.webhook.model.MessageEvent;
import com.linecorp.bot.webhook.model.TextMessageContent;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;

@WebServlet ("/lineEventHandler")
@Slf4j
public class LineEventHandlerServlet extends HttpServlet {

    @Override
    protected void doPost(final HttpServletRequest request, final HttpServletResponse response)
            throws ServletException, IOException {

        final var json = IOUtils.toByteArray(request.getInputStream());
        final var signature = request.getHeader(WebhookParser.SIGNATURE_HEADER_NAME);

        try {
            final var client = MessagingApiClient.builder(System.getenv("LINE_CHANNEL_ACCESS_TOKEN")).build();
            final var validator = new LineSignatureValidator(System.getenv("LINE_CHANNEL_SECRET").getBytes());
            final var parser = new WebhookParser(validator);
            final var callbackRequest = parser.handle(signature, json);

            for (final Event event : callbackRequest.events()) {
                if (event instanceof MessageEvent) {
                    final var messageEvent = (MessageEvent) event;
                    if (messageEvent.message() instanceof TextMessageContent) {
                        client.replyMessage(new ReplyMessageRequest(
                                messageEvent.replyToken(),
                                List.of(new TextMessage("Hello")),
                                false)).get();
                    }
                }
            }

            response.setStatus(HttpServletResponse.SC_OK);
            response.getWriter().write("Done");

        } catch (final Throwable t) {
            LineEventHandlerServlet.log.error(t.getMessage(), t);
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            response.getWriter().write("Internal Server Error");
        }
    }
}
```

# LINE Messaging APIの設定
1. **LINE Developersコンソールでチャネルを作成**
    - チャネルシークレットとチャネルアクセストークンを取得

2. **環境変数の設定**
    - `LINE_CHANNEL_SECRET` と `LINE_CHANNEL_ACCESS_TOKEN` を環境変数として設定

# 動作確認
1. サーブレットをデプロイ
2. LINEアプリでボットにメッセージを送信
3. ボットからの「Hello」メッセージを確認

# まとめ
以上で、基本的なLINE BOTの作成手順が完了です。これを基にして、さらに高度な機能を持つボットを開発してみてください。