API 활용

[cafe24 api] 쇼핑몰에 새로운 주문이 있는지 확인하기

cha2hyun 2021. 12. 16. 17:10

곧 업데이트 됩니다.

 

views.py

from rest_framework.views import APIView
from rest_framework.response import Response
from .utils import Cafe24BoardManager, Cafe24OrderManager, TokenManager
import time 

class OAuth(APIView):
    def get(self, request):
        try:
            oauth_code = request.GET.get('code',' ')
            TokenManager().deleteOldToken()
            TokenManager().createToken(oauth_code)
            return Response(status=200)
        except:
            return Response(status=400)

class UpdateToken(APIView):
    # path(r'cafe24/oauth/update/', cafe24.UpdateToken.as_view(), name='UpdateToken'),
    def get(self, request): 
        if TokenManager().updateToken():
            return Response(status=200)
        else: 
            return Response(status=400)
    
class Board(APIView):
    # path(r'cafe24/board/', cafe24.Board.as_view(), name='Board'),
    def get(self, request):        
        if TokenManager().updateToken():
            BoardManager = Cafe24BoardManager()
            BoardManager.getNewArticle()
            return Response(status=200)
        else: 
            return Response(status=400)

class Order(APIView):
    # path(r'cafe24/order/', cafe24.Order.as_view(), name='Order'),
    def get(self, request):        
        if TokenManager().updateToken():
            OrderManager = Cafe24OrderManager()
            OrderManager.getNewOrder()
            return Response(status=200)
        else: 
            return Response(status=400)


class CronJob(APIView):
    # path(r'cafe24/cron/', cafe24.CronJob.as_view(), name='CronJob'),
    def get(self, request):
        if TokenManager().updateToken():
            BoardManager = Cafe24BoardManager()
            BoardManager.getNewArticle()
            time.sleep(1)
            OrderManager = Cafe24OrderManager()
            OrderManager.getNewOrder()
            return Response(status=200)
        else: 
            return Response(status=400)

 

 

utils.py

from django.http import Http404

from ..static import CLIENT_ID, CLIENT_SECRET_KEY, BASE64_ENCODED, REDIRECT_URI, CAFE24_OAUTH_URL, ERR_MESSAGE, AS_URL, CAFE24_BOARD_URL, ADMIN_NICKNAME, KIMCHI_BOARD_URL, CAFE24_API_URL, CAFE24_ORDER_URL
from ..log.views import LogSave
from ..serialnumber.utils import clean_text
from .models import cafe24_token, cafe24_article, cafe24_board, cafe24_order

from datetime import datetime, timedelta
from bs4 import BeautifulSoup
import requests 
import time

class TokenManager():
    headers = {
        "Authorization": "Basic " + BASE64_ENCODED,
        "Content-Type": "application/x-www-form-urlencoded", 
    }

    def createToken(self, code):
        response = requests.post(CAFE24_OAUTH_URL,
            headers = self.headers,
            data = {
                "grant_type" : "authorization_code",
                "redirect_uri" : REDIRECT_URI,
                "code" : code,
            }
        ).json()
        self.saveToken(response)    

    def updateToken(self):        
        try:
            obj = cafe24_token.objects.latest('expires_at')       
            refresh_token = obj.refresh_token
            response = requests.post(CAFE24_OAUTH_URL,
                headers = self.headers,
                data = {
                    "grant_type" : "refresh_token",
                    "redirect_uri" : REDIRECT_URI,
                    "refresh_token" : refresh_token,
                }
            ).json()
            self.saveToken(response)        
            return True
        except Exception as e:
            raise Http404(f"Please Do OAuth First or check the error {e}")
            return False
    
    def saveToken(self, response):     
        self.deleteOldToken()
        access_token = response['access_token']
        expires_at = response['expires_at']
        refresh_token = response['refresh_token']
        refresh_token_expires_at = response['refresh_token_expires_at']        
        cafe24_token(access_token = access_token, expires_at = expires_at, refresh_token = refresh_token, refresh_token_expires_at = refresh_token_expires_at).save()

    def deleteOldToken(self):
        obj = cafe24_token.objects.all().delete()
    
    def getToken(self): 
        obj = cafe24_token.objects.latest('expires_at')
        return obj.access_token

    


class Cafe24BoardManager():
    title = "카페24 게시글 크롤링"
    headers = {'Content-Type': 'text/text; charset=utf-8'}
    
    def __init__(self):
        self.access_token = TokenManager().getToken()
        self.end_date = datetime.today().strftime('%Y-%m-%d')		
        self.start_date = (datetime.today() + timedelta(days=-7)).strftime('%Y-%m-%d')
        self.limit = "20"
        self.board_list = ["4", "5", "6", "14", "15"]

    def getNewArticle(self):
        for board_no in self.board_list:
            url = f"{CAFE24_API_URL}/boards/{board_no}/articles?start_date={self.start_date}&end_date={self.end_date}&limit={self.limit}"	
            response = Cafe24APIResponseToJson(url, self.access_token)
            articles = list(response['articles'])
            for article in articles:
                self.checkArticle(article, board_no)

    def checkArticle(self, article, board_no):
        if cafe24_article.objects.filter(article__board_no=board_no).filter(article_no = article['article_no']):
            pass
            # print("새로운 게시글 없음")            
        else:
            # 관리자 글 패스
            if article['parent_article_no'] != None:
                pass
            else:
                article_no = str(article['article_no'])
                writer = str(article['writer'])
                member_id = str(article['member_id'])
                nick_name = str(article['nick_name'])
                created_date = str(article['created_date'])
                title = str(article['title'])
                content = str(article['content'])
                board = cafe24_board.objects.get(board_no=board_no)
                board_name = board.board_name                
                article_link = KIMCHI_BOARD_URL + f"{board_name.replace(' ','-')}/{board_no}/{article_no}/"
                
                message = ""
                message += "`[" + board_name + "]에 새로운 글이 등록되었어요.*`" + "\n"                
                message += ">*" + title + "* | " + writer + " | " + created_date[:10] + " | <" + article_link + "|(바로가기)>" + "\n"
                message += ">" + content[:300] + "\n"
                
                content_contain = ["수리", "as", "AS", "As", "소리", "교체", "선골", "팁교체"]
                if any(_ in content for _ in content_contain) or board_no == "14":
                    self.send_message(AS_URL, message)    
                else:
                    self.send_message(CAFE24_BOARD_URL, message)    

                cafe24_article(article = board, article_no = article_no,writer = writer,member_id = member_id,nick_name = nick_name,created_date = created_date,title = title,content = content).save()                

    def send_message(self, url, message):
        message = clean_text(message)
        payload = 'payload={"text": "' + message + '"}'        
        res = requests.post(url, data=payload.encode('utf-8'), headers=self.headers)
        time.sleep(1)
        if res.json()["success"] != True:    
            self.send_error(res)        

    def send_error(self, res):
        LogSave(f">{ADMIN_NICKNAME} CAFE24 BOARD ERROR\nres > {res.json()}")


class Cafe24OrderManager():
    title = "카페24 주문 크롤링"
    headers = {'Content-Type': 'text/text; charset=utf-8'}
    
    def __init__(self):
        self.access_token = TokenManager().getToken()
        self.end_date = datetime.today().strftime('%Y-%m-%d')		
        self.start_date = (datetime.today() + timedelta(days=-7)).strftime('%Y-%m-%d')
        self.limit = "100"
        self.order_status = "N10" #상품준비중
        
    def getNewOrder(self):        
        # 모든 상품준비중 상품 불러오기
        orders_url = f"{CAFE24_API_URL}/orders?start_date={self.start_date}&end_date={self.end_date}&limit={self.limit}&order_status={self.order_status}"
        orders_response = Cafe24APIResponseToJson(orders_url, self.access_token)
        orders = orders_response["orders"]
        message = ""
        if len(orders) > 0:
            for order in orders:
                order_id = order["order_id"]
                message += f"\n`쇼핑몰 새로운 주문이 결제되었습니다.`\n"       
                message += self.getOrderMessage(order)     

                items_url = f"{CAFE24_API_URL}/orders/{order_id}/items"
                items_response = Cafe24APIResponseToJson(items_url, self.access_token)   
                items = items_response["items"]             
                for item in items:           
                    message += self.getItemMessage(item)

            if not self.isAlreadyExist(order_id):               
                cafe24_order(order_id = order_id, member_id = self.member_id, billing_name = self.billing_name, actual_order_amount = self.actual_order_amount, payment_date = self.payment_date, cellphone = self.cellphone, product_name = self.product_name, option_value = self.option_value, quantity = self.quantity).save()
                self.send_message(CAFE24_ORDER_URL, message)

    def isAlreadyExist(self, order_id):
        return cafe24_order.objects.filter(order_id=order_id)

    def getOrderMessage(self, order):
        message = ""
        self.member_id = order["member_id"]			
        if self.member_id == "":
            self.member_id = "비회원"
        self.billing_name = order["billing_name"]	
        self.actual_order_amount = str(order["actual_order_amount"]["order_price_amount"])
        self.actual_order_amount = self.actual_order_amount.split(".")[0]
        self.actual_order_amount = format(int(self.actual_order_amount),",")
        self.payment_date = str(order["payment_date"])
        self.payment_date = self.payment_date.split("T")[0]

        # 택배 수령자 정보 불러오기
        order_id = order["order_id"]
        receivers_url = f"{CAFE24_API_URL}/orders/{order_id}/receivers"
        receivers_response = Cafe24APIResponseToJson(receivers_url, self.access_token)
        receivers = receivers_response["receivers"][0]
        self.cellphone = receivers["cellphone"]
        message += f">{self.billing_name} [{self.member_id}] | {self.cellphone}\n>결제액 : {self.actual_order_amount}원 | 결제일 : {self.payment_date}"
        return message
    
    def getItemMessage(self, item):
        # 상품 옵션 불러오기
        message = ""
        self.product_name = item["product_name"]
        self.option_value = item["option_value"]
        self.quantity = item["quantity"]
        options = " |  "
        if self.option_value != "":
            self.option_value = self.option_value.split(",")
            for option in self.option_value:						
                options += "" + option.split("=")[1] + "   "
            options = options[:-2] 
        else:
            options = ""
        message += "\n>" + f"--- {self.product_name} {options} |  {self.quantity}개"
        return message
        
    def send_message(self, url, message):
        message = clean_text(message)
        payload = 'payload={"text": "' + message + '"}'        
        res = requests.post(url, data=payload.encode('utf-8'), headers=self.headers)
        time.sleep(1)
        if res.json()["success"] != True:    
            self.send_error(res)        

    def send_error(self, res):
        LogSave(f">{ADMIN_NICKNAME} CAFE24 ORDER ERROR\nres > {res.json()}")


def Cafe24APIResponseToJson(url, access_token):
    response = requests.get(url, 
        headers = { 
            "Authorization": "Barrer " + access_token,
            "Content-Type": "application/json", 
        },
        data = {}
    ).json()
    return response