Skip to content

Latest commit

 

History

History
741 lines (601 loc) · 24.8 KB

File metadata and controls

741 lines (601 loc) · 24.8 KB

실습 8: Google Sheets API와 Apps Script를 활용한 웹 고객 리드 데이터 수집 자동화

이번 실습에서는 외부 웹사이트에서 고객 리드 데이터를 수집하고, Google Apps Script를 API 엔드포인트로 활용하여 데이터를 수신한 뒤 Google Sheets에 자동으로 정리·저장하는 시스템을 구축합니다.

전체 흐름: 외부 웹사이트(HTML 폼)fetch()로 POST 전송Google Apps Script(doPost)Google Sheets 저장

사용 도구: Google Apps Script, Google Sheets API, Google Cloud Platform


1. Google Cloud 프로젝트 설정 및 Sheets API 활성화

1-1. Google Cloud 프로젝트 생성

  1. 프로젝트 생성:
    • Google Cloud Console에 접속하여 새로운 프로젝트를 생성합니다.
    • 프로젝트 이름 예시: Web Lead Collection

1-2. Google Sheets API 활성화

  1. API 활성화:

    • 생성한 프로젝트에서 **'API 및 서비스' > '라이브러리'**로 이동합니다.
    • 검색창에 Google Sheets API를 입력하고 나타나는 결과를 선택한 후 **'사용 설정'**을 클릭합니다.
  2. OAuth 동의 화면 설정:

    • **'API 및 서비스' > 'OAuth 동의 화면'**으로 이동합니다.
    • 사용자 유형을 **'외부'**로 선택하고, 앱 이름과 필수 정보를 입력합니다.
    • 범위(Scopes)에서 https://www.googleapis.com/auth/spreadsheets를 추가합니다.

2. Google Sheets 설정

2-1. 리드 관리 스프레드시트 생성

  1. 스프레드시트 생성:

    • Google Sheets에 접속하여 새로운 스프레드시트를 만듭니다.
    • 예시: 고객 리드 관리
  2. 시트 구성:

    • 첫 번째 행에 다음 헤더를 추가합니다:
    A B C D E F G
    수집일시 이름 이메일 전화번호 회사명 유입경로 관심제품
  3. 스프레드시트 ID 확인:

    • 스프레드시트 URL에서 ID를 확인합니다.
    • 예: https://docs.google.com/spreadsheets/d/SPREADSHEET_ID/edit에서 SPREADSHEET_ID 부분이 ID입니다.

3. Google Apps Script 프로젝트 생성 및 설정

3-1. Apps Script 프로젝트 생성

  1. 프로젝트 생성:

    • Google Apps Script에 접속하여 **'새 프로젝트'**를 클릭합니다.
    • 프로젝트 이름 예시: Lead Collection Web App
  2. Google Cloud 프로젝트 연결:

    • Apps Script 편집기에서 '프로젝트 설정'(톱니바퀴 아이콘)을 클릭합니다.
    • 'Google Cloud Platform(GCP) 프로젝트' 섹션에서 **'프로젝트 변경'**을 클릭하고, 앞서 생성한 GCP 프로젝트 번호를 입력하여 연결합니다.

3-2. OAuth 범위 설정

  1. appsscript.json 수정:

    • 편집기 왼쪽의 **'프로젝트 설정'**에서 **'appsscript.json 매니페스트 파일을 편집기에 표시'**를 체크합니다.
    • appsscript.json 파일을 열어 다음과 같이 수정합니다:
    {
      "timeZone": "Asia/Seoul",
      "dependencies": {},
      "exceptionLogging": "STACKDRIVER",
      "webapp": {
        "executeAs": "USER_DEPLOYING",
        "access": "ANYONE_ANONYMOUS"
      },
      "oauthScopes": [
        "https://www.googleapis.com/auth/spreadsheets",
        "https://www.googleapis.com/auth/script.external_request"
      ]
    }

4. Google Apps Script - API 엔드포인트 구현 (Code.gs)

외부 웹사이트에서 전송한 리드 데이터를 수신하여 Google Sheets에 저장하는 API 엔드포인트를 작성합니다.

4-1. Code.gs 작성

Code.gs 파일에 다음과 같이 작성합니다:

// 스프레드시트 ID (본인의 스프레드시트 ID로 교체)
var SPREADSHEET_ID = 'YOUR_SPREADSHEET_ID';
var SHEET_NAME = 'Sheet1';

/**
 * 외부 웹사이트에서 POST 요청으로 전송된 리드 데이터를 수신하는 함수
 * @param {Object} e - POST 요청 이벤트 객체
 * @returns {TextOutput} - JSON 응답
 */
function doPost(e) {
  try {
    var leadData = JSON.parse(e.postData.contents);

    // 필수 필드 검증
    if (!leadData.name || !leadData.email || !leadData.phone) {
      return ContentService.createTextOutput(
        JSON.stringify({ status: 'error', message: '필수 필드(name, email, phone)가 누락되었습니다.' })
      ).setMimeType(ContentService.MimeType.JSON);
    }

    // Google Sheets에 데이터 저장
    var sheet = SpreadsheetApp.openById(SPREADSHEET_ID).getSheetByName(SHEET_NAME);
    var timestamp = Utilities.formatDate(new Date(), 'Asia/Seoul', 'yyyy-MM-dd HH:mm:ss');

    sheet.appendRow([
      timestamp,
      leadData.name,
      leadData.email,
      leadData.phone,
      leadData.company || '',
      leadData.source || '',
      leadData.product || ''
    ]);

    Logger.log('리드 데이터 저장 완료: ' + leadData.name);

    return ContentService.createTextOutput(
      JSON.stringify({ status: 'success', message: '리드 데이터가 저장되었습니다.' })
    ).setMimeType(ContentService.MimeType.JSON);

  } catch (error) {
    Logger.log('doPost 오류: ' + error.message);
    return ContentService.createTextOutput(
      JSON.stringify({ status: 'error', message: error.message })
    ).setMimeType(ContentService.MimeType.JSON);
  }
}

/**
 * GET 요청 시 API 상태를 확인하는 함수
 */
function doGet() {
  return ContentService.createTextOutput(
    JSON.stringify({ status: 'ok', message: 'Lead Collection API is running.' })
  ).setMimeType(ContentService.MimeType.JSON);
}

YOUR_SPREADSHEET_ID를 앞서 확인한 실제 스프레드시트 ID로 교체해야 합니다.


5. Apps Script 웹 앱 배포 (API 엔드포인트)

  1. 배포 설정:

    • Apps Script 편집기에서 **'배포' > '새 배포'**를 클릭합니다.
    • 왼쪽 톱니바퀴 아이콘에서 **'웹 앱'**을 선택합니다.
  2. 배포 옵션 설정:

    • 설명: 고객 리드 수집 API v1
    • 실행 사용자: 나(본인 계정)
    • 액세스 권한: 모든 사용자 (외부 웹사이트에서 접근해야 하므로)
  3. 배포 완료:

    • '배포' 버튼을 클릭합니다.
    • 권한 요청 창이 나타나면 지시에 따라 권한을 승인합니다.
    • 생성된 웹 앱 URL을 복사합니다. (예: https://script.google.com/macros/s/AKfycbx.../exec)
    • 이 URL이 외부 웹사이트에서 데이터를 전송할 API 엔드포인트가 됩니다.
  4. API 동작 확인:

    • 브라우저에서 웹 앱 URL에 접속하면 다음과 같은 JSON 응답이 표시됩니다:
    { "status": "ok", "message": "Lead Collection API is running." }

6. 외부 웹사이트 - 리드 수집 폼 구현

외부 웹사이트에 리드 수집 폼을 작성하고, fetch()를 사용하여 Apps Script API로 데이터를 전송합니다.

6-1. HTML 파일 작성 (index.html)

외부 웹 서버 또는 로컬 환경에 다음 HTML 파일을 생성합니다:

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>제품 문의 및 상담 신청</title>
  <style>
    body {
      font-family: 'Arial', sans-serif;
      max-width: 600px;
      margin: 40px auto;
      padding: 20px;
      background-color: #f9f9f9;
    }
    h2 {
      color: #333;
      text-align: center;
    }
    .form-group {
      margin-bottom: 15px;
    }
    label {
      display: block;
      margin-bottom: 5px;
      font-weight: bold;
      color: #555;
    }
    input, select {
      width: 100%;
      padding: 10px;
      border: 1px solid #ddd;
      border-radius: 4px;
      box-sizing: border-box;
    }
    button {
      width: 100%;
      padding: 12px;
      background-color: #4CAF50;
      color: white;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      font-size: 16px;
    }
    button:hover {
      background-color: #45a049;
    }
    button:disabled {
      background-color: #ccc;
      cursor: not-allowed;
    }
    .success-message {
      display: none;
      text-align: center;
      color: #4CAF50;
      font-size: 18px;
      margin-top: 20px;
    }
    .error-message {
      display: none;
      text-align: center;
      color: #f44336;
      font-size: 14px;
      margin-top: 10px;
    }
  </style>
</head>
<body>
  <h2>제품 문의 및 상담 신청</h2>
  <form id="leadForm">
    <div class="form-group">
      <label for="name">이름 *</label>
      <input type="text" id="name" name="name" required>
    </div>
    <div class="form-group">
      <label for="email">이메일 *</label>
      <input type="email" id="email" name="email" required>
    </div>
    <div class="form-group">
      <label for="phone">전화번호 *</label>
      <input type="tel" id="phone" name="phone" required>
    </div>
    <div class="form-group">
      <label for="company">회사명</label>
      <input type="text" id="company" name="company">
    </div>
    <div class="form-group">
      <label for="source">유입경로</label>
      <select id="source" name="source">
        <option value="">선택해주세요</option>
        <option value="검색엔진">검색엔진</option>
        <option value="SNS">SNS</option>
        <option value="블로그">블로그</option>
        <option value="지인추천">지인추천</option>
        <option value="광고">광고</option>
        <option value="기타">기타</option>
      </select>
    </div>
    <div class="form-group">
      <label for="product">관심 제품</label>
      <select id="product" name="product">
        <option value="">선택해주세요</option>
        <option value="제품A">제품 A</option>
        <option value="제품B">제품 B</option>
        <option value="제품C">제품 C</option>
        <option value="전체">전체 제품</option>
      </select>
    </div>
    <button type="button" id="submitBtn" onclick="submitLead()">상담 신청하기</button>
  </form>
  <div id="successMessage" class="success-message">
    상담 신청이 완료되었습니다. 감사합니다!
  </div>
  <div id="errorMessage" class="error-message"></div>

  <script>
    // Apps Script 웹 앱 URL (배포 시 생성된 URL로 교체)
    var APPS_SCRIPT_URL = 'https://script.google.com/macros/s/YOUR_DEPLOYMENT_ID/exec';

    function submitLead() {
      var name = document.getElementById('name').value.trim();
      var email = document.getElementById('email').value.trim();
      var phone = document.getElementById('phone').value.trim();

      // 필수 필드 검증
      if (!name || !email || !phone) {
        alert('이름, 이메일, 전화번호는 필수 입력 항목입니다.');
        return;
      }

      // 이메일 형식 검증
      var emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
      if (!emailRegex.test(email)) {
        alert('올바른 이메일 형식을 입력해주세요.');
        return;
      }

      var leadData = {
        name: name,
        email: email,
        phone: phone,
        company: document.getElementById('company').value.trim(),
        source: document.getElementById('source').value,
        product: document.getElementById('product').value
      };

      // 버튼 비활성화 (중복 전송 방지)
      var submitBtn = document.getElementById('submitBtn');
      submitBtn.disabled = true;
      submitBtn.textContent = '전송 중...';

      // Apps Script API로 POST 전송
      fetch(APPS_SCRIPT_URL, {
        method: 'POST',
        mode: 'no-cors',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(leadData)
      })
      .then(function() {
        // no-cors 모드에서는 응답을 읽을 수 없으므로 성공으로 처리
        document.getElementById('leadForm').style.display = 'none';
        document.getElementById('successMessage').style.display = 'block';
      })
      .catch(function(error) {
        document.getElementById('errorMessage').textContent = '제출 중 오류가 발생했습니다. 다시 시도해주세요.';
        document.getElementById('errorMessage').style.display = 'block';
        submitBtn.disabled = false;
        submitBtn.textContent = '상담 신청하기';
      });
    }
  </script>
</body>
</html>

YOUR_DEPLOYMENT_ID를 5단계에서 복사한 실제 배포 URL로 교체해야 합니다.

6-2. fetch()와 no-cors 모드에 대한 참고

  • Apps Script 웹 앱은 CORS 헤더를 직접 제어할 수 없으므로, mode: 'no-cors'를 사용합니다.
  • no-cors 모드에서는 응답 본문을 읽을 수 없지만, 데이터 전송 자체는 정상적으로 이루어집니다.
  • 응답 확인이 필요한 경우, Apps Script를 JSONP 방식으로 구현하거나 Google Sheets에서 직접 저장 여부를 확인합니다.

7. 테스트 및 검증

7-1. API 테스트 (curl)

터미널에서 다음 명령어로 Apps Script API가 정상 동작하는지 먼저 확인합니다:

curl -L -X POST \
  'https://script.google.com/macros/s/YOUR_DEPLOYMENT_ID/exec' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "테스트",
    "email": "test@example.com",
    "phone": "010-0000-0000",
    "company": "테스트회사",
    "source": "검색엔진",
    "product": "제품A"
  }'

정상 응답 예시:

{ "status": "success", "message": "리드 데이터가 저장되었습니다." }

7-2. 외부 웹사이트에서 폼 테스트

  1. HTML 파일 실행:

    • index.html 파일을 브라우저에서 열거나, 로컬 웹 서버로 실행합니다.
    • 예: npx serve . 또는 VS Code의 Live Server 확장 활용
  2. 테스트 데이터 입력:

    • 다음과 같이 테스트 데이터를 입력하고 '상담 신청하기' 버튼을 클릭합니다:
      • 이름: 홍길동
      • 이메일: hong@example.com
      • 전화번호: 010-1234-5678
      • 회사명: 테스트 주식회사
      • 유입경로: 검색엔진
      • 관심 제품: 제품 A
  3. 데이터 확인:

    • Google Sheets를 열어 입력한 데이터가 정상적으로 저장되었는지 확인합니다.
    수집일시 이름 이메일 전화번호 회사명 유입경로 관심제품
    2025-01-15 14:30:00 홍길동 hong@example.com 010-1234-5678 테스트 주식회사 검색엔진 제품A

추가 실습 1: 수집된 리드 데이터를 기반으로 고객 등급 자동 분류

수집된 리드 데이터에서 회사명, 관심 제품 등의 정보를 기반으로 고객 등급(예: VIP, 일반, 잠재)을 자동으로 분류하여 시트에 태깅합니다.

1. 스프레드시트 헤더 추가

  • 기존 시트의 H열에 고객등급 헤더를 추가합니다.

2. 등급 분류 함수 작성

Code.gs에 다음 함수를 추가합니다:

/**
 * 리드 데이터를 기반으로 고객 등급을 분류하는 함수
 * @param {Object} leadData - 리드 데이터
 * @returns {string} - 고객 등급 (VIP / 일반 / 잠재)
 */
function classifyLead(leadData) {
  // VIP: 회사명이 있고, 전체 제품에 관심이 있는 경우
  if (leadData.company && leadData.product === '전체') {
    return 'VIP';
  }
  // 일반: 회사명이 있는 경우
  if (leadData.company) {
    return '일반';
  }
  // 잠재: 그 외
  return '잠재';
}

3. doPost 함수 수정

기존 doPost 함수를 수정하여 등급 분류를 추가합니다:

function doPost(e) {
  try {
    var leadData = JSON.parse(e.postData.contents);

    if (!leadData.name || !leadData.email || !leadData.phone) {
      return ContentService.createTextOutput(
        JSON.stringify({ status: 'error', message: '필수 필드가 누락되었습니다.' })
      ).setMimeType(ContentService.MimeType.JSON);
    }

    var sheet = SpreadsheetApp.openById(SPREADSHEET_ID).getSheetByName(SHEET_NAME);
    var timestamp = Utilities.formatDate(new Date(), 'Asia/Seoul', 'yyyy-MM-dd HH:mm:ss');

    // 고객 등급 분류
    var grade = classifyLead(leadData);

    sheet.appendRow([
      timestamp,
      leadData.name,
      leadData.email,
      leadData.phone,
      leadData.company || '',
      leadData.source || '',
      leadData.product || '',
      grade  // 고객 등급 추가
    ]);

    Logger.log('리드 저장 완료 - 이름: ' + leadData.name + ', 등급: ' + grade);

    return ContentService.createTextOutput(
      JSON.stringify({ status: 'success', message: '리드 데이터가 저장되었습니다.', grade: grade })
    ).setMimeType(ContentService.MimeType.JSON);

  } catch (error) {
    return ContentService.createTextOutput(
      JSON.stringify({ status: 'error', message: error.message })
    ).setMimeType(ContentService.MimeType.JSON);
  }
}

추가 실습 2: 신규 리드 유입 시 Slack/이메일 알림 자동 발송

신규 리드가 유입되면 영업팀에 Slack 메시지 또는 이메일로 알림을 자동 발송합니다.

1. Slack Incoming Webhook 설정

  1. Slack API에서 새로운 앱을 생성합니다.
  2. Incoming Webhooks를 활성화하고, 알림을 받을 채널을 선택합니다.
  3. 생성된 Webhook URL을 복사합니다.

2. 알림 함수 작성

Code.gs에 다음 함수를 추가합니다:

var SLACK_WEBHOOK_URL = 'YOUR_SLACK_WEBHOOK_URL';
var NOTIFY_EMAIL = 'sales@example.com'; // 영업팀 이메일

/**
 * Slack으로 신규 리드 알림을 발송하는 함수
 * @param {Object} leadData - 리드 데이터
 * @param {string} grade - 고객 등급
 */
function sendSlackNotification(leadData, grade) {
  var message = {
    text: ':tada: *신규 리드 유입!*',
    attachments: [{
      color: grade === 'VIP' ? '#ff0000' : '#36a64f',
      fields: [
        { title: '이름', value: leadData.name, short: true },
        { title: '고객등급', value: grade, short: true },
        { title: '이메일', value: leadData.email, short: true },
        { title: '전화번호', value: leadData.phone, short: true },
        { title: '회사명', value: leadData.company || '미입력', short: true },
        { title: '관심제품', value: leadData.product || '미선택', short: true },
        { title: '유입경로', value: leadData.source || '미선택', short: true }
      ]
    }]
  };

  var options = {
    method: 'post',
    contentType: 'application/json',
    payload: JSON.stringify(message)
  };

  UrlFetchApp.fetch(SLACK_WEBHOOK_URL, options);
}

/**
 * 이메일로 신규 리드 알림을 발송하는 함수
 * @param {Object} leadData - 리드 데이터
 * @param {string} grade - 고객 등급
 */
function sendEmailNotification(leadData, grade) {
  var subject = '[신규 리드] ' + leadData.name + ' (' + grade + ')';
  var htmlBody =
    '<h3>신규 리드가 유입되었습니다</h3>' +
    '<table border="1" cellpadding="8" cellspacing="0">' +
    '<tr><td><b>이름</b></td><td>' + leadData.name + '</td></tr>' +
    '<tr><td><b>이메일</b></td><td>' + leadData.email + '</td></tr>' +
    '<tr><td><b>전화번호</b></td><td>' + leadData.phone + '</td></tr>' +
    '<tr><td><b>회사명</b></td><td>' + (leadData.company || '미입력') + '</td></tr>' +
    '<tr><td><b>유입경로</b></td><td>' + (leadData.source || '미선택') + '</td></tr>' +
    '<tr><td><b>관심제품</b></td><td>' + (leadData.product || '미선택') + '</td></tr>' +
    '<tr><td><b>고객등급</b></td><td>' + grade + '</td></tr>' +
    '</table>';

  MailApp.sendEmail({
    to: NOTIFY_EMAIL,
    subject: subject,
    htmlBody: htmlBody
  });
}

3. doPost 함수에 알림 추가

function doPost(e) {
  try {
    var leadData = JSON.parse(e.postData.contents);

    if (!leadData.name || !leadData.email || !leadData.phone) {
      return ContentService.createTextOutput(
        JSON.stringify({ status: 'error', message: '필수 필드가 누락되었습니다.' })
      ).setMimeType(ContentService.MimeType.JSON);
    }

    var sheet = SpreadsheetApp.openById(SPREADSHEET_ID).getSheetByName(SHEET_NAME);
    var timestamp = Utilities.formatDate(new Date(), 'Asia/Seoul', 'yyyy-MM-dd HH:mm:ss');
    var grade = classifyLead(leadData);

    sheet.appendRow([
      timestamp,
      leadData.name,
      leadData.email,
      leadData.phone,
      leadData.company || '',
      leadData.source || '',
      leadData.product || '',
      grade
    ]);

    // Slack 알림 발송
    sendSlackNotification(leadData, grade);

    // 이메일 알림 발송
    sendEmailNotification(leadData, grade);

    Logger.log('리드 저장 및 알림 발송 완료: ' + leadData.name);

    return ContentService.createTextOutput(
      JSON.stringify({ status: 'success', message: '리드 데이터가 저장되었습니다.', grade: grade })
    ).setMimeType(ContentService.MimeType.JSON);

  } catch (error) {
    return ContentService.createTextOutput(
      JSON.stringify({ status: 'error', message: error.message })
    ).setMimeType(ContentService.MimeType.JSON);
  }
}

YOUR_SLACK_WEBHOOK_URLNOTIFY_EMAIL을 실제 값으로 교체해야 합니다.


추가 실습 3: 시간 기반 트리거로 주기적 웹 리드 데이터 자동 수집

외부 웹사이트(예: 채용 플랫폼, 비즈니스 디렉토리)에서 잠재 고객 정보를 주기적으로 수집하여 Google Sheets에 저장합니다.

1. 외부 웹 데이터 수집 함수 작성

Code.gs에 다음 함수를 추가합니다:

/**
 * 외부 웹 API에서 리드 데이터를 수집하는 함수
 * 예시: 공개 API에서 비즈니스 정보를 가져옴
 */
function fetchExternalLeads() {
  var apiUrl = 'https://api.example.com/leads'; // 실제 API URL로 교체

  var options = {
    method: 'get',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY'
    }
  };

  try {
    var response = UrlFetchApp.fetch(apiUrl, options);
    var data = JSON.parse(response.getContentText());

    var sheet = SpreadsheetApp.openById(SPREADSHEET_ID).getSheetByName(SHEET_NAME);

    data.forEach(function(lead) {
      // 중복 검사: 이메일 기준
      if (!isDuplicate(sheet, lead.email)) {
        var timestamp = Utilities.formatDate(new Date(), 'Asia/Seoul', 'yyyy-MM-dd HH:mm:ss');
        var grade = classifyLead(lead);

        sheet.appendRow([
          timestamp,
          lead.name,
          lead.email,
          lead.phone,
          lead.company,
          '자동수집',
          lead.product || '',
          grade
        ]);
      }
    });

    Logger.log('외부 리드 수집 완료: ' + data.length + '건 처리');
  } catch (error) {
    Logger.log('외부 리드 수집 오류: ' + error.message);
  }
}

/**
 * 이메일 기준으로 중복 데이터를 검사하는 함수
 * @param {Sheet} sheet - 대상 시트
 * @param {string} email - 검사할 이메일 주소
 * @returns {boolean} - 중복 여부
 */
function isDuplicate(sheet, email) {
  var data = sheet.getDataRange().getValues();
  for (var i = 1; i < data.length; i++) {
    if (data[i][2] === email) { // C열(이메일)
      return true;
    }
  }
  return false;
}

2. 시간 기반 트리거 설정

  1. 트리거 추가:

    • Apps Script 편집기에서 왼쪽 메뉴의 시계 아이콘(트리거)을 클릭합니다.
    • '트리거 추가' 버튼을 클릭합니다.
  2. 트리거 설정:

    • 실행할 함수: fetchExternalLeads
    • 이벤트 소스: 시간 기반
    • 시간 기반 트리거 유형: 시간 간격 타이머
    • 간격 선택: 매 1시간마다 (필요에 따라 조정)
  3. 권한 부여:

    • 권한 요청 창이 나타나면 지시에 따라 권한을 승인합니다.

주의 사항

  • API 키 보안: SPREADSHEET_ID, SLACK_WEBHOOK_URL, API 키 등 민감한 정보는 코드에 직접 작성하지 않고 Apps Script의 스크립트 속성(프로젝트 설정 > 스크립트 속성)에 저장하여 관리하는 것을 권장합니다.

    // 스크립트 속성에서 값 가져오기
    var SPREADSHEET_ID = PropertiesService.getScriptProperties().getProperty('SPREADSHEET_ID');
  • API 호출 한도: Google Apps Script는 일일 실행 시간 및 API 호출 횟수에 제한이 있습니다. 할당량 문서를 확인하세요.

  • 개인정보 보호: 고객의 개인정보를 수집·저장할 때는 개인정보 보호법을 준수해야 하며, 수집 목적과 이용 범위를 명확히 고지해야 합니다.


이 실습을 통해 웹에서 고객 리드 데이터를 수집하고 Google Sheets에 자동으로 저장하며, 등급 분류와 알림 발송까지 자동화하는 시스템을 구축할 수 있습니다. 이는 영업팀의 리드 관리 효율을 크게 높이는 데 활용될 수 있습니다.