Springboot + Slack bot 으로 지하철 알림 보내기

특정 시간대에 같은 지하철을 타기 때문에 타는 시간에 지하철 정보를 슬랙봇으로 알림이 가도록 할 것이다.

1. 의존성 추가

이전에 devtools에서 작성한 쿼리대로 가져오도록 하기 위해서 의존성을 추가해준다.

	implementation 'org.elasticsearch.client:elasticsearch-rest-high-level-client'
	implementation 'co.elastic.clients:elasticsearch-java:7.16.3'

2. 엘라스틱 연결

application.yml 파일에 url, port를 지정해준 후 @Value로 가져오도록 한다. 또한 엘라스틱 연동 방법 중에서 HighLevelClient로 연결을 해준다.

    @Value(value = "${elasticsearch.host}")
    String url;
    @Value(value = "${elasticsearch.port}")
    int port;
    static RestHighLevelClient client;

    public void init()
    {
        client = new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost(url, port, "http")));
    }

3. 쿼리 작성

    public Map<String,Object> search_one(String name,String text)throws IOException {

        init();

        Map<String, Object> result = null;
        //조회 할 인덱스 지정
        SearchRequest searchRequest = new SearchRequest("realtime-subway");
        //쿼리 지정
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.matchQuery(name, text))
                .sort(new FieldSortBuilder("realtimeArrivalList.recptnDt").order(SortOrder.DESC));

        searchSourceBuilder.from(0);
        searchSourceBuilder.size(1);

        //searchRequset에 빌더 지정
        searchRequest.source(searchSourceBuilder);

        try {
            SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
            for (SearchHit s : searchResponse.getHits().getHits()) {
                result = s.getSourceAsMap();
            }
            return result;
        } catch (IOException e) {
            System.err.println("Elastic search fail");
        }
        return null;
    }

이전에 devtools에서 작성한 쿼리대로 가져와준다. matchQuery로 어떤 방면인지 검색하도록하고, recptnDt 기준으로 내림차순 정렬을 통해 가장 최신의 데이터를 들고오도록 한다.

4. 스프링 스케줄러

특정 시간에 알림이 오도록 하기 위해서 스케줄러를 이용한다. fixed, cron 정규식으로 시간을 지정할 수 있으며 이번에는 로그스태시와 마찬가지로 cron 정규식을 이용하도록 하였다.

@RequiredArgsConstructor
@Configuration
@EnableScheduling
public class SlackScheduler {
    private final SlackService slackService;
    private final ElasticService elasticService;

    @Scheduled(cron="0/60 * * * * *") //1분에 한 번씩
    public void slackScheduler() throws IOException {
        String responseMessage = subway();
		//슬랙 메시지 전송
        slackService.postSlackMessage(responseMessage);
    }

    private String subway() throws IOException {
        Map<String, Object> result = elasticService.search_one("realtimeArrivalList.trainLineNm", "이수");

        String responseMessage = "🚊 지하철 알림 🚊"+ "\n";

		//메시지 파싱
        String[] results = result.get("realtimeArrivalList").toString()
                .replace("{","").replace("}","")
                .split(",");

        for (String s : results) {
            String[] split = s.split("=");
            System.out.println(split[0]);
            responseMessage += split[1] +"\n";
        }
        return responseMessage;
    }
}

엘라스틱에서 가져온 데이터를 적절히 파싱한 후, 슬랙에 메시지를 보내도록 한다. 테스트 용으로 1분 간격으로 시행해보았으며, 크론식을 다음과 같이@Scheduled(cron = "0 0 18 ? * MON-FRI") 로 이용해 평일 18시에 알림을 보내도록 할 수 있다.

🙌 슬랙 전송 결과

좋은 웹페이지 즐겨찾기