RSS
백오피스

텔레그램 알림 봇 만들기: BotFather 토큰부터 chat id까지

작성자
듀오랩스 대표·6분 읽기

예약해 둔 작업은 사람이 없는 시각에 서버가 혼자 처리합니다. 잘 끝나면 다행이지만, 중간에 막히면 그 작업은 조용히 대기 상태로 돌아갑니다. 까닭은 기록에 남는데, 기록을 열어 보기 전에는 아무도 모릅니다. 그래서 고객사 업무 시스템의 예약 작업에 텔레그램 알림을 붙였고, 그 알림을 받을 봇을 새로 만들기로 했습니다.

이 글은 그 봇을 만드는 순서입니다. 코드보다 텔레그램 쪽에서 눌러야 할 것이 더 많고, 그중 둘은 처음 하면 꼭 한 번 막히는 곳이라 순서대로 적어 둡니다.

이미 있는 봇을 쓰지 않은 이유

같은 고객사의 다른 서비스에 이미 알림 봇이 하나 있습니다. 토큰을 그대로 가져다 쓰면 새로 만들 것이 없으니 처음엔 그쪽으로 기울었습니다.

결국 새로 만들었습니다. 성격이 다른 알림이 한 대화방에 섞이면, 급한 알림이 일상적인 알림 사이에 묻힙니다. 토큰을 두 서비스가 나눠 가지면 한쪽에서 토큰을 갈 때 다른 쪽도 같이 다시 배포해야 합니다. 봇은 만드는 데 돈이 들지 않으니, 알림의 성격이 다르면 봇도 나누는 편이 낫다고 판단했습니다.

BotFather에게 받는 토큰

텔레그램 봇은 전부 @BotFather라는 공식 봇과 대화해서 만듭니다. 웹 콘솔 같은 것은 없습니다.

  1. 텔레그램에서 @BotFather를 찾아 대화를 열고 /newbot을 보냅니다.
  2. 보여 줄 이름을 묻습니다. 대화 목록에 뜨는 이름이라 한글도 되고 나중에 바꿀 수 있습니다.
  3. 아이디(username)를 묻습니다. 반드시 bot으로 끝나야 하고(example_alert_bot), 이미 누가 쓰는 이름이면 다시 묻습니다.
  4. 성공하면 123456789:AA… 꼴의 토큰을 줍니다.

이 토큰이 곧 봇의 비밀번호입니다. 토큰만 있으면 누구든 그 봇의 이름으로 메시지를 보낼 수 있습니다. 채팅방이나 메모장에 붙여 두지 말고 바로 비밀 저장소에 넣는 것이 좋습니다. 새어 나갔다고 의심되면 BotFather에서 /revoke로 토큰을 새로 받을 수 있고, 그 순간 옛 토큰은 쓸 수 없게 됩니다.

봇은 먼저 말을 걸 수 없다는 제약

토큰을 받았다고 바로 알림을 보낼 수 있는 것은 아닙니다. 텔레그램 봇은 사람이 먼저 대화를 시작한 상대에게만 메시지를 보낼 수 있습니다. 스팸 봇을 막는 장치라 우회할 길도 없습니다.

그래서 알림을 받을 사람이 새 봇과의 대화를 열고 「시작」(/start)을 한 번 눌러야 합니다. 아무 말이나 하나 더 보내 두면 다음 단계가 쉬워집니다.

화면에 나오지 않는 숫자, chat id

메시지를 보낼 때는 받는 사람을 아이디가 아니라 숫자 chat id로 적습니다. 이 숫자는 화면 어디에도 나오지 않아서, 봇이 받은 메시지 목록에서 꺼내야 합니다.

curl -s "https://api.telegram.org/bot<토큰>/getUpdates"

방금 보낸 메시지가 result 배열에 들어 있고, 그 안의 message.chat.id가 찾는 숫자입니다. 개인 대화면 양수, 그룹이면 -로 시작하는 음수입니다.

result가 비어 있으면 둘 중 하나입니다. 봇에게 아직 아무 말도 하지 않았거나, 그 봇에 웹훅(setWebhook)이 걸려 있는 경우입니다. 웹훅이 걸린 봇은 getUpdates가 동작하지 않습니다. 다른 서비스가 웹훅으로 받고 있는 봇을 가져다 쓰려 하면 여기서 막힙니다. 새 봇을 만든 것이 이 점에서도 편했습니다.

그룹으로 받고 싶다면 봇을 그룹에 초대한 뒤 그룹에서 /start@봇아이디를 보내고 같은 방법으로 id를 찾습니다. 봇은 기본 설정에서 그룹의 일반 대화를 읽지 못하고 명령어와 자기를 부른 메시지만 받으니, 명령어 꼴로 보내야 목록에 잡힙니다.

메시지 한 통으로 하는 확인

토큰과 chat id가 맞는지는 메시지 한 통이면 확인됩니다.

curl -s -X POST "https://api.telegram.org/bot<토큰>/sendMessage" \
  -H "Content-Type: application/json" \
  -d '{"chat_id": "<chat id>", "text": "알림 시험"}'

응답이 "ok": true이고 폰에 알림이 오면 끝입니다. chat not found가 나오면 대부분 대화를 시작하지 않은 경우입니다.

알림이 본래 작업을 막지 않게 정한 규칙

서버 쪽은 sendMessage를 부르는 함수 하나라 길지 않습니다. 다만 알림이 본래 일을 망가뜨리지 않게 몇 가지를 정해 두었습니다.

토큰이나 chat id가 비어 있으면 아무것도 하지 않고 넘어갑니다. 알림은 있으면 좋은 것이지 작업의 조건이 아니라서, 설정이 빠졌다고 예약 작업까지 멈추면 안 됩니다.

텔레그램 요청에는 5초 시간 제한을 걸었습니다. 텔레그램이 느리게 답하면 예약 확인 전체가 그만큼 밀리기 때문입니다.

실패했을 때 응답 본문은 로그에 남기지 않고 상태 코드만 남깁니다. 요청 주소에 토큰이 들어가는 API라서, 오류 문구에 무엇이 실려 올지 장담할 수 없었습니다.

알림 내용에는 무엇이 끝났는지 알아볼 수 있는 제목과 번호만 넣고 세부 내용은 넣지 않았습니다. 텔레그램도 결국 바깥 서비스이고, 알림의 목적은 「끝났다」와 「막혔다」를 아는 것이지 내용을 다시 읽는 것이 아니기 때문입니다.

참고: Telegram Bot API, BotFather 안내

마지막 수정:

공유하실 때는 출처(Duolabs)와 원문 주소를 표시해 주세요.