m_shige1979のときどきITブログ

プログラムの勉強をしながら学習したことや経験したことをぼそぼそと書いていきます

Github(変なおっさんの顔でるので気をつけてね)

https://github.com/mshige1979

BlumixのCFアプリのJavaサーブレットでLINE APIのボットサンプルを作成

Javaはクラスを基準に制御する

のでjson変換するのはjacksonを使用してみた。

LINE API

メッセージを送受信できるAPI
大抵のことはPHPでやっていたけどJavaでやっておく

・署名
json解析
・LINE送信

Jasksonを使うと簡単に解析できる

クラスやクラス内のネスト情報も取得できる

こんな画面

f:id:m_shige1979:20161203210414p:plain

pom.xmlの追加部分

        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
		<dependency>
		    <groupId>com.fasterxml.jackson.core</groupId>
		    <artifactId>jackson-core</artifactId>
		    <version>2.8.5</version>
		</dependency>
		
		<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
		<dependency>
		    <groupId>com.fasterxml.jackson.core</groupId>
		    <artifactId>jackson-annotations</artifactId>
		    <version>2.8.5</version>
		</dependency>
		
		<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
		<dependency>
		    <groupId>com.fasterxml.jackson.core</groupId>
		    <artifactId>jackson-databind</artifactId>
		    <version>2.8.5</version>
		</dependency>

		<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
		<dependency>
		    <groupId>org.apache.httpcomponents</groupId>
		    <artifactId>httpclient</artifactId>
		    <version>4.5.2</version>
		</dependency>

		<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpcore -->
		<dependency>
		    <groupId>org.apache.httpcomponents</groupId>
		    <artifactId>httpcore</artifactId>
		    <version>4.4.5</version>
		</dependency>
		
		<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
		<dependency>
		    <groupId>commons-codec</groupId>
		    <artifactId>commons-codec</artifactId>
		    <version>1.10</version>
		</dependency>

サンプルソース

package wasdev.sample.servlet;

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

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletContext;
import java.io.BufferedReader;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import org.apache.commons.codec.binary.Base64;
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 javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * Servlet implementation class SimpleServlet
 */
@WebServlet("/SimpleServlet")
public class SimpleServlet extends HttpServlet {
    private static final long serialVersionUID = 3L;

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException, JsonParseException, JsonMappingException {
    	
    	ServletContext sc = getServletContext();
    	String num = (String)sc.getAttribute("count");
    	if(null == num){
    		num = "1";
    	} else {
    		num = String.valueOf((Integer.parseInt(num) + 1));
    	}
    	sc.setAttribute("count", num);
    	
    	String body = (String)sc.getAttribute("body");
    	String token = (String)sc.getAttribute("token");
    	String signature = (String)sc.getAttribute("signature");
    	
    	response.setContentType("text/html; charset=UTF-8");
        response.getWriter().print(num);
        response.getWriter().print(body);
        response.getWriter().print(token);
        response.getWriter().print(signature);
    }
    
    @Override    
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{
    	
    	ServletContext sc = getServletContext();
    	String num = (String)sc.getAttribute("count");
    	if(null == num){
    		num = "1";
    	} else {
    		num = String.valueOf((Integer.parseInt(num) + 1));
    	}
    	sc.setAttribute("count", num);
    	
    	// 受信
    	BufferedReader bufferReaderBody = new BufferedReader(request.getReader());
		String body = bufferReaderBody.readLine();
		sc.setAttribute("body", body);
		
		// 署名
		try{
			String channel_secret = "シークレットキー";
			String signature = request.getHeader("X-Line-Signature");
			SecretKeySpec key = new SecretKeySpec(channel_secret.getBytes(), "HmacSHA256");
			Mac mac = Mac.getInstance("HmacSHA256");
			mac.init(key);
	        byte[] source = body.getBytes(StandardCharsets.UTF_8);
	        String createdSignature = Base64.encodeBase64String(mac.doFinal(source));
	        if (!signature.equals(createdSignature)) {
		    	sc.setAttribute("signature", "ng");
	        	response.setStatus(200);
	            return;
	        }else{
		    	sc.setAttribute("signature", "ok");
	        }
		}catch(NoSuchAlgorithmException e){
		}catch(InvalidKeyException e){
		}
		
		// json->オブジェクト変換
		ObjectMapper mapper = new ObjectMapper();
        LineBotResponse result = mapper.readValue(body, LineBotResponse.class);
        
        // イベントデータ取得
        Event event = result.get(0);
            System.out.println(event.replyToken);
    	sc.setAttribute("token", event.replyToken);
    	
    	// 送信データを作成
    	LineBotRequest lineReq = null;
        String json = null ;
        lineReq = new LineBotRequest();
        lineReq.replyToken = event.replyToken;
        lineReq.messages.add(new SendMessageText("hogehoge"));
        json = mapper.writeValueAsString(lineReq);
        
        // 送信処理
        String access_token = "シークレットアクセスキー";
        HttpPost httpPost = new HttpPost("https://api.line.me/v2/bot/message/reply");    
        httpPost.setHeader("Content-Type", "application/json");
       	httpPost.setHeader("Authorization", "Bearer " + access_token);
        StringEntity params = new StringEntity(json, 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) {
        }
    	
    }

}