slontが2016年10月4日に投稿(2016年10月6日更新)

無限の可能性を感じる…(?)

0. はじめに

つい先日、遂にLINEのMessaging APIが公開されました。これを機に、今までLINE@に手を出していなかった個人・法人も、一斉に開発に乗り出すのではないでしょうか。

さて、早速このMessaging APIをJavaでさくっと試してみました。LINE@宛にメッセージが飛んできたら、それをWebhookで拾って、固定メッセージを返すという、超基本的サンプル的なものです。

さくっとなんで、説明もさくっとやります。


1. ざっくり用意するもの

  • Java8
  • Servlet(Tomcat)(Spring版SDKはこちらで公開されてます)
  • Jackson(JsonNode用)
  • Httpsサーバ(ちゃんと使えるやつを用意)


2. まずは登録から

こちらから登録します。手順などは割愛します。


3. Channel Secretとかをメモる

登録が済んだら、LINE Developersに行く。そして以下の画面を探す。 このChannel SecretChannel Access Tokenをメモる。


4. HTTPSのURLをWebhook URLに設定

HTTPSの環境構築はこれまた別の話なので割愛。


構築が済んだら、Webhook URLに登録する。画像は既に登録済み。ユーザからメッセージがあると、このURLにPOSTでリクエストが飛ぶようになる。VERIFYボタンでちゃんと使えるか確認できる。
リファレンス


5. ソースコード

省略してるところもありますが、大体以下のような感じ。

@WebServlet(name="LineServlet", urlPatterns={"/line"})
public class LineServlet extends HttpServlet {  
    private static final String CHANNEL_SECRET = "channel_secret";
    private static final String CHANNEL_ACCESS_TOKEN = "channel_access_token";
    private static final String HMAC_SHA256 = "HmacSHA256";

    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 署名検証
        String body = null;
        try (Stream<String> stream = request.getReader().lines()) {
            String signature = request.getHeader("X-Line-Signature");
            body = stream.reduce((s1, s2) -> s1 + "\n" + s2).orElse("");
            SecretKeySpec key = new SecretKeySpec(CHANNEL_SECRET.getBytes(), HMAC_SHA256);
            Mac mac = Mac.getInstance(HMAC_SHA256);
            mac.init(key);
            byte[] source = body.getBytes(StandardCharsets.UTF_8);
            String createdSignature = Base64.encodeBase64String(mac.doFinal(source));
            if (!signature.equals(createdSignature)) {
                // LINEからのリクエストじゃない場合の処理
                // 常に200を返す
                response.setStatus(200);
                return;
            }
        } catch (IOException e) {
        } catch (NoSuchAlgorithmException e) {
        } catch (InvalidKeyException e) {}

        ObjectMapper mapper = new ObjectMapper();
        JsonNode events = mapper.readTree(body).path("events");
        // リプライの種類(今回はtext)
        String type = events.path(0).path("message").path("type").asText(null);
        // テキスト
        String query = events.path(0).path("message").path("text").asText(null);
        // 返信用Token
        String replyToken = events.path(0).path("replyToken").asText(null);
        // リプライを送る
        HttpPost httpPost = new HttpPost("https://api.line.me/v2/bot/message/reply");
        httpPost.setHeader("Content-Type", "application/json");
        httpPost.setHeader("Authorization", "Bearer " + CHANNEL_ACCESS_TOKEN);
        // 返信用のJSON
        // サンプルとして「リプライありがとう!」を返す
        String replyBody = String.format("{\"replyToken\":\"%s\", \"messages\":[{\"type\":\"text\", \"text\":\"リプライありがとう!\"}]}", replyToken);
        StringEntity params = new StringEntity(replyBody, StandardCharsets.UTF_8);
        httpPost.setEntity(params);
        try (CloseableHttpClient client = HttpClients.createDefault();
                CloseableHttpResponse resp = client.execute(httpPost);
                BufferedReader br = new BufferedReader(new InputStreamReader(resp.getEntity().getContent(), StandardCharsets.UTF_8)))
        {
            int statusCode = resp.getStatusLine().getStatusCode();
            switch (statusCode) {
            case 200:
                // ↓これは空のJSON({})が返るはず
                br.readLine();
                break;
            default:
            }
        } catch (final ClientProtocolException e) {
        } catch (final IOException e) {
        }
        response.setStatus(200);
    }
}

署名検証がちと長いかな。
以降の処理はよしなに書いてください。


6. LINE@アカウントにメッセージを送ってみよう

個別返信は出来ないと言っていたアカウントが…





こうじゃ!



ちゃんとお礼を言えるようになりました。良い子。


7. まとめ

めちゃくちゃ簡単に自動返信ができるようになりました。後はメッセージを解析してよしなに返信するスクリプトを組めば、もうLINEの既読に悩まされることも、未読スルーも関係ありませんね。

みなさんも是非Messaging APIを活用して、素敵なLINEライフを送りましょう!


参考

公式リファレンス

↑気に入ったらシェアしてね↑
プロフィール
slont

slont

元金融エンジニア。メイン言語はJava, HTML, JavaScript, Python, Kotlinあたり。SECCONやCTF、NLP、機械学習に興味あり。金融日記購読4年。巷で話題の変態紳士。美女ソムリエ始めてました。 お仕事の依頼はTwitterからお願いします。

comments powered by Disqus
Back to top