[리원아빠] 카카오톡 자동 토큰 발행 후 나에게 메시지 보내기

2022. 3. 3. 10:58Python

반응형

카카오톡 자동 토큰 발행 및 메시지 보내기



이전 포스팅에 카카오톡을 통해 자신에게 메시지를 보내는 방법에 대해 알아봤다. 

 

2022.03.02 - [IT/Python] - [리원아빠] 파이썬으로 카카오톡 메시지 나에게 보내기

 

[리원아빠] 파이썬으로 카카오톡 메시지 나에게 보내기

카카오톡 메시지 나에게 보내기 파이썬을 통해 키워드 챗봇을 만들었다. 텔레그램이 아닌 카카오톡으로 만들다보니 카카오 인증이 필요했다. 인증은 json으로 처리했는데 처음해봐서 구글링이

liwonfather.tistory.com

 

하지만 단점으로 언급한것처럼 카카오톡으로 메시지를 보내기 위해서는

적어도 하루에 한번은 token을 새로 발급하는 일종의 인증 과정이 필요했다.

인증은 token이라는 개념을 사용하는데 token의 종류는 access token과 refresh token, 두가지로 구분된다.

두가지 중 우리가 메시지를 전송할 때 필요한 것은 access token으로 유효기간이 채 하루가 되지 않는다.

반면 refresh token은 access token을 갱신할 때는 필요한 token으로 유효기간이 약 2달정도 된다.

어떻게 하면 이런 번거로운 인증 과정을 최소화 할 수 있을까 고민을 하다가 내린 결론은 아래와 같다.

  • 유효기간이 refresh token을 활용하자.
  • refresh token으로 메시지를 보낼 때마다 새로운 access token을 발행하자.

그래서 두개의 함수를 만들고 첫번째 함수는 refresh token을 발췌하고

두번째 함수는 refresh token을 가지고 새로운 access token을 발행하는 코드를 작성했다.

그리고 다음글에 포스팅 하겠지만 이렇게 새로 발급된 access token을 가지고 메시지를 보낼 때 사용한다.

그럼 먼저 refresh token을 발췌하는 함수부터 살펴보자.

 

def f_auth():
    data = {
        'grant_type': 'authorization_code',
        'client_id': rest_api_key,
        'redirect_uri': redirect_uri,
        'code': authorize_code,
    }

    response = requests.post(url, data=data)
    tokens = response.json()

    with open("kakao_code.json", "w") as fp:
        json.dump(tokens, fp)
    with open("kakao_code.json", "r") as fp:
        ts = json.load(fp)
    r_token = ts["refresh_token"]
    return r_token

rest api key값과 code값을 가지고 최초 token 발행을 하면서 그 내용을 json 형태로 저장하고

다시 refresh token 값만 읽어들여 return 해준다.

최초 발행은 access token과 refresh token 두 가지다 발급된다.

이 부분이 가장 번거로운데 그 이유는 프로그램을 수행할 때 마다 code 값을

항상 redirect_uri를 통해 확인을 해서 새로 넣어줘야하기 때문이다. (code 값은 가장 최신의 값만 유효)

이제 refresh token 정보를 가지고 있으니 새로운 access token을 발행해주는 함수를 살펴보자.

 

def f_auth_refresh(r_token):
    with open("kakao_code.json", "r") as fp:
        ts = json.load(fp)
    data = {
        "grant_type": "refresh_token",
        "client_id": rest_api_key,
        "refresh_token": r_token
    }
    response = requests.post(url, data=data)
    tokens = response.json()

    with open(r"kakao_code.json", "w") as fp:
        json.dump(tokens, fp)
    with open("kakao_code.json", "r") as fp:
        ts = json.load(fp)
    token = ts["access_token"]
    return token

정보를 전달 할 때 grant_type과 전달되는 내용이 기존함수와 다르며

새로 발급된 access_token을 return 해준다.

저장된 json 파일을 보면 최초 token 발행시에는 access token, refresh token 둘다 있지만

refresh token을 통한 aceess token 갱신시에는 refresh token 값은 별도로 저장되지 않는다.

사실 이 두가지 함수만 봐서는 카카오톡 자동 인증 과정이 잘 이해가 되지 않을 수 있다.

그래서 필자가 테스트하고 실제 사용하고 있는 전체 소스를 첨부한다.

 

import requests
import json

#code url  https://kauth.kakao.com/oauth/authorize?client_id=자신의 rest key값&redirect_uri=https://example.com/oauth&response_type=code
url = 'https://kauth.kakao.com/oauth/token'  
rest_api_key = '자신의 rest key값'  
redirect_uri = 'https://example.com/oauth'  
authorize_code = '자신의 코드값'  


def f_auth():
    data = {
        'grant_type': 'authorization_code',
        'client_id': rest_api_key,
        'redirect_uri': redirect_uri,
        'code': authorize_code,
    }

    response = requests.post(url, data=data)
    tokens = response.json()

    with open("kakao_code.json", "w") as fp:
        json.dump(tokens, fp)
    with open("kakao_code.json", "r") as fp:
        ts = json.load(fp)
    r_token = ts["refresh_token"]
    return r_token


def f_auth_refresh(r_token):
    with open("kakao_code.json", "r") as fp:
        ts = json.load(fp)
    data = {
        "grant_type": "refresh_token",
        "client_id": rest_api_key,
        "refresh_token": r_token
    }
    response = requests.post(url, data=data)
    tokens = response.json()

    with open(r"kakao_code.json", "w") as fp:
        json.dump(tokens, fp)
    with open("kakao_code.json", "r") as fp:
        ts = json.load(fp)
    token = ts["access_token"]
    return token


def f_send_talk(token, text):
    header = {'Authorization': 'Bearer ' + token}
    url = 'https://kapi.kakao.com/v2/api/talk/memo/default/send'  
    post = {
        'object_type': 'text',
        'text': text,
        'link': {
            'web_url': 'https://developers.kakao.com',
            'mobile_web_url': 'https://developers.kakao.com'
        },
        'button_title': '키워드'
    }
    data = {'template_object': json.dumps(post)}
    return requests.post(url, headers=header, data=data)


r_token = f_auth()


while True:
    token = f_auth_refresh(r_token)  
    f_send_talk (token, '보낼 메시지')
    time.sleep(1800)

rest api key값과 code값은 자신의 값으로 변경해야 한다.

필자는 크롤링을 목적으로 사용하고 있어 while문 안에 크롤링된 내용들을 가공 후 카톡으로 보내고 있다.

같은 방식으로 사용할 거라면 while문 안의 f_send_talk 함수 호출 전

자신이 하고자 하는 일을 처리하면 될듯하다.

다음엔 실제 특정 사이트에서 정보를 따와서 주기적으로 카톡을 보내주는 내용을 포스팅 해보겠다.

 

그럼 끝.

반응형