Skip to content
hyukjunkim1116 edited this page Jul 6, 2023 · 4 revisions

✔️ COUPANG API

  • 사용자의 냉장고를 확인하고 사용자에게 없는 재료를 구매 할 수 있도록 쿠팡 제품을 추천해줌
  • 쿠팡에서 제공하는 API를 이용해서 키워드에 맞는 제품 1-10순위 목록을 사용자에게 제공함
  • 해당 링크로 물건을 구매시 커미션을 받는 구조로 수익모델 기능을 함
  • 쿠팡 API 공식문서 지침에 따라 API 호출횟수를 1분에 50번으로 제한함

💻 code

coupang.py
class CoupangManage:
    DOMAIN = "https://api-gateway.coupang.com"

    # HMAC서명 생성
    def generateHmac(self, method, url, secretKey, accessKey):
        path, *query = url.split("?")
        current_datetime = datetime.utcnow().strftime("%y%m%dT%H%M%SZ")
        message = current_datetime + method + path + (query[0] if query else "")
        signature = hmac.new(
            bytes(secretKey, "utf-8"), message.encode("utf-8"), hashlib.sha256
        ).hexdigest()

        return "CEA algorithm=HmacSHA256, access-key={}, signed-date={}, signature={}".format(
            accessKey, current_datetime, signature
        )

    def get_productsdata(self, request_method, authorization, url):
        response = requests.request(
            method=request_method,
            url=url,
            headers={
                "Authorization": authorization,
                "Content-Type": "application/json;charset=UTF-8",
            },
        )
        retdata = json.dumps(response.json(), indent=4).encode("utf-8")
        jsondata = json.loads(retdata)
        data = jsondata["data"]

        productdata = data["productData"]

        return productdata

    def get_products_by_keyword(self, keyword, limit=10, subld="cookaicookai"):
        request_method = "GET"
        method = "GET"

        query = {"keyword": keyword, "limit": limit, "subId": subld}
        encoded_query = urlencode(query)

        # API 요청 URL
        request_url = (
            "/v2/providers/affiliate_open_api/apis/openapi/products/search?{}".format(
                encoded_query
            )
        )

        # HMAC 생성
        authorization = self.generateHmac(method, request_url, SECRET_KEY, ACCESS_KEY)

        # 요청 URL
        full_url = "{}{}".format(self.DOMAIN, request_url)

        # 상품 데이터 받기
        product_data = self.get_productsdata(request_method, authorization, full_url)

        # 딕셔너리 생성
        products = [
            {
                "product_url": product["productUrl"],
                "product_image_url": product["productImage"],
                "product_price": product["productPrice"],
            }
            for product in product_data
        ]

        return products
views.py
class LinkPlusView(APIView):
    permission_classes = [permissions.IsAuthenticated]

    def get(self, request, article_id):
        # 로그인된 사용자의 Fridge 조회
        user_fridge_ingredients = Fridge.objects.filter(user=request.user).values_list(
            "ingredient", flat=True
        )

        # article_id와 연결된 RecipeIngredient 조회
        recipe_ingredients = RecipeIngredient.objects.filter(
            article_id=article_id
        ).values_list("ingredient", flat=True)

        # 사용자의 Fridge에 없는 Ingredient 찾기
        missing_ingredients = set(recipe_ingredients) - set(user_fridge_ingredients)

        # 없는 Ingredient와 연결된 IngredientLink 조회
        # column_name+__in : 리스트 안에 지정한 문자열들 중에 하나라도 포함된 데이터를 찾을 때 사용
        ingredient_links = IngredientLink.objects.filter(
            ingredient__in=missing_ingredients
        )

        # 현재 시간과 5일 전 시간 구하기
        now = timezone.now()
        five_days_ago = now - timedelta(days=5)

        # 존재하지 않는 IngredientLink 인스턴스 생성 및 저장
        for ingredient in missing_ingredients:
            ingredient_links = IngredientLink.objects.filter(ingredient=ingredient)
            if not ingredient_links.exists():
                save_coupang_links_to_ingredient_links(ingredient)
            else:
                # link가 등록된 재료라도 `updated_at`이 5일 이상 지났다면 최신화하기
                existing_link = ingredient_links.first()
                if (
                    existing_link.ingredient.updated_at is None
                    or existing_link.ingredient.updated_at <= five_days_ago
                ):
                    save_coupang_links_to_ingredient_links(ingredient)

        # 다시 IngredientLink를 조회
        ingredient_links = IngredientLink.objects.filter(
            ingredient__in=missing_ingredients
        )

        # JSON 형태로 반환
        serialized_links = IngredientLinkSerializer(ingredient_links, many=True)
        return Response(serialized_links.data, status=status.HTTP_200_OK)

📷 View
Image
Clone this wiki locally