LoginSignup
3
8

More than 5 years have passed since last update.

Lambda(Java)を使ってLINE Message APIとやり取りする

Last updated at Posted at 2017-02-18

使用サービス

  • AWS API Gateway
  • AWS Lambda
  • LINE Message API

開発環境等

  • Java 1.8
  • Eclipse
  • Maven

目的

  • Line Message APIとの話の仕方を知りたい
  • AWS Lambdaの使い方を知りたい。

この記事で説明を省いていること

  • LINEのアカウント開設やWebhook URLの設定

  • API Gatewayの設定の仕方

  • Line Message API側で"Server IP Whitelist"を設定し、AWS側でも認証させる仕組み

  • リクエストの送信元がLINEであることを確認するために署名検証

  • Lineで設定されるChannel Access TokenはLambdaの環境変数から取得する仕組み

手順

1. LINE Message API

  1. アカウント開設
  2. Webhook URLの設定

2. AWS API Gateway

  1. リソース作成
  2. 作成したリソースとLambda Functionを連携

3. Lambda Function

3.1. JSONをPOJOで受け取るためのInputクラス作成
3.2. Outputクラス作成
3.3. InputからreplyToken, text取得し、Outputに格納。合わせてReply Messageに必要な情報もセット。
3.4. OutputをJSONに変換
3.5. リクエストを生成し送信
3.6. 全体コード

3.1. JSONをPOJOで受け取るためのInputクラス作成

下記のJSONオブジェクトが送信されるので、Inputクラスもそれに合わせて構築する

{
  "events": [
    {
      "replyToken": "nHuyWiB7yP5Zw52FIkcQobQuGDXCTA",
      "type": "message",
      "timestamp": 1462629479859,
      "source": {
        "type": "user",
        "userId": "U206d25c2ea6bd87c17655609a1c37cb8"
      },
      "message": {
        "id": "325708",
        "type": "text",
        "text": "Hello, world"
      }
    },
    {
      "replyToken": "nHuyWiB7yP5Zw52FIkcQobQuGDXCTA",
      "type": "follow",
      "timestamp": 1462629479859,
      "source": {
        "type": "user",
        "userId": "U206d25c2ea6bd87c17655609a1c37cb8"
      }
    }
  ]
}
Input.java
package jp.linebot;

import java.util.List;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Input {

    private Events[] events;

}
Events.java
package jp.linebot;

import org.joda.time.DateTime;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Events {
    private String replyToken;
    private String type;
    private Long timestamp;
    private Source source;
    private Message message;    
}
Source.java
package jp.linebot;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Source {
    private String type;
    private String userId;
}
Message.java
package jp.linebot;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Message {
    private String id;
    private String type;
    private String text;    
}

3.2. Outputクラス作成

Output.java
package jp.linebot;

import java.util.ArrayList;
import java.util.List;

import lombok.Data;

@Data
public class Output {

    private String replyToken;
    private List<Messages> messages = new ArrayList<>();
}
Messages.java
package jp.linebot;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Messages {

    private String type;
    private String text;
}

3.3. InputからreplyToken, text取得し、Outputに格納。合わせてReply Messageに必要な情報もセット。

Output output = new Output();
output.setReplyToken(input.getEvents()[0].getReplyToken());
Messages outMessage = new Messages();
outMessage.setType("text");
outMessage.setText(input.getEvents()[0].getMessage().getText() + "?");
output.getMessages().add(outMessage);

3.4. OutputをJSONに変換

Gson gson = new Gson();
context.getLogger().log(gson.toJson(output));

3.5. リクエストを生成し送信

httpPost = new HttpPost("https://api.line.me/v2/bot/message/reply");
httpPost.setHeader("Content-Type", "application/json");
httpPost.setHeader("Authorization", "Bearer " + "{Channel Access Token}");
StringEntity entity = new StringEntity(gson.toJson(output), StandardCharsets.UTF_8);
httpPost.setEntity(entity);

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:
            br.readLine();
            break;
        default:
        }
    } catch (final ClientProtocolException e) {
    } catch (final IOException e) {
}
return null;

3.6. 全体コード

LambdaFunctionHandler.java
package jp.linebot;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;

import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.google.gson.Gson;

public class LambdaFunctionHandler implements RequestHandler<Input, Object> {

    @Override
    public Object handleRequest(Input input, Context context) {
        // TODO Auto-generated method stub

        context.getLogger().log("token : " + input.getEvents()[0].getReplyToken());
        context.getLogger().log("text : " + input.getEvents()[0].getMessage().getText());

        Output output = new Output();
        output.setReplyToken(input.getEvents()[0].getReplyToken());
        Messages outMessage = new Messages();
        outMessage.setType("text");
        outMessage.setText(input.getEvents()[0].getMessage().getText() + "?");
        output.getMessages().add(outMessage);

        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}");

        Gson gson = new Gson();
        context.getLogger().log(gson.toJson(output));
        StringEntity entity = new StringEntity(gson.toJson(output), StandardCharsets.UTF_8);
        httpPost.setEntity(entity);
        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:
                br.readLine();
                break;
            default:
            }
        } catch (final ClientProtocolException e) {
        } catch (final IOException e) {
        }
        return null;
    }

}

参考リンク

3
8
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
3
8