본문 바로가기

구글 시트에 제목만 입력하면 블로그 글이 자동으로 올라갈까?|ChatGPT·Apps Script 자동화 방법

BinniH2 2026. 10. 11.
반응형

구글 시트 작업 화면이 열린 노트북과 블로그 자동화 주제가 표시된 책상

 

구글 시트에 블로그 제목을 한 줄 적어두면, 알아서 글을 쓰고 발행까지 해주면 얼마나 편할까요? 반복해서 글을 작성하는 분이라면 한 번쯤 생각해 보셨을 겁니다. 하지만 글을 자동으로 만드는 것과 블로그에 자동으로 올리는 것은 서로 다른 작업입니다.

결론부터 말씀드리면, 구글 시트 블로그 자동화로 ChatGPT API에 제목을 전달해 초안을 만들고 Google Drive에 저장하는 것까지는 가능합니다. 다만 티스토리는 공식 글쓰기 Open API가 종료되어, 이 방식만으로 티스토리 글이 자동 발행되지는 않습니다.

핵심 요약

구글 시트에 제목을 입력하면 Apps Script가 OpenAI API를 호출해 글 초안을 만들고 Google Drive에 자동 저장하도록 설정할 수 있습니다. 다만 티스토리는 공식 Open API가 종료되었으므로 초안을 검토한 뒤 티스토리 편집기에서 직접 발행해야 합니다.

구글 시트에 제목만 입력하면 실제로 어디까지 자동화될까?

작업을 세 부분으로 나누어 보면 이해하기 쉽습니다. 먼저 구글 시트가 제목과 진행 상태를 관리하고, Apps Script가 입력을 감지합니다. 그다음 OpenAI API가 글을 생성하고, 완성된 초안을 Google Drive에 파일로 남깁니다.

제목을 입력할 행이 강조된 표 형태의 작업 계획 이미지

작업 자동화 가능 여부
제목 입력 감지 가능: Apps Script 설치형 트리거
AI 글 초안 생성 가능: OpenAI API 호출
초안 파일 자동 저장 가능: Google Drive
티스토리 공식 API 발행 불가: Open API 종료

티스토리는 2023년 12월 22일 공지에서 Open API를 2023년 12월 말부터 2024년 2월 말까지 순차 종료한다고 안내했습니다. 여기에는 글 작성·수정과 이미지·파일 첨부 기능도 포함되어 있습니다. 예전의 tistory/post/write 호출 방법을 그대로 따라 하는 글은 현재 기준으로 맞지 않습니다.

자동화 전에 준비할 것과 구글 시트 구성

준비물은 구글 계정, 구글 시트, Apps Script, OpenAI API 키, 그리고 결과물을 보관할 Google Drive 폴더입니다. ChatGPT 웹 구독과 OpenAI API 이용 요금은 별개이므로 API 계정의 결제 설정과 사용량을 먼저 확인하세요.

시트의 탭 이름은 글목록으로 지정하고, 첫 번째 행에 A1: 제목, B1: 상태, C1: 초안 링크를 적습니다. 실제 제목은 A2부터 입력합니다. 자동화가 성공하면 B열은 ‘검토 대기’로 바뀌고 C열에는 생성된 초안 링크가 기록됩니다.

구글 시트 입력에서 자동 처리와 문서 생성으로 이어지는 세 단계 그림

ChatGPT API와 Apps Script 연결하는 방법

  1. 구글 시트에서 확장 프로그램 → Apps Script를 열어 새 스크립트를 만듭니다.
  2. Apps Script의 프로젝트 설정 → 스크립트 속성에서 OPENAI_API_KEY에 API 키를, DRAFT_FOLDER_ID에 초안을 보관할 Google Drive 폴더 ID를 등록합니다. 폴더 ID는 해당 폴더 주소에 포함된 식별자입니다.
  3. 아래 예제를 스크립트 편집기에 붙여 넣고 저장합니다. 이 예제는 제목을 한 칸씩 직접 수정할 때 초안 텍스트 파일을 만듭니다.
  4. 왼쪽의 트리거에서 트리거를 추가하고 실행할 함수를 onSheetTitleEdit, 이벤트 소스를 ‘스프레드시트에서’, 이벤트 유형을 ‘수정 시’로 선택한 후 권한을 승인합니다.
  5. ‘글목록’ 시트 A2에 시험 제목을 입력해 B열 상태와 C열 파일 링크를 확인합니다.

외부 API 호출과 Drive 파일 생성에는 권한이 필요하므로 단순 onEdit 대신 설치형 수정 트리거를 사용하는 것이 중요합니다.

Apps Script 예제 코드 펼쳐 보기
function onSheetTitleEdit(e) {
  if (!e || !e.range) return;
  const cell = e.range;
  const sheet = cell.getSheet();
  if (sheet.getName() !== '글목록' || cell.getColumn() !== 1 ||
      cell.getRow() < 2 || cell.getNumRows() !== 1 ||
      cell.getNumColumns() !== 1) return;

  const title = String(cell.getDisplayValue()).trim();
  if (!title) return;
  const row = cell.getRow();
  const state = sheet.getRange(row, 2);
  const link = sheet.getRange(row, 3);
  const lock = LockService.getDocumentLock();
  if (!lock.tryLock(10000)) return;

  try {
    if (String(state.getDisplayValue()).trim()) return;
    state.setValue('생성 중');
    const cfg = PropertiesService.getScriptProperties();
    const key = cfg.getProperty('OPENAI_API_KEY');
    const folderId = cfg.getProperty('DRAFT_FOLDER_ID');
    if (!key || !folderId) throw new Error('스크립트 속성을 확인하세요.');

    const prompt = '한국어 생활정보 블로그 초안을 작성하세요. 제목: ' + title +
      '\n구성: 도입, H2 소제목, 실용적인 방법, 주의사항, 질문 3개, 정리.' +
      '\n사실 확인이 필요한 수치·정책·URL은 지어내지 말고 확인 필요로 표시하세요.' +
      '\n독자가 검토할 수 있도록 자연스러운 존댓말로 작성하세요.';
    const response = UrlFetchApp.fetch('https://api.openai.com/v1/responses', {
      method: 'post',
      contentType: 'application/json',
      headers: { Authorization: 'Bearer ' + key },
      payload: JSON.stringify({ model: 'gpt-5.4-mini', input: prompt }),
      muteHttpExceptions: true
    });
    if (response.getResponseCode() !== 200) {
      throw new Error('API 응답 오류: ' + response.getResponseCode());
    }
    const data = JSON.parse(response.getContentText());
    const body = (data.output || [])
      .filter(x => x.type === 'message')
      .flatMap(x => x.content || [])
      .filter(x => x.type === 'output_text')
      .map(x => x.text).join('\n').trim();
    if (!body) throw new Error('생성 결과가 비어 있습니다.');

    const safeName = title.replace(/[\\/:*?"<>|]/g, '-').slice(0, 70);
    const file = DriveApp.getFolderById(folderId)
      .createFile(safeName + '.txt', body, 'text/plain');
    link.setValue(file.getUrl());
    state.setValue('검토 대기');
  } catch (err) {
    state.setValue('오류: ' + String(err.message).slice(0, 90));
  } finally {
    lock.releaseLock();
  }
}

이 예제는 텍스트 초안 저장용으로, 사진 생성이나 티스토리 글 발행 코드를 포함하지 않습니다. 여러 행을 한 번에 붙여 넣는 경우에는 동작하지 않도록 설정했으며, 같은 행을 다시 실행하려면 B열의 기존 상태를 지우고 A열 제목을 다시 수정해야 합니다.

티스토리까지 자동으로 발행하려면 무엇이 다를까?

티스토리에서는 공식 Open API 발행이 지원되지 않기 때문에 Apps Script만 추가한다고 자동 게시가 되는 것은 아닙니다. 일부 비공식 브라우저 자동화는 웹 편집기를 조작하지만, 로그인 상태나 에디터 변경에 따라 실패할 수 있고 서비스 정책도 따로 확인해야 합니다.

따라서 티스토리 운영자라면 제목 입력 → 초안 생성 → 사실 확인과 이미지 정리 → 티스토리 편집기에서 발행 순서가 현실적인 방법입니다. 반면 WordPress처럼 공식 글쓰기 API가 제공되는 플랫폼은 인증과 권한을 갖춘 별도의 발행 연동을 추가할 수 있지만, 이는 여기서 소개한 티스토리 설정과는 다릅니다.

작성된 글을 항목별로 확인하는 문서와 돋보기 그림

자동 생성 후 꼭 확인할 부분

완성된 글처럼 보여도 AI가 수수료, 신청 기간, 버튼 이름, 공식 링크를 잘못 적을 수 있습니다. 특히 정책·요금·법률·건강 관련 내용은 해당 기관의 최신 자료를 직접 확인하고, 실제 사용 경험과 독자에게 필요한 설명을 추가한 후 발행하세요.

  • 중복 실행: 상태가 비어 있는 제목 셀을 다시 수정하면 새로운 API 요청이 발생할 수 있습니다.
  • API 키 보안: 키를 시트 셀이나 게시글 코드에 넣지 말고 스크립트 속성으로 관리하세요. 스크립트 편집 권한도 필요한 사람에게만 제공하세요.
  • 호출 제한과 비용: API 요금과 Google Apps Script 실행 할당량, 오류 기록을 함께 확인하세요.
  • 이미지와 링크: 텍스트 초안만 자동 저장됩니다. 이미지 삽입과 실제 티스토리 발행은 별도 작업입니다.

자주 묻는 질문

Q1. ChatGPT 유료 구독이 있으면 API 키도 무료인가요?

아닙니다. ChatGPT 구독과 OpenAI API는 별도 결제 체계로 운영됩니다. API 사용량에 따른 비용을 확인하세요.

Q2. 구글 시트를 켜 두어야 글이 생성되나요?

설치형 수정 트리거는 시트가 편집될 때 실행되도록 설정합니다. 다만 단순히 시간이 지났다고 새 글이 생성되는 것은 아니며, 시간 기반 자동 확인을 원하면 별도 트리거와 처리 코드를 마련해야 합니다.

Q3. 시트에 제목을 여러 개 한꺼번에 붙여 넣어도 되나요?

위 예제는 실수와 중복 처리를 줄이기 위해 한 번에 한 셀만 처리합니다. 대량 등록은 행별 상태 관리와 일괄 처리 기능을 별도로 개발해야 합니다.

Q4. 이미지까지 자동으로 넣고 티스토리에 발행할 수 있나요?

이미지 생성과 보관은 별도 서비스 연동으로 확장할 수 있지만, 티스토리 공식 Open API를 통한 자동 업로드·발행은 지원되지 않습니다. 이미지 품질과 저작권을 확인하고 편집기에서 작업하는 편이 안전합니다.

정리: 글쓰기 자동화와 발행 자동화는 구분하세요

구글 시트 제목만으로 블로그 초안을 만드는 자동화는 충분히 시도해 볼 만합니다. 제목 목록을 관리하고 반복되는 초안 작업을 줄이는 데 특히 유용합니다. 다만 티스토리에 자동 발행까지 되는 것으로 이해하면 안 됩니다. 현재 가능한 자동화 범위를 정확히 정하고, 최종 검토와 발행은 직접 책임지는 방식으로 시작해 보세요.

※ 플랫폼 기능, API 모델 및 사용 요금은 변경될 수 있으므로 실제 설정 전 해당 서비스의 최신 공식 안내를 확인하세요.

관련 자료

반응형

댓글