# AI 상품 추천:데이터 호출형\_모든 페이지

## **1. 시스템 구조도**

<figure><img src="https://files.helpdocs.io/p92xn84cjv/articles/n4klfe09xw/1711528840377/image.png" alt=""><figcaption></figcaption></figure>

***

<br>

## **2. 개요**

* 스크립트 LOAD 완료된 후 원하는 시점에 추천 상품 목록을 가져와서 사용할 수 있습니다.
* DIV형과는 다르게 디자인을 자유롭게 구성 가능합니다.

***

## **3. 연동 방식**

* 고객사에서 그루비에서 추천 상품 요청 시 데이터를 바로 전달합니다.

```
groobee.getGroobeeKeyBaseRecommendAsync("캠페인키", "추천타입", "타입에따른 기준값", 타임아웃) 
                    .then( data =>  { console.log(data); } );    
```

* 비동기식이라 요청이 느려졌을 경우 html에 추천 리스트를 표현하지 못하는 경우가 존재합니다.

{% hint style="warning" %}
이 문제를 방지하려면 아래 사항을 확인해 주세요.

1. 스크립트 로드 완료 후 호출\
   추천 API는 그루비 스크립트가 완전히 로드된 이후에 호출해야 합니다.\
   스크립트 로드 전에 호출할 경우 추천 결과가 정상적으로 렌더링되지 않을 수 있습니다.
2. 타임아웃 설정 조정\
   네트워크 환경에 따라 응답이 지연될 수 있습니다.\
   응답 실패가 자주 발생하는 경우, 타임아웃 값을 늘려 충분한 응답 대기 시간을 확보하는 것을 권장합니다.
3. 추천 실패 시 재시도 로직 구현 (고객사 직접 구현)\
   타임아웃 또는 네트워크 오류로 추천 요청이 실패한 경우, 그루비는 자동 재시도를 제공하지 않습니다.\
   실패 시 재시도 로직은 고객사 측에서 직접 구현해 주시기 바랍니다.\
   예) 일정 횟수만큼 재요청하거나, 실패 시 기본 상품 리스트로 대체 노출
   {% endhint %}

***

## **4. 어드민 설정**

<figure><img src="https://files.helpdocs.io/p92xn84cjv/articles/14wigwrpkn/1714385351375/image.png" alt=""><figcaption></figcaption></figure>

키(Key) 기반 추천 상품 조회를 사용할 경우 새로운 AI 추천 생성 시 무조건 모든페이지(데이터호출형)을 사용해야만 합니다.<br>

<figure><img src="https://files.helpdocs.io/p92xn84cjv/articles/14wigwrpkn/1714385367753/image.png" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
모든 페이지(데이터 호출형)을 선택 후 나오는 추천 유형은 getGroobeeKeyBaseRecommendAsync에서 사용할 추천 종류(recommendBaseType)와 똑같이 맞춰주셔야 합니다.
{% endhint %}

***

## **5. 키(Key) 기반 추천 상품 조회(getGroobeeKeyBaseRecommendAsync)**

* 고객사에서 추천 상품 요청 시 전달해주는 함수입니다.
* 정의
  * 역할: 추천 상품 조회
  * 함수명: groobee.getGroobeeKeyBaseRecommendAsync
  * 파라미터

| campaignKey       | 캠페인키                                                              | string                                                                                                   |
| ----------------- | ----------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| recommendBaseType | 추천 종류(대문자)                                                        | string                                                                                                   |
| recommendValue    | 추천 검색 값                                                           | string                                                                                                   |
|                   | <p>recommendBaseType 종류<br>• CATEGORY<br>• GOODS<br>• KEYWORD</p> | <p>recommendBaseType에 따른 recommendValue<br>• CATEGORY : 카테고리 코드<br>• GOODS : 상품코드<br>• KEYWORD : 검색어</p> |

**작성 예**

```
    groobee.getGroobeeKeyBaseRecommendAsync("RE6b33946d7add471dbd33f35347b5c06f",
    “CATEGORY“, “카테고리코드“, 500).then(
            data =>  { console.log(data); }
);
 
    groobee.getGroobeeKeyBaseRecommendAsync("RE6b33946d7add471dbd33f35347b5c06f",
    “GOODS“, “상품코드“, 500).then(
            data =>  { console.log(data); }
);
 
    groobee.getGroobeeKeyBaseRecommendAsync("RE6b33946d7add471dbd33f35347b5c06f",
     “KEYWORD“, “검색어“, 500).then(
            data => { console.log(data); } 
);
```

**결과 값**

```
{
    "campaignKey": "RE0878d834239d4160b8d9fbac6e69617c",
    "algorithmCd": "ST09",
    "goodsList": [
        {
            "serviceKey": "21af7eb7cd8643a0ac599fd2ea1c9611",
            "goodsNm": "자갸드 원피스",
            "goodsCd": "49",
            "goodsImg": "//shop3.grooshop.com/web/product/medium/202008/179f46dfad80fd80432fc283f8735e91.jpg",
            "goodsCateNm": "",
            "goodsCate": "",
            "goodsPrc": 52800,
            "goodsSalePrc": 47520,
            "regDtm": [2020,5,21,22,16,13,232000000],
            "moddDtm": [2020,5,21,22,16,13,232000000],
        },
        ...
    ]
}
```

***

## **6. DI(노출)**

* 실제 고객사에서 노출시킨 상품 정보를 그루비로 보내줍니다.
* 그루비로 노출시킨 상품 정보를 보내주면 통계에 집계되어 어드민에서 확인 가능합니다.
* **정의**
  * 역할: 전시되는 상품을 그루비에서 노출 처리
  * 함수명: groobee.send
  * 파라미터

| type       | 노출 코드("DI" 고정 값) | string |
| ---------- | ---------------- | ------ |
| groobeeObj | 노출 관련 object     | Object |

```
groobeeObj = {
   algorithmCd : "알고리즘코드",
   campaignKey : "추천캠페인키",
   campaignTypeCd : "RE", //고정
   goods: [
      {goodsCd: "노출된 상품코드1"},
      {goodsCd: "노출된 상품코드2"}
      ]
}
```

***

## **7. CL(클릭)**

* 고객이 클릭한 상품 정보를 그루비로 보내줍니다.
* 고객이 클릭한 상품 정보를 그루비로 보내주면 통계에 집계되어 어드민에서 확인 가능합니다.
* **정의**
  * 역할: 고객이 클릭한 상품을 그루비에서 클릭 처리
  * 함수명: groobee.send
  * 파라미터

| type       | 노출 코드("CL" 고정 값) | string |
| ---------- | ---------------- | ------ |
| groobeeObj | 노출 관련 object     | Object |

```
groobeeObj = {
   algorithmCd : "알고리즘코드",
   campaignKey : "추천캠페인키",
   campaignTypeCd : "RE", //고정
   goods: [
        {goodsCd: "고객이 클릭한 상품코드1"}
        ]
}
```

***

## **8. 사용 가능 알고리즘 정의**

* 사용 가능한 알고리즘을 확인합니다.

| RecommendBaseType | Algorithm                                                                                                                                                          |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| CATEGORY(카테고리 기반) | <p>1. 카테고리 TOP N<br>2. 실시간 카테고리 TOP N<br>3. 연관 카테고리 상품</p>                                                                                                         |
| GOODS(상품 기반)      | <p>1. 함께 본 상품<br>2. 함께 구매한 상품<br>3. 함께 담은 상품<br>4. 구매 패턴 유사 상품<br>5. 상품명 기반 유사 상품<br>6. 딥러닝 기반 유사 상품<br>7. 연관 카테고리 상품<br>8. 이미지 기반 유사 상품<br>9. 딥러닝 기반 다음에 볼 상품</p> |
| KEYWORD(검색어 기반)   | 1. 검색어 추천                                                                                                                                                          |

***

## **9. 작성 예시**

코드 작성 예시를 보여줍니다.

{% code lineNumbers="true" %}

```javascript
//작성 예시일 뿐 고객사의 코드에 맞게 수정해주시면 됩니다.
//아래 코드가 정답이 아닙니다. 참고만 부탁드립니다.
function groobeeRecommendCall () {
  //함수가 존재하는지 체크
  if (groobee && groobee.getGroobeeKeyBaseRecommendAsync) {
    //groobee.getGroobeeKeyBaseRecommendAsync 함수를 정상적으로 호출이 될 경우
    groobee.getGroobeeKeyBaseRecommendAsync('RE6b33946d7add471dbd33f35347b5c06f')
      .then(data => {
        고객사처리함수(data);
      })
  }  else {
    //groobee.getGroobeeKeyBaseRecommendAsync 함수가 정상적으로 호출이 되지 않을 경우
    let tryCnt = 0;
    let _timer = setInterval(()=> {
      // 3회 넘어갈시 중지
      if(tryCnt==3){
          clearInterval(_timer);
          $('#지정된ID').hide();
          return;
      }
      tryCnt++;
      // function 존재시에만 실행
      if(groobee.getGroobeeKeyBaseRecommendAsync && typeof groobee.getGroobeeKeyBaseRecommendAsync == 'function')
 {
          groobee.getGroobeeKeyBaseRecommendAsync('RE6b33946d7add471dbd33f35347b5c06f')
            .then(data => {
              고객사처리함수(data);
            })
          clearInterval(_timer);
      }}, 500);
  }
}
function 고객사처리함수(data) {
  console.log('recommendData :::', data);
  if (data && data.goodsList) {
    //고객사 추천상품 노출 및 데이터처리
    ...code 
    /*
      추천 상품 선별 및 노출작업
      각 상품 클릭 시 이벤트 연결처리도 필요 아래 clickGroobeeProduct(함수명은 자유)
      예시일 뿐 고객사에 맞춰서 코드는 새로 작성할 것
    */
    var html = "<ul>"; 
    for (let i = 0; i < data.goodsList.length; i++) { 
      html += `<li onClick="clickGroobeeProduct(${data.algorithmCd}, ${data.campaignKey}, 
 ${data.goodsList[i].goodsCd})">${data.goodsList[i].goodsNm}</li>`; 
     }
    html += "</ul>";
    $('#지정된ID').append(html);
    $('#지정된ID').show();
    --------------groobee 노출(DI) 처리 START----------------
    groobeeDisplayInsert(data.campaignKey, data.algorithmCd, data.goodsList);
    --------------groobee 노출(DI) 처리 END------------------
  } else {
    $('#지정된ID').hide();
  }
}
function groobeeDisplayInsert(type, campignKey, algorithmCd, goodsList) {
  //상품목록이 존재하는지 체크
  if (!goodsList || goodsList.length == 0) return;
  //이전에 goodsCd만 가공해서 보냈다면 1번 방식을 그게 아니라면 2번 방식을 채택하시면됩니다.
  1. var goods = goodsList;
  2. var goods = [];
    for (var i = 0; i < goodsList.length; i++) {
      var newObj = {goodsCd: goodsList[i].goodsCd};
      goods.push(newObj);
    } 
  var groobeeObj = {
    algorithmCd: algorithmCd, //알고리즘코드 (추천받을때 받은 algorithmCd)
    campaignKey: campaignKey, //캠페인키
    campaignTypeCd: 'RE',     //고정값
    goods: goods
  }
  groobee.send('DI', groobeeObj);
}
function clickGroobeeProduct(campaignKey, algorithmCd, goodsCd) {
  //추천 클릭처리
  var groobeeObj = {
    algorithmCd: algorithmCd, //알고리즘코드 (추천받을때 받은 algorithmCd)
    campaignKey: campaignKey, //캠페인키
    campaignTypeCd: 'RE',     //고정값
    goods: [
      {goodsCd: goodsCd}
    ]
  }
  groobee.send('CL', groobeeObj);
  //고객사 페이지 이동처리
  code....
}
        
```

{% endcode %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.groobee.ai/developer-guide/script-guide/ai-recommendation/all-page.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
