LoginSignup
23
23

More than 5 years have passed since last update.

java8 を練習しながら line bot を書いてみた

Last updated at Posted at 2016-04-14

java8 + spring-boot で line bot を書きました

  • callback は https://...:443/linebot に
  • 必要情報は環境変数で
  • jackson, httpclient, lombok 使用
  • try catch はノーポリシー

controller

@RestController
public class LineBotController {
    @Autowired
    LineBotService botService;

    @RequestMapping(value = "/linebot")
    String index(HttpServletRequest request) throws RuntimeException {
        botService.sendToChannel(request);
        return "OK";
    }
}

model

// callback にくるやつ
@Data
public class LineBotResponse {
    List<LineBotResponseResult> result;
}

@Data
public class LineBotResponseResult {
    LineBotResponseContent content;
    BigDecimal createdTime;
    String eventType;
    String from;
    BigDecimal fromChannel;
    String id;
    List<String> to;
    BigDecimal toChannel;

}

@Data
public class LineBotResponseContent {
    String toType;
    BigDecimal createdTime;
    String from;
    String location;
    String id;
    List<String> to;
    String text;
    Map<String, String> contentMetadata;
    BigDecimal deliveredTime;
    BigDecimal contentType;
    String seq;

}

// line bot api に投げるやつ
@Data
public class LineBotRequest {
    List<String> to;
    final int toChannel = 1383378250;
    final String eventType = "138311608800106203";
    LineBotResponseContent content;
}

service

@Service
@val
@Slf4j
public class LineBotService {
    final String LINEBOTAPI_ENDPOINT = System.getenv("LINEBOTAPI_ENDPOINT");
    final String LINE_CHANNEL_ID = System.getenv("LINE_CHANNEL_ID");
    final String LINE_CHANNEL_SECRET = System.getenv("LINE_CHANNEL_SECRET");
    final String LINE_CHANNEL_MID = System.getenv("LINE_CHANNEL_MID");

    public void sendToChannel(HttpServletRequest request) {
        try {
            val jb = new StringBuffer();
            request.getReader().lines().forEach(jb::append);

            val mapper = new ObjectMapper();
            val botResponse = mapper.readValue(jb.toString(), LineBotResponse.class);

            botResponse.getResult().stream().forEach(this::sendRequest);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    void sendRequest(LineBotResponseResult botResponse) {
        try {
            val botContent = botResponse.getContent();
            val request = new LineBotRequest();
            request.setTo(Arrays.asList(botContent.getFrom()));
            request.setContent(botContent);
            val text = botContent.getText();
            // 1もじづつばらばらにして送り返す
            Stream<String> stream = Arrays.stream(text.split(""));
            val post = new HttpPost(LINEBOTAPI_ENDPOINT);
            post.setHeader("Content-Type", "application/json; charset=UTF-8");
            post.setHeader("X-Line-ChannelID", LINE_CHANNEL_ID);
            post.setHeader("X-Line-ChannelSecret", LINE_CHANNEL_SECRET);
            post.setHeader("X-Line-Trusted-User-With-ACL", LINE_CHANNEL_MID);
            try (val httpclient = HttpClients.createDefault()) {
                stream.forEach(e -> sendOneRequest(httpclient, post, request, e));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    void sendOneRequest(CloseableHttpClient client, HttpPost post, LineBotRequest request, String oneString) {
        try {
            request.getContent().setText(oneString);
            val mapper = new ObjectMapper();
            val json = mapper.writeValueAsString(request);

            post.setEntity(new StringEntity(json, StandardCharsets.UTF_8));
            val res = client.execute(post);

            try (val br = new BufferedReader(
                    new InputStreamReader(res.getEntity().getContent(), StandardCharsets.UTF_8))) {
                br.lines().forEach(e -> log.info(e.toString()));
            } catch (IOException e) {
                e.printStackTrace();
            }
            log.info("STATUSLINE:" + res.getStatusLine().toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

build.gradle

dependencies {
    compileOnly('org.projectlombok:lombok')
    compile('org.springframework.boot:spring-boot-starter-web')
    compile('com.fasterxml.jackson.core:jackson-databind:2.7.0')
    compile('com.fasterxml.jackson.core:jackson-annotations:2.7.0')
    compile('com.fasterxml.jackson.core:jackson-core:2.7.0')
    compile('org.apache.httpcomponents:httpasyncclient:4.1.1')
    compile('org.apache.httpcomponents:httpcore-nio:4.4.4')
}

task wrapper(type: Wrapper) {
    gradleVersion = '2.12'
}
23
23
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
23
23