Discourse 쿼리를 Google Sheets로 동기화하는 자동화

Google Sheets로 Discourse Data Explorer 쿼리 동기화하기

:bookmark: 이 가이드는 Google Apps Script를 사용하여 Discourse Data Explorer 쿼리 결과를 Google Sheets로 자동으로 가져오는 방법을 설명합니다.

:person_raising_hand: 필요한 사용자 권한: 관리자(Administrator)

개요

Google Sheets를 Discourse 사이트의 Data Explorer 플러그인에 연결하면 일정된 간격으로 자동으로 쿼리 결과를 가져올 수 있습니다. 이는 대시보드 생성, 지표 추적, 또는 Discourse 관리자 접근 권한이 없는 팀 구성원과 보고서 공유에 유용합니다.

사전 요구 사항

시작하기 전에 다음 사항이 준비되어 있는지 확인하십시오:

  • Discourse 사이트에 Data Explorer 플러그인이 활성화되어 있음
  • 동기화하려는 저장된 Data Explorer 쿼리
  • Discourse 사이트의 관리자 접근 권한
  • Google Sheets에 접근할 수 있는 Google 계정

1단계: Discourse 준비하기

쿼리 ID 가져오기

  1. Discourse 사이트의 관리자 패널로 이동합니다.
  2. 플러그인(Plugins)Data Explorer로 이동합니다.
  3. 동기화하려는 쿼리를 엽니다.
  4. 브라우저 주소줄의 URL을 확인합니다. .../queries/123과 같은 형태일 것입니다. 끝의 숫자가 쿼리 ID입니다.

API 키 생성하기

  1. **관리자(Admin) → 고급(Advanced) → API 키(API Keys)**로 이동합니다.

  2. **새 API 키(New API Key)**를 클릭합니다.

  3. 키를 설정합니다:

    • 설명(Description): "Google Sheets Sync"와 같이 설명적인 이름을 입력합니다.
    • 사용자 수준(User Level): "단일 사용자(Single User)"를 선택하고 관리자 사용자를 지정하거나, "모든 사용자(All Users)"를 선택합니다.
    • 범위(Scope): "세분화(Granular)"를 선택한 후, Data Explorer 섹션에서 **쿼리 실행(run queries)**을 체크합니다.

    :information_source: 세분화된 “쿼리 실행” 범위를 사용하면 이 API 키가 Data Explorer 쿼리 실행에만 제한되므로, 전역 키를 사용하는 것보다 더 안전합니다.

  4. **저장(Save)**을 클릭하고 API 키를 즉시 복사하십시오—다시 볼 수 없습니다.

API 키에 대한 자세한 내용은 다음을 참고하세요: API 키 생성 및 구성

2단계: Google Apps Script 설정

Google Apps Script에는 UrlFetchApp이 내장 서비스로 포함되어 있습니다—설정이 필요 없습니다. 코드 편집기에 입력하면 스크립트 엔진이 자동으로 인식합니다.

  1. Google 스프레드시트를 엽니다.
  2. 확장 프로그램(Extensions)Apps Script로 이동합니다.
  3. Code.gs의 기존 코드를 모두 삭제하고 다음을 붙여넣습니다:
function syncDiscourseData() {
  // ============ CONFIGURATION ============
  const DISCOURSE_URL = "https://your-forum.com"; // Your Discourse URL (no trailing slash)
  const QUERY_ID = "123";                         // Your Data Explorer query ID
  const API_KEY = "your_api_key_here";            // Your API key
  const API_USERNAME = "system";                  // Username for API requests
  // ========================================
  
  const url = `${DISCOURSE_URL}/admin/plugins/discourse-data-explorer/queries/${QUERY_ID}/run.csv`;
  
  const options = {
    "method": "post",
    "headers": {
      "Api-Key": API_KEY,
      "Api-Username": API_USERNAME
    }
  };

  try {
    const response = UrlFetchApp.fetch(url, options);
    const csvData = response.getContentText();
    const data = Utilities.parseCsv(csvData);
    
    const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
    
    // Clear existing data and write new data
    sheet.clear(); 
    sheet.getRange(1, 1, data.length, data[0].length).setValues(data);
    
    // Add a "Last Updated" timestamp two columns after the data
    const timestampCell = sheet.getRange(1, data[0].length + 2);
    const now = new Date();
    timestampCell.setValue("Last Updated: " + Utilities.formatDate(now, Session.getScriptTimeZone(), "yyyy-MM-dd HH:mm:ss"));
    timestampCell.setFontWeight("bold");
    
    Logger.log("Successfully synced " + (data.length - 1) + " rows");
    
  } catch (e) {
    Logger.log("Error: " + e.toString());
  }
}
  1. 스크립트 상단의 구성 값을 업데이트합니다:
    • https://your-forum.com을(를) Discourse URL로 교체합니다.
    • 123을(를) 쿼리 ID로 교체합니다.
    • your_api_key_here을(를) API 키로 교체합니다.

3단계: 스크립트 실행 및 권한 승인

  1. 저장(Save) 아이콘(:floppy_disk:)을 클릭하고 프로젝트 이름을 지정합니다(예: “Discourse Sync”).

  2. 실행(Run) 버튼(:play_button:)을 클릭합니다.

  3. 권한 승인을 요청하는 팝업이 나타납니다:

    • **권한 검토(Review Permissions)**를 클릭합니다.
    • Google 계정을 선택합니다.
    • "Google이 이 앱을 인증하지 않았습니다"라는 메시지가 보이면 고급(Advanced) → **[프로젝트 이름]로 이동(unsafe)**을 클릭합니다.
    • **허용(Allow)**을 클릭합니다.
  4. Google 스프레드시트를 확인합니다—데이터가 이제 표시되어야 합니다.

:bulb: 오류가 발생하면 Apps Script 편집기에서 보기(View) → **로그(Logs)**를 클릭하여 상세한 오류 메시지를 확인하세요.

4단계: 자동 동기화 설정 (선택 사항)

일정에 따라 자동으로 동기화를 실행하려면:

  1. Apps Script 편집기에서 왼쪽 사이드바의 트리거(Triggers) 아이콘(:one_o_clock:)을 클릭합니다.

  2. **+ 트리거 추가(Add Trigger)**를 클릭합니다(우측 하단).

  3. 트리거를 구성합니다:

    • 실행할 함수(Function to run): syncDiscourseData
    • 이벤트 소스(Event source): 시간 기반(Time-driven)
    • 시간 기반 트리거 유형(Type of time based trigger): 원하는 주기를 선택합니다(예: Day timer, Hour timer).
    • 하루 중 시간/간격(Time of day/interval): 동기화를 실행할 시간을 선택합니다.
  4. **저장(Save)**을 클릭합니다.

매개변수가 있는 쿼리 처리

Data Explorer 쿼리에 매개변수가 사용되는 경우, 요청 페이로드에 추가하십시오:

const options = {
  "method": "post",
  "headers": {
    "Api-Key": API_KEY,
    "Api-Username": API_USERNAME
  },
  "payload": {
    "params": JSON.stringify({
      "start_date": "2024-01-01",
      "category_id": "5"
    })
  }
};

:warning: 모든 매개변수 값은 숫자 매개변수인 경우를 포함하여 문자열이어야 합니다.

매개변수화된 쿼리 실행에 대한 자세한 내용은 다음을 참고하세요: Discourse API를 사용하여 Data Explorer 쿼리 실행

대규모 데이터셋 처리

CSV 내보내기는 기본적으로 최대 10,000행을 제한합니다. 더 큰 데이터셋의 경우, LIMITOFFSET 매개변수를 사용하여 쿼리에 페이지네이션을 구현하십시오:

--[params]
-- integer :limit = 1000
-- integer :page = 0

SELECT *
FROM your_table
OFFSET :page * :limit
LIMIT :limit

그런 다음 더 이상 결과가 반환되지 않을 때까지 페이지를 반복하도록 스크립트를 수정하십시오.

문제 해결

문제 해결책
403 Forbidden 오류 API 키에 “쿼리 실행(run queries)” 범위가 있고 사용자 이름에 관리자 접근 권한이 있는지 확인하십시오
404 Not Found 오류 쿼리 ID가 정확하고 쿼리가 존재하는지 확인하십시오
빈 결과 Data Explorer에서 직접 실행할 때 쿼리가 데이터를 반환하는지 확인하십시오
속도 제한 오류 Discourse는 기본적으로 Data Explorer API 요청을 10초당 2회로 제한합니다. 필요시 요청 사이에 지연을 추가하십시오

추가 자료

4개의 좋아요