์ฟ ํก์ํ ์๋ ๋ ธ์ถ ์๋ฒฝ ์ ์ฉ ๋ฐฉ๋ฒ ๋ชฉ๋ก(์นดํ ๊ณ ๋ฆฌ) ํ์ด์ง์ฉ
์ฟ ํก ํํธ๋์ค ์ํ์ ๋ธ๋ก๊ทธ์ ์๋์ผ๋ก ๋ ธ์ถํ๊ณ ์ถ๋ค๋ฉด, Google Apps Script(GAS)๋ฅผ ํ์ฉํ ์๋ํ๊ฐ ๊ฐ์ฅ ์ฝ๊ณ ์์ ํ ๋ฐฉ๋ฒ์ ๋๋ค. ๋ชฉ๋ก ํ์ด์ง ์ ์ฉ ์คํฌ๋ฆฝํธ ์ ์ฉ๋ฒ๋ถํฐ API ์ฐ๋๊น์ง ํ ๋ฒ์ ์ ๋ฆฌํ์ต๋๋ค.
์ฟ ํก ํํธ๋์ค ์ํ์ ๋ด ๋ธ๋ก๊ทธ์ ์๋์ผ๋ก ๋ ธ์ถ์ํค๋ฉด ์์ต ์ฆ๋๋ ๋ฌผ๋ก ๋ฐฉ๋ฌธ์์ ํธ์๋ ๋์ผ ์ ์์ฃ .
ํ์ง๋ง ๋จ์ํ ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ๋ธ๋ก๊ทธ์ ๋ฃ๋ ๊ฒ๋ง์ผ๋ก๋ ํ๊ณ๊ฐ ์์ต๋๋ค.
์ Google Apps Script(GAS)๋ฅผ ํ์ฉํด์ผ ํ ๊น์?
์ด ๊ธ์์๋ ์ฟ ํก์ํ ์๋ ๋ ธ์ถ์ ์ต์ ํ๋, ํนํ ๋ชฉ๋ก(์นดํ ๊ณ ๋ฆฌ) ํ์ด์ง์์๋ง ๋์ํ๋ GAS ํ์ฉ๋ฒ๊ณผ ๊ธฐ๋ณธ ์ฝ๋๋ฅผ ์ 3ํ์ผ๋ก ์ค๋ช ํฉ๋๋ค. ์ด๋ณด์๋ ์ฝ๊ฒ ๋ฐ๋ผ ํ ์ ์๋๋ก ํต์ฌ๋ง ์ ๋ฆฌํ์ผ๋ ๋๊น์ง ์ฝ๊ณ ๋ฐ๋ก ์ ์ฉํด ๋ณด์ธ์!
์ฟ ํก์ํ ์๋ ๋ ธ์ถ ์ฝ๊ฒ ๊ตฌํํ๋ ๋ฐฉ๋ฒ
Google Apps Script(GAS)๋ ์๋ฐ์คํฌ๋ฆฝํธ๋ง ์ง์ํ๋ ๋๊ตฌ์ ๋๋ค. "๊ทธ๋ฅ ๋ด ๋ธ๋ก๊ทธ๋ ์น์ฌ์ดํธ์ ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ์ฐ๋ฉด ๋์ง, ์ ์จ์ผ ํ ๊น?"๋ผ๋ ์๋ฌธ์ด ์๊ธธ ์ ์์ฃ .
ํ์ง๋ง GAS๋ ๋จ์ํ ์๋ฐ์คํฌ๋ฆฝํธ ์คํ๊ธฐ๊ฐ ์๋๋๋ค.์๋ฒ์ฒ๋ผ ์๋ํ๋ ๋๊ตฌ์ด๊ธฐ ๋๋ฌธ์, ์น์ฌ์ดํธ์์ ํ ์ ์๋ ์ฌ๋ฌ ์์ ๋ค์ ๋์ ํด์ค๋๋ค.
Google Apps Script๋ฅผ ์ฌ์ฉํ๋ ์ด์

1. ์๋ฒ ์์ด๋ API์ฒ๋ผ ์ฌ์ฉํ ์ ์์
- ์ผ๋ฐ ์น์ฌ์ดํธ๋ ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ค๊ธฐ ์ํด ์ธ๋ถ ์๋ฒ๊ฐ ํ์ํฉ๋๋ค.
- GAS๋ ๋ณ๋์ ์๋ฒ ์์ด, ์๋ฐ์คํฌ๋ฆฝํธ ํจ์๋ฅผ API์ฒ๋ผ URL๋ก ์ ๊ณตํด ์ค๋๋ค.
- ์: https://script.google.com/macros/s/์ฑID/exec?keyword=ํค์๋
2. ์ค์ํ ์ ๋ณด(๋น๋ฐ ํค ๋ฑ)๋ฅผ ๊ฐ์ถ ์ ์์
- HTML์ ์ง์ ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ๋ฃ์ผ๋ฉด ๋๊ตฌ๋ ์ฝ๋๋ฅผ ๋ณผ ์ ์์ต๋๋ค.
- GAS๋ ์๋ฒ์์ ์คํ๋๋ฏ๋ก ์ฝ๋๊ฐ ์ธ๋ถ์ ๋ ธ์ถ๋์ง ์์ต๋๋ค.
- ์: ์ฟ ํก ํํธ๋์ค API ํค๋ฅผ ์จ๊ธฐ๊ณ ์์ ํ๊ฒ ์ค๊ณ ๊ฐ๋ฅ
3. Google ์๋น์ค์ ์ฝ๊ฒ ์ฐ๋๋จ
- GAS๋ Google Sheets, Gmail, Docs ๋ฑ๊ณผ ์์ฐ์ค๋ฝ๊ฒ ์ฐ๊ฒฐ๋ฉ๋๋ค.
- ์: ์ํธ์ ์ ์ฅ๋ ์ํ ๋ฐ์ดํฐ๋ฅผ GAS๋ก JSON์ผ๋ก ๋ง๋ค์ด ๋ธ๋ก๊ทธ์ ๋ณด์ฌ์ฃผ๊ธฐ
4. ์๋ฒ ๋น์ฉ์ด ๋ค์ง ์์
- GAS๋ ๋ณ๋ ํธ์คํ ์์ด Google ํด๋ผ์ฐ๋์์ ์คํ๋ฉ๋๋ค.
- ํธ๋ํฝ์ด ๋ง์ง ์์ ๊ฐ์ธ ๋ธ๋ก๊ทธ๋ ๊ฐ๋จํ API์๋ ๋ฌด๋ฃ๋ก ์ถฉ๋ถํ ์ฌ์ฉ ๊ฐ๋ฅํฉ๋๋ค.
์ ๋ฆฌํ๋ฉด...
Google Apps Script๋ ๋จ์ํ ์๋ฐ์คํฌ๋ฆฝํธ ์คํ ๋๊ตฌ๊ฐ ์๋๋ผ, ์๋ฒ ์์ด๋ ์ธ๋ถ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ณ ๊ฐ๊ณตํด์ ๋ณด์ฌ์ค ์ ์๋ ๊ฐ๋ ฅํ ๋๊ตฌ์ ๋๋ค.
๋ธ๋ก๊ทธ๋ ์น์ฌ์ดํธ์ "๋๋ง์ ๋ฐ์ดํฐ API"๋ฅผ ๋ง๋ค๊ณ ์ถ์ ๋, GAS๋ฅผ ํ์ฉํ๋ฉด ๋น์ฉ ์์ด๋ ์์ฝ๊ฒ ๊ตฌํํ ์ ์์ต๋๋ค.
ํนํ, ์ฟ ํก ์ํ ์๋ ๋ ธ์ถ, ์ํธ ๋ฐ์ดํฐ ๋ถ๋ฌ์ค๊ธฐ, ์ธ๋ถ API ๊ฐ๊ณต ๋ฑ์ ์ต์ ํ๋ ์ ํ์ ๋๋ค.
๊ทธ๋ ๋ค๋ฉด ์ฟ ํก์์ ์ ๊ณตํ๋ API ๊ธฐ๋ฅ์ ์ด์ฉํ๊ธฐ ์ํด์๋, ๋ฐ๋์ ์ ์กฐ๊ฑด์ ๋ง๋ ์น์ฑ ํ๋ซํผ ๋๋ ์๋ฒ๋ฆฌ์ค ํ๋ซํผ์ด ํ์ํฉ๋๋ค.
Google Apps Script ์ฌ์ฉ ๋ฐฉ๋ฒ์ ์ด ๋งํฌ(์ฟ ํก ํํธ๋์ค ์ํ ์๋ ๋ฑ๋ก ์์ตํ! ๋ธ๋ก๊ทธ์ ์ํ ์๋ ๋ฑ๋กํ๋ ๋ฐฉ๋ฒ)๋ฅผ ์ฐธ๊ณ ํ์ธ์.
ํด๋น ์ฌ์ดํธ์ ์๋ ์ฝ๋๋ฅผ ์ ์ฉํ๋ฉด ๋๋ฉฐ, ๋ณ๊ฒฝํ ๋ถ๋ถ๋ง ์์ ํ ํ ์ ์ฒด ์ฝ๋๋ฅผ ๋ณต์ฌํด์ ๋ถ์ฌ๋ฃ๊ธฐ ํ์๋ฉด ๋ฉ๋๋ค.
์์ฃผ ๊ฐ๋จํ์ฃ ?
์ฟ ํก ์ํ ์๋ํ ์ ์ฉ์ ๋ณ๊ฒฝํ ์ฝ๋
// ==== ์ค์ ๊ฐ (๋ณธ์ธ์ ์ ๋ณด๋ก ๋ณ๊ฒฝ) ====
// ์ฟ ํก API Access Key
const COUPANG_ACCESS_KEY = " ACCESS KEY";
// ์ฟ ํก API Secret Key
const COUPANG_SECRET_KEY = " SECRET KEY";
// ์ฟ ํก ํํธ๋์ค ID (์: lptag=AF1234567 ์ค AF1234567)
const COUPANG_AFFILIATE_ID = " AF1234567";
GAS์ ์ ์ฉํ ์ ์ฒด ์ฝ๋
์ ์ฝ๋๋ฅผ ์์ ํด์ ๋ณต์ฌ ํ ์ฌ์ฉํ์๋ฉด ๋ฉ๋๋ค.
// ==== ์ค์ ๊ฐ (๋ณธ์ธ์ ์ ๋ณด๋ก ๋ณ๊ฒฝ) ====
const COUPANG_ACCESS_KEY = " ACCESS KEY";
const COUPANG_SECRET_KEY = " SECRET KEY";
const COUPANG_AFFILIATE_ID = " AF1234567";
const COUPANG_API_BASE_URL = "https://api-gateway.coupang.com";
const PRODUCT_SEARCH_API_PATH = "/v2/providers/affiliate_open_api/apis/openapi/products/search";
function getCoupangApiDate() {
const date = new Date();
const year = date.getUTCFullYear().toString().substring(2);
const month = (date.getUTCMonth() + 1).toString().padStart(2, '0');
const day = date.getUTCDate().toString().padStart(2, '0');
const hours = date.getUTCHours().toString().padStart(2, '0');
const minutes = date.getUTCMinutes().toString().padStart(2, '0');
const seconds = date.getUTCSeconds().toString().padStart(2, '0');
const datetime = `${year}${month}${day}T${hours}${minutes}${seconds}Z`;
return datetime;
}
function generateCoupangSignature(method, uri, secretKey, accessKey) {
const parts = uri.split('?');
const path = parts[0];
const query = (parts.length === 2) ? parts[1] : '';
const datetime = getCoupangApiDate();
const stringToSign = `${datetime}${method}${path}${query}`;
const signatureBytes = Utilities.computeHmacSha256Signature(stringToSign, secretKey);
const signatureHex = bytesToHex(signatureBytes);
return `CEA algorithm=HmacSHA256, access-key=${accessKey}, signed-date=${datetime}, signature=${signatureHex}`;
}
function bytesToHex(bytes) {
return Array.from(bytes, b = ('0' + (b & 0xFF).toString(16)).slice(-2)).join('');
}
function fetchCoupangProducts(limit = 10, keyword = null) {
if (!keyword) throw new Error("๊ฒ์ ํค์๋๊ฐ ํ์ํฉ๋๋ค.");
const method = 'GET';
const encodedKeyword = encodeURIComponent(keyword);
const uri = `${PRODUCT_SEARCH_API_PATH}?keyword=${encodedKeyword}&limit=${limit}`;
const url = COUPANG_API_BASE_URL + uri;
const options = {
method: method,
headers: { 'Authorization': generateCoupangSignature(method, uri, COUPANG_SECRET_KEY, COUPANG_ACCESS_KEY) },
muteHttpExceptions: true
};
const response = UrlFetchApp.fetch(url, options);
return JSON.parse(response.getContentText());
}
function doGet(e) {
try {
const keyword = e.parameter.keyword;
const limit = parseInt(e.parameter.limit) || 10;
if (!keyword) return createJsonResponse({ error: "๊ฒ์ ํค์๋ ํ์" });
return createJsonResponse(fetchCoupangProducts(limit, keyword));
} catch (error) {
return createJsonResponse({ error: error.message });
}
}
function createJsonResponse(data) {
return ContentService.createTextOutput(JSON.stringify(data)).setMimeType(ContentService.MimeType.JSON);
}
์๋ ์ฝ๋๋ ์ฌ์ฉํ ๋ธ๋ก๊ทธ ์ฌ์ดํธ์ ์ ์ฉํ๋ ์ฝ๋์ ๋๋ค. ์ฝ๋ ์์ฒด๋ ์์ฃผ ๊ฐ๋จํฉ๋๋ค.
๋จผ์ ์์์ ๋ง๋ ๊ตฌ๊ธ ์คํฌ๋ฆฝํธ ์ฝ๋๋ฅผ ์คํํ๋ฉด, API ํธ์ถ์ ์ฌ์ฉํ ์ฃผ์(URL)๊ฐ ์์ฑ๋ฉ๋๋ค.
๊ทธ ์ฃผ์๋ง ๋ณต์ฌํด์ ์๋ ์ฝ๋์ ํด๋น ์์น์ ๋ถ์ฌ ๋ฃ์ผ์๋ฉด ๋ฉ๋๋ค.
๋ ธ์ถํ ์ํ ๊ฐฏ์๋ ์ด ์ฝ๋ ๋ด์์ ์ฝ๊ฒ ์์ ํ ์ ์์ต๋๋ค.
- ์์ ํ ๋ถ๋ถ: API ์ฃผ์(URL)
- ๋ ธ์ถํ ์ํ ๊ฐ์
์ด ๋ ๊ฐ์ง๋ง ๋ฐ๊พธ๋ฉด ๋ฐ๋ก ์ฌ์ฉ ๊ฐ๋ฅํฉ๋๋ค.
์ฟ ํก ์ํ ์๋ ๋ ธ์ถ์ ์ํด ๋ณ๊ฒฝํ ์ฝ๋
script
const API_URL_POST = 'Google Apps Script (GAS) ์ฃผ์ ์
๋ ฅ';
const LIMIT_POST = 3;
/script
์ด ์ฝ๋๋ ์ฝํ
์ธ ํ์ด์ง์์๋ง ์ฟ ํก ํํธ๋์ค ์ํ์ด ๋
ธ์ถ๋๋๋ก ์์ฑํ์ต๋๋ค.
๊ทธ ์ด์ ๋ ๊ฐ๊ฐ ๋ค๋ฅธ ์ฝ๋๊ฐ ๋ค์์ด๋ฉด ๊ด๋ฆฌ๊ฐ ๋ณต์กํด์ง๊ณ , ๋์ค์ ์์ ํ๊ธฐ ์ด๋ ค์์ง๊ธฐ ๋๋ฌธ์
๋๋ค.
๋น์ ํ์๋ฉด, ๊ตญ๋ฐฅ์ฒ๋ผ ์ฌ๋ฃ๋ฅผ ๋ฐ๋ก๋ฐ๋ก ๋ฃ์ด ๋ง๋๋ ๊ฒ ์๋๋ผ ๋น๋น๋ฐฅ์ฒ๋ผ ๋ชจ๋ ์ฌ๋ฃ๋ฅผ ํ๊บผ๋ฒ์ ์์ผ๋ฉด ๊ฐ๋จํ์ง๋ง,
๊ด๋ฆฌ ์ธก๋ฉด์์๋ ๊ตญ๋ฐฅ์ฒ๋ผ ๊ฐ ์ฌ๋ฃ๊ฐ ๋ถ๋ฆฌ๋์ด ์๋ ๊ฒ ๋ ํธํ๋ค๋ ๋ป์
๋๋ค.
๋ํ, ๋งค๋ฒ ๋ค๋ฅธ ์ฝ๋๋ฅผ ์คํํ์ง ์๊ณ , ์ผ๊ด๋ ์ฝ๋๋ฅผ ์ ์งํ๊ธฐ ์ํจ์ด๊ธฐ๋ ํฉ๋๋ค.
๋
ธ์ถ ์์น๋ ๊ธฐ๋ณธ์ ์ผ๋ก h3 ํ๊ทธ ์๋๋ก ์ค์ ํ์ต๋๋ค.
ํ์์ ๋ฐ๋ผ ์์น๋ฅผ ๋ณ๊ฒฝํ์
๋ ๋ฌด๋ฐฉํฉ๋๋ค.
๋ธ๋ก๊ทธ ์ฌ์ดํธ ์ฝํ ์ธ ์ ์ ์ฉํ ์ฝ๋
script
const API_URL_H3 = 'GAS ์ฃผ์';
const LIMIT_H3 = 3;
// ... ์๋ต (์ ๋ณธ๋ฌธ์ JavaScript ๋ก์ง ์ ์ฉ) ...
/script
๋ธ๋ก๊ทธ ์ฌ์ดํธ ๋ชฉ๋ก(์นดํ ๊ณ ๋ฆฌ)์ ์ ์ฉํ ์ฝ๋
script
const API_URL_POST = 'GAS ์ฃผ์';
const LIMIT_POST = 3;
// ... ์๋ต (์ ๋ณธ๋ฌธ์ JavaScript ๋ก์ง ์ ์ฉ) ...
/script
์ ์ฉ ํ๊ทธ ์์ โฌ ์๋ ๊ด๊ณ ํ์ธํด๋ณด์ธ์!
p class="shoptag"์ง์ฅ๋ฉด/p
Q. ์๋ํ ์คํฌ๋ฆฝํธ๋ฅผ ์ ์ฉํ๋๋ฐ ์ํ์ด ๊ฒ์ ์์ง์ ๋ ธ์ถ๋์ง ์์ผ๋ฉด ์ด๋ป๊ฒ ํ๋์?
A. ๊ฒ์ ๋ ธ์ถ ์ํ๋ฅผ ์ ๊ฒํ๊ธฐ ์ํด ๊ฐ์ฅ ๋จผ์ ๊ตฌ๊ธ ์์น์ฝ์์ 'URL ๊ฒ์ฌ' ๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ธ์. '์ค์ ํ์ด์ง ํ ์คํธ'๋ฅผ ํตํด ์คํฌ๋ฆฝํธ๊ฐ ์คํ๋ ํ์ ์ต์ข HTML์ ์ํ ์ ๋ณด๊ฐ ํฌํจ๋์ด ์๋์ง ํ์ธํด์ผ ํฉ๋๋ค. ๋ง์ฝ ๋ ๋๋ง ๊ฒฐ๊ณผ์ ์ํ์ด ๋ณด์ด์ง ์๋๋ค๋ฉด GAS์ ์คํ ๊ถํ ์ค์ ์ด๋ API ํ ๋น๋์ ์ ๊ฒํด ๋ณด์๊ธฐ ๋ฐ๋๋๋ค.
Q. ๊ฒ์ ์์ง์ด ์๋ฐ์คํฌ๋ฆฝํธ๋ก ์์ฑ๋ ์ฟ ํก ์ํ์ ์ฝ์ด๊ฐ ์ ์๋์?
A. ์ต์ ๊ตฌ๊ธ ๊ฒ์ ์์ง์ ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ๋ ๋๋งํ์ฌ ๋ด์ฉ์ ์์ธํ์ง๋ง, ์คํ ์๋๊ฐ ๋๋ฆฌ๊ฑฐ๋ ์ค๋ฅ๊ฐ ์์ผ๋ฉด ์๋ต๋ ์ ์์ต๋๋ค. ์ํ ๋ ธ์ถ ์ํ ์ ๊ฒ ์ ํ์ด์ง ๋ก๋ฉ ์๋๋ฅผ ์ต์ ํํ๊ณ , ๊ฒ์ ๋ด์ด ์ ๊ทผํ ๋ API ํธ์ถ์ด ์ง์ฐ๋์ง ์๋๋ก ๊ด๋ฆฌํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.
Q. ๊ฒ์ ๋ ธ์ถ ์์์ ๋ถ์ ์ ์ธ ์ํฅ์ ๋ฏธ์น์ง๋ ์์๊น์?
A. ๋จ์ํ ์ํ๋ง ๋์ดํ๋ ๊ฒ์ด ์๋๋ผ, ๋ณธ๋ฌธ์ ํต์ฌ ์ฃผ์ ์ ์ฐ๊ด๋ ์ํ์ด ๋ ธ์ถ๋๋๋ก ํค์๋ ์ค์ ์ ์ ๊ตํ๊ฒ ํ๋ ๊ฒ์ด ํต์ฌ์ ๋๋ค. ๊ฒ์ ๋ ธ์ถ ์ํ ์ ๊ฒ์ ์ฃผ๊ธฐ์ ์ผ๋ก ์งํํ๋ฉฐ, ์ฌ์ฉ์ ๊ฒฝํ์ ํด์น์ง ์๋ ์์น(์: h3 ํ๊ทธ ํ๋จ ๋ฑ)์ ๋ฐฐ์นํ์ฌ ์ฒด๋ฅ ์๊ฐ์ ์ ์งํ๋ค๋ฉด ๊ธ์ ์ ์ธ ํจ๊ณผ๋ฅผ ๊ธฐ๋ํ ์ ์์ต๋๋ค.