Post List

2019년 3월 13일 수요일

R을 이용한 텔레그램봇 만들기 (시장 레포트 텔레그램으로 전송하기)


업무의 자동화가 회사 생활을 편하게 만들듯이, 투자 관련 각종 데이터나 성과 리포트의 자동화도 여러분의 투자를 매우 편하게 만들어 줄 수 있습니다. 그 중 텔레그램을 이용한 각종 데이터 전송은 이미 많이 쓰이고 있는 기법입니다.

파이썬을 이용한 텔레그램으로의 데이터 전송은 이미 쉽게 찾아볼 수 있지만, R을 이용한 텔레그램과의 연동을 찾아보기가 힘들어, 한번 만들어 보았습니다.

그 예제로써 시장 관련 애널리스트 레포트를 크롤링 한 후, 이를 텔레그램으로 전송하는 방법을 살펴보도록 하겠습니다.


텔레그램 메신저들은 다들 설치되어 있다고 믿고, 여러분이 만들 채팅방의 API를 부여받아야 합니다. 먼저 ID에서 BotFather 를 검색합니다. 



텔레그램 메신저 자체의 봇이 나타납니다. /start 를 입력하면 여러분이 사용가능한 각종 명령어를 확인할 수 있습니다. 새로운 여러분만의 생성 및 api를 부여받도록 하겠습니다.




먼저 /newbot 을 입력하면 새로운 봇 생성을 위한 이름을 물으며, 예제로 hqnews_bot 을 입력하였습니다 (봇의 이름은 항상 _bot 으로 끝나야 하며, 기존에 존재하는 이름은 사용할 수 없습니다.)

봇이 생성되면 해당 봇의 HTTP API를 알려줍니다. 이를 까먹지 말고 잘 기억해 두셔야 합니다. 이제 이 API 값을 이용하여 R과 텔레그램을 연결해 보도록 합시다.


# telegram
# install.packages('telegram.bot')
library(telegram.bot)

bot = Bot(token = "YOUR API KEY")
print(bot$getMe())

$id
[1] 704368869

$is_bot
[1] TRUE

$first_name
[1] "fin_news_bot"

$username
[1] "hqnews_bot"


먼저 telegram.bot 패키지를 설치한 후 열어주도록 합니다. 그 후 Bot() 함수 내의 토큰 값에 여러분이 위에서 부여받은 API 키를 입력해 주도록 합니다. 이후 getMe() 함수를 통해 출력을 해보면 여러분이 부여받은 API 값에 해당하는 봇의 정보가 나타나게 됩니다.


그 후 R과 대화방을 연결하기 위해 반드시 텔레그램 내에서 테스트용 메시지를 보내야 합니다.




이제 대화방의 id를 찾아보도록 하겠습니다.

updates = bot$getUpdates()
updates[[1]]$message$chat

$id
[1] 26796xxxx

$first_name
[1] "현열"

$last_name
[1] "이"

$username
[1] "xxxxxxx"

$type
[1] "private"


먼저 bot$getUpdates()를 통해 채팅방의 업데이트 내용을 받도록 합니다. 이 중 첫번째 리시스트의 message 클래스의 chat 항목이 채팅방 정보에 대한 내용입니다. 이중 $id에 해당하는 부분이 채팅방 ID에 해당하는 부분입니다.


chat_id = updates[[1]]$message$chat$id
> chat_id
[1] 2679xxxx

id에 해당하는 부분을 chat_id 변수에 저장합니다. 이제 위에서 구해진 id를 바탕으로 해당 대화방에 테스트용 메세지를 전송해 보도록 하겠습니다.


bot$sendMessage(chat_id = chat_id, text = "Henry Quant")



wow!!! 우리가 text에 입력한 Henry Quant라는 단어가 제대로 전송되었습니다. 이처럼 API 연결과 채팅방 ID 연결이 되었으므로, bot$sendMessage() 혹은 bot$sendPhoto() 함수를 통해 원하는 정보를 텔레그램에 전송할 수 있습니다.

이제는 시장 레포트의 제목 및 url을 전송하는 예제를 살펴보도록 하겠습니다.




먼저 한경컨센서스의 시장 탭에 있는 내용들을 크롤링 하도록 하겠습니다. (크롤링 하는법에 대한 설명은 기존에 이미 많이 하였으므로 생략하도록 하겠습니다. 궁금하시면 코드를 라인 바이 라인으로 따라가시면 됩니다.)


# 한경 컨센서스 크롤링
url = 'http://hkconsensus.hankyung.com/apps.analysis/analysis.list?skinType=market'
down = GET(url) %>% read_html(encoding = 'EUC-KR')

data_url = down %>% html_nodes('.dv_input') %>% html_nodes('a') %>% html_attr('href') %>%
  paste0('http://hkconsensus.hankyung.com', .) 

data_date = down %>% html_nodes('.first.txt_number') %>% html_text()
data_title = down %>% html_nodes('.text_l') %>% html_nodes('a')%>%
  html_text() %>% str_remove_all('.pdf')

data = paste(data_date, data_title, data_url, sep="\n")
data
[1] "2019-03-13\n>> Global Asset Monitor l 2019.03.13\nhttp://hkconsensus.hankyung.com/apps.analysis/analysis.downpdf?report_idx=516902"   
[2] "2019-03-13\n한투의 아침\nhttp://hkconsensus.hankyung.com/apps.analysis/analysis.downpdf?report_idx=516894"                            
[3] "2019-03-13\nStart with IBKS\nhttp://hkconsensus.hankyung.com/apps.analysis/analysis.downpdf?report_idx=516884"                        
[4] "2019-03-13\nKTB MORNING EXPRESS\nhttp://hkconsensus.hankyung.com/apps.analysis/analysis.downpdf?report_idx=516874"                    
[5] "2019-03-13\nDaily KTB Morning Brief\nhttp://hkconsensus.hankyung.com/apps.analysis/analysis.downpdf?report_idx=516873"                
[6] "2019-03-13\n미래에셋대우 Daily\nhttp://hkconsensus.hankyung.com/apps.analysis/analysis.downpdf?report_idx=516862"                     
[7] "2019-03-13\n마감 시장 스크린\nhttp://hkconsensus.hankyung.com/apps.analysis/analysis.downpdf?report_idx=516861"                       
[8] "2019-03-13\nSamsung Daily\nhttp://hkconsensus.hankyung.com/apps.analysis/analysis.downpdf?report_idx=516856"                          
[9] "2019-03-13\n오늘의 테마: 갤럭시S10 판매호조\nhttp://hkconsensus.hankyung.com/apps.analysis/analysis.downpdf?report_idx=516855"        
[10] "2019-03-13\n오늘의 특징주 CJ ENM(035760) 2019-03-12\nhttp://hkconsensus.hankyung.com/apps.analysis/analysis.downpdf?report_idx=516854"
[11] "2019-03-13\n시동 걸린 Bear Market Rally 후반전\nhttp://hkconsensus.hankyung.com/apps.analysis/analysis.downpdf?report_idx=516850"     
[12] "2019-03-13\n1분 브리핑\nhttp://hkconsensus.hankyung.com/apps.analysis/analysis.downpdf?report_idx=516836"                             
[13] "2019-03-13\n마켓 레이더\nhttp://hkconsensus.hankyung.com/apps.analysis/analysis.downpdf?report_idx=516822"                            
[14] "2019-03-13\n약해져도 변심은 아니다\nhttp://hkconsensus.hankyung.com/apps.analysis/analysis.downpdf?report_idx=516820"                 
[15] "2019-03-13\nMORNING CALL\nhttp://hkconsensus.hankyung.com/apps.analysis/analysis.downpdf?report_idx=516791"                           
[16] "2019-03-13\n경기선행지수가 보여준 Bright side\nhttp://hkconsensus.hankyung.com/apps.analysis/analysis.downpdf?report_idx=516784"      
[17] "2019-03-13\n KB Daily\nhttp://hkconsensus.hankyung.com/apps.analysis/analysis.downpdf?report_idx=516762"                              
[18] "2019-03-12\n이은택의 그림으로 보는 전략\nhttp://hkconsensus.hankyung.com/apps.analysis/analysis.downpdf?report_idx=516750"            
[19] "2019-03-12\nGeopolitical Monitor\nhttp://hkconsensus.hankyung.com/apps.analysis/analysis.downpdf?report_idx=516744"                   
[20] "2019-03-12\n미래에셋대우 Daily\nhttp://hkconsensus.hankyung.com/apps.analysis/analysis.downpdf?report_idx=516743" 


이제 생성된 data를 sapply를 사용하여 하나씩 채팅방에 보내보도록 하겠습니다.


sapply(data, function(x) {bot$sendMessage(chat_id = chat_id, x)})




레포트 날자 / 레포트 제목 / 레포트 url이 매우 성공적으로 전송되었습니다. 각 url을 클릭하면 해당 레포트를 손쉽게 확인할 수도 있습니다.


이처럼 telegram.bot 패키지를 이용할 경우 R에서 가공한 정보를 매우 손쉽게 텔레그램 채팅방으로 전송할 수 있습니다. 만일 R 내에서 스케쥴러 기능을 사용한다면 정해진 일정마다 동일한 작업을 반복할 수 있을 것입니다. (예: 매일 아침 8시에 오늘 업로드 된 레포트 전송)

또한 웹서버를 이용할 경우 내 pc가 꺼져있어도 해당 작업이 웹이서 이루어지므로, 모든 작업이 자동화 될수 있습니다. 이에 대해서는 다음번에 다시 알아보도록 하겠습니다.

댓글 6개:

  1. 좋은글 감사합니자.telegram.bot 패키지는 어떻게설치하나요?

    답글삭제
    답글
    1. install.package('telegram.bot') 으로요...

      삭제
  2. 안녕하세요 블로그 글 감사하게 보고 있는 1인입니다.
    근데 R 텔레그램은 워낙 자료가 없어서 문제 해결이 안되네요..

    "R과 대화방을 연결하기 위해 반드시 텔레그램 내에서 테스트용 메시지를 보내야 합니다."
    에서 테스트용 메시지를 누구에게 어떻게 보내라는 건지 잘 모르겠습니다..

    "updates[[1]]$message$chat" 입력하면
    "Error in updates[[1]] : subscript out of bounds" 이라고 에러가 떠서 진행이 안되네요..

    저장한 메시지로 저에게 보내거나, 다른 사람한테 테스트로 문자 보내고 나서 실행해도 계속 에러가 뜨는데..
    추가로 설치가 필요한 패키지가 있는지.. 궁금합니다.

    답글삭제
    답글
    1. 만드신 텔레그램봇 방 안에서 메세지 보내셔야 합니다.

      삭제
  3. 안녕하세요 좋은글 항상 잘보고 있습니다.
    저도 윗분과 똑같은 메세지가 떠서 질문드립니다.
    답변해주신것처럼 텔레그램봇 방 안에서 메세지를 보내려면 특정 채팅방을 실행시켜야 하는지
    Bot Father에서 문자를 작성하면 되는지 궁금합니다.
    감사합니다.

    답글삭제
    답글
    1. 같은문제를 겪었는데요 간단한 문제입니다.
      새로운 봇의 이름을 정한후
      봇의 유저네임을 지정을 하게됩니다. (...choose a username for your bot..)
      이때 지정한 유저네임을
      텔레그램 상에서 검색하면 채팅방이 뜹니다
      그 방안에서 메세지를 보내라는 뜻이였네요 ㅎㅎ

      삭제