명상충만
명상충만
🌿 뉴비 파트너
🚀 SNS 챌린지 달성자

구글 시트로 OSMU (One Sorce Multi Use) 컨텐츠 생성결과를 보내도록 자동화 할 때 주의점

소개

일전에 구글 스크립트를 통해 OSMU를 시도했죠. 그러나 함수로 만들었기 때문에 텍스트 복사가 안되는 것을 경험합니다. 그래서 함수없이 지정된 열에 주어진 프롬프트를 실행하도록 다시 만들었는데, 생각보다 많은 경험을 하게 됩니다.

‎​

Google Docs에 있는 문서의 스크린샷

위 그림을 보면 문제점이 2개가 있습니다.

[문제 1] 페이지 열때마다 로딩이 되어
1) 이전에 생성된 기록이 지워지며 2) 생성될때마다 api사용 요금이 과금된다는 것이지요.

[문제 2] 생성된 글이 있는 셀을 클릭해서 텍스트를 복사하려면 복사가 안된다는거에요.
그럼 그 텍스트를 화면캡쳐해서 다시 텍스트로 변환해야하는 불편함이 있겠지요?

유용했지만, 사용성이 떨어지는 이 시트는 반쪽짜리 시트밖에 되지 않는다는 것에 힘이 쭉 빠졌지요. 그러나 스터디장이신 여행가 J님께서 "자동화 한번에 할려고 그러냐... 두번 하다보면 더 잘하게 된다"란 말씀을 주셔서... 틀린말이 하나도 없기에.... 대수롭지 않게 생각하고 다시 시작하게 됩니다.

진행 방법

그런데 문제는, 생성된 결과를 보니까, 이전 생성물은 꽤 마음에 들었는데, 이번에는 너무 말도 안되게 생성이 된거에요. 그래서 계속 더 섬세한 프롬프트를 주는 걸로 시도해서 좀 쓸만한 결과물이 나오도록 몇시간을 씨름하다가... 결국 새창을 열고 GPT에게 이전코드에 비해서 왜 이번코드의 결과물은 형편없는지를 불어봅니다. 그랬더니 대답은 잘 해주네요.

한국어 텍스트가 있는 검은 화면

그래서 좋은 코드가 있으면 그걸 잘 메모해두고, 유사한 다른 코딩을 할때 재활용하는 것이 중요하다는 것을 학습하게 되었습니다. 정말 생성형 AI는 알수록 사례공유가 중요하다는걸 알게되네요.

Tip: 코드 전문은 코드블록에 감싸서 작성해주세요. ( / 을 눌러 '코드 블록'을 선택)

예를들어, 결과물이 좋았던 코드는 아래와 같이 프롬프트가 매 열별로 되어 있고, 한글로 준 프롬프트는 모두 영문으로 되어 있었어요.

// GPT-4o 모델을 호출하여 네이버 블로그 글을 생성하는 함수
function callGPTForBlogPost(subject, keywords, brandName, tone) {
  const apiUrl = 'https://api.openai.com/v1/chat/completions';
  const payload = {
    model: "gpt-4o",
    messages: [
      {
        role: "system", 
        content: `You are a professional content creator and a coach specializing in self-development, coaching, and counseling. Please write a blog post in Korean using the following format:
        (1) Title optimized for SEO, including 3-5 hashtags.
        (2) Structure the content with headings (H2, H3), lists, and image captions.
        (3) Improve readability by breaking up paragraphs, using lists, and emphasizing important information.
        (4) Use the following brand name: ${brandName}.
        (5) The tone of the post should be friendly, like a coach sharing an experience.
        (6) Ensure the keywords are present: ${keywords}.
        (7) The subject is: ${subject}.`
      }
    ],
    max_tokens: 5000
  };

  const options = {
    method: 'post',
    contentType: 'application/json',
    headers: {
      Authorization: `Bearer ${OPENAI_API_KEY}`
    },
    payload: JSON.stringify(payload)
  };

  try {
    const response = UrlFetchApp.fetch(apiUrl, options);
    const json = JSON.parse(response.getContentText());
    const blogPost = json.choices[0].message.content.trim();
    return blogPost;
  } catch (error) {
    Logger.log('Error during API request: ' + error);
    return "블로그 글 작성 실패";
  }
}

// 사용자 정의 함수: =blog(F5)
function blog(cellText) {
  if (!cellText) {
    return "주제가 없습니다"; // 텍스트가 없을 경우
  }

  const subject = cellText;  // 주제
  const keywords = "믿음, 사랑, 스스로";  // 키워드
  const brandName = "Truth in Mind";  // 브랜드명
  const tone = "친절한 코치";  // 톤앤매너
  
  return callGPTForBlogPost(subject, keywords, brandName, tone); // GPT-4o로 블로그 글 생성
}

// GPT-4o 모델을 호출하여 Thread용 메시지를 생성하는 함수
function callGPTForThreads(text) {
  const apiUrl = 'https://api.openai.com/v1/chat/completions';
  const payload = {
    model: "gpt-4o",
    messages: [
      {
        role: "system", 
        content: "You are an expert in writing warm and insightful social media posts for Meta's Threads platform. Please create 10 powerful expressions that convey key messages and keywords from the provided text. Each message should be in Korean (informal tone) followed by an English translation."
      },
      {
        role: "user",
        content: `다음 텍스트에서 인사이트가 넘치고 따뜻한 표현으로 10개의 메시지를 만들어줘. 한글은 반말로 써주고, 한글 다음에 영어로 번역해줘: ${text}`
      }
    ],
    max_tokens: 1000  // 적절한 토큰 수 설정
  };

  const options = {
    method: 'post',
    contentType: 'application/json',
    headers: {
      Authorization: `Bearer ${OPENAI_API_KEY}`
    },
    payload: JSON.stringify(payload)
  };

  try {
    const response = UrlFetchApp.fetch(apiUrl, options);
    const json = JSON.parse(response.getContentText());
    const threadsPost = json.choices[0].message.content.trim();
    return threadsPost;
  } catch (error) {
    Logger.log('Error during API request: ' + error);
    return "Thread 글 작성 실패";
  }
}

// 사용자 정의 함수: =thread(E5)
function thread(cellText) {
  if (!cellText) {
    return "내용이 없습니다"; // 텍스트가 없을 경우
  }
  
  return callGPTForThreads(cellText); // GPT-4o로 Thread용 글 생성
}

// GPT-4o 모델을 호출하여 Brunch 글을 생성하는 함수
function callGPTForBrunchPost(text) {
  const apiUrl = 'https://api.openai.com/v1/chat/completions';
  const payload = {
    model: "gpt-4o",
    messages: [
      {
        role: "system", 
        content: `You are a coach who helps clients shift their fixed beliefs. Write a blog post that starts with a philosophical question, includes conversational dialogue, and emphasizes an emotional and persuasive approach to changing someone's perspective. The core message is that real love is believing in someone's potential, even without scientific or logical proof. The tone should help readers reflect on their own beliefs.`
      },
      {
        role: "user",
        content: `다음 텍스트를 바탕으로 코치가 내담자의 고정관념을 전환하는 글을 써줘: ${text}`
      }
    ],
    max_tokens: 5000  // 적절한 토큰 수 설정
  };

  const options = {
    method: 'post',
    contentType: 'application/json',
    headers: {
      Authorization: `Bearer ${OPENAI_API_KEY}`
    },
    payload: JSON.stringify(payload)
  };

  try {
    const response = UrlFetchApp.fetch(apiUrl, options);
    const json = JSON.parse(response.getContentText());
    const brunchPost = json.choices[0].message.content.trim();
    return brunchPost;
  } catch (error) {
    Logger.log('Error during API request: ' + error);
    return "Brunch 글 작성 실패";
  }
}

// 사용자 정의 함수: =brunch(E5)
function brunch(cellText) {
  if (!cellText) {
    return "내용이 없습니다"; // 텍스트가 없을 경우
  }

  return callGPTForBrunchPost(cellText); // GPT-4o로 Brunch 글 생성
}

// GPT-4o 모델을 호출하여 YouTube VOD 스크립트를 생성하는 함수
function callGPTForVOD(text) {
  const apiUrl = 'https://api.openai.com/v1/chat/completions';
  const payload = {
    model: "gpt-4o",
    messages: [
      {
        role: "system", 
        content: "You are a scriptwriter for YouTube VOD content. Please write a Korean script based on the following content. The script should include an introduction, key points, and a clear conclusion, suitable for a long-format VOD."
      },
      {
        role: "user",
        content: `다음 내용을 바탕으로 유튜브 VOD 스크립트를 작성해줘: ${text}`
      }
    ],
    max_tokens: 1500
  };

  const options = {
    method: 'post',
    contentType: 'application/json',
    headers: {
      Authorization: `Bearer ${OPENAI_API_KEY}`
    },
    payload: JSON.stringify(payload)
  };

  try {
    const response = UrlFetchApp.fetch(apiUrl, options);
    const json = JSON.parse(response.getContentText());
    const vodScript = json.choices[0].message.content.trim();
    return vodScript;
  } catch (error) {
    Logger.log('Error during API request: ' + error);
    return "VOD 스크립트 생성 실패";
  }
}

// 사용자 정의 함수: =vod(E5)
function vod(cellText) {
  if (!cellText) {
    return "내용이 없습니다"; 
  }
  return callGPTForVOD(cellText); 
}

// GPT-4o 모델을 호출하여 YouTube Shorts 스크립트를 생성하는 함수
function callGPTForShorts(text) {
  const apiUrl = 'https://api.openai.com/v1/chat/completions';
  const payload = {
    model: "gpt-4o",
    messages: [
      {
        role: "system", 
        content: "You are a scriptwriter for YouTube Shorts content. Write a concise, engaging, and fast-paced Korean script based on the following content, suitable for a short video format."
      },
      {
        role: "user",
        content: `다음 내용을 바탕으로 유튜브 Shorts 스크립트를 작성해줘: ${text}`
      }
    ],
    max_tokens: 500
  };

  const options = {
    method: 'post',
    contentType: 'application/json',
    headers: {
      Authorization: `Bearer ${OPENAI_API_KEY}`
    },
    payload: JSON.stringify(payload)
  };

  try {
    const response = UrlFetchApp.fetch(apiUrl, options);
    const json = JSON.parse(response.getContentText());
    const shortsScript = json.choices[0].message.content.trim();
    return shortsScript;
  } catch (error) {
    Logger.log('Error during API request: ' + error);
    return "Shorts 스크립트 생성 실패";
  }
}

// 사용자 정의 함수: =shorts(E5)
function shorts(cellText) {
  if (!cellText) {
    return "내용이 없습니다"; 
  }
  return callGPTForShorts(cellText); 
}

// GPT-4o 모델을 호출하여 명상을 위한 스크립트를 생성하는 함수
function callGPTForMeditation(text) {
  const apiUrl = 'https://api.openai.com/v1/chat/completions';
  const payload = {
    model: "gpt-4o",
    messages: [
      {
        role: "system", 
        content: "You are a meditation guide. Write a calming and relaxing Korean script for a meditation session based on the following content. The script should help the listener feel peaceful and grounded."
      },
      {
        role: "user",
        content: `다음 내용을 바탕으로 명상 스크립트를 작성해줘: ${text}`
      }
    ],
    max_tokens: 1000
  };

  const options = {
    method: 'post',
    contentType: 'application/json',
    headers: {
      Authorization: `Bearer ${OPENAI_API_KEY}`
    },
    payload: JSON.stringify(payload)
  };

  try {
    const response = UrlFetchApp.fetch(apiUrl, options);
    const json = JSON.parse(response.getContentText());
    const meditationScript = json.choices[0].message.content.trim();
    return meditationScript;
  } catch (error) {
    Logger.log('Error during API request: ' + error);
    return "명상 스크립트 생성 실패";
  }
}

// 사용자 정의 함수: =mdscript(E5)
function mdscript(cellText) {
  if (!cellText) {
    return "내용이 없습니다"; 
  }
  return callGPTForMeditation(cellText); 
}

// GPT-4o 모델을 호출하여 홈페이지용 글을 생성하는 함수
function callGPTForHomepage(text) {
  const apiUrl = 'https://api.openai.com/v1/chat/completions';
  const payload = {
    model: "gpt-4o",
    messages: [
      {
        role: "system", 
        content: "You are a content creator for a website. Please write a Korean article optimized for SEO based on the following content. The article should include a clear structure, calls to action, and customer testimonials. Make sure the content is highly readable and well-structured."
      },
      {
        role: "user",
        content: `다음 내용을 바탕으로 홈페이지에 게시할 SEO 최적화된 글을 작성해줘. Call to Action과 고객 후기를 포함해줘: ${text}`
      }
    ],
    max_tokens: 1500
  };

  const options = {
    method: 'post',
    contentType: 'application/json',
    headers: {
      Authorization: `Bearer ${OPENAI_API_KEY}`
    },
    payload: JSON.stringify(payload)
  };

  try {
    const response = UrlFetchApp.fetch(apiUrl, options);
    const json = JSON.parse(response.getContentText());
    const homepageContent = json.choices[0].message.content.trim();
    return homepageContent;
  } catch (error) {
    Logger.log('Error during API request: ' + error);
    return "홈페이지 글 작성 실패";
  }
}

// 사용자 정의 함수: =homepage(E5)
function homepage(cellText) {
  if (!cellText) {
    return "내용이 없습니다"; 
  }
  return callGPTForHomepage(cellText); 
}

// GPT-4o 모델을 호출하여 영어로 번역하는 함수
function callGPTForEnglishTranslation(text) {
  const apiUrl = 'https://api.openai.com/v1/chat/completions';
  const payload = {
    model: "gpt-4o",
    messages: [
      {
        role: "system", 
        content: "You are a professional translator. Please translate the following content into natural, fluent English."
      },
      {
        role: "user",
        content: `다음 내용을 영어로 번역해줘: ${text}`
      }
    ],
    max_tokens: 5000
  };

  const options = {
    method: 'post',
    contentType: 'application/json',
    headers: {
      Authorization: `Bearer ${OPENAI_API_KEY}`
    },
    payload: JSON.stringify(payload)
  };

  try {
    const response = UrlFetchApp.fetch(apiUrl, options);
    const json = JSON.parse(response.getContentText());
    const englishTranslation = json.choices[0].message.content.trim();
    return englishTranslation;
  } catch (error) {
    Logger.log('Error during API request: ' + error);
    return "영어 번역 실패";
  }
}

// 사용자 정의 함수: =inEng(F5)
function inEng(cellText) {
  if (!cellText) {
    return "내용이 없습니다"; 
  }
  return callGPTForEnglishTranslation(cellText); 
}

// GPT-4o 모델을 호출하여 동화책의 일부분을 생성하는 함수
function callGPTForFairytalePart(text, startPage, endPage) {
  const apiUrl = 'https://api.openai.com/v1/chat/completions';
  const payload = {
    model: "gpt-4o",
    messages: [
      {
        role: "system", 
        content: `You are writing a children's story for preschoolers. Each page has one sentence in English followed by one sentence in Korean. Write a vivid, engaging story about two friends helping each other. Please generate the story for pages ${startPage} to ${endPage}.`
      },
      {
        role: "user",
        content: `다음 내용을 바탕으로 ${startPage}에서 ${endPage}까지의 동화책 페이지를 작성해줘: ${text}`
      }
    ],
    max_tokens: 1000  // 2~3페이지 분량을 생성할 수 있는 충분한 토큰 설정
  };

  const options = {
    method: 'post',
    contentType: 'application/json',
    headers: {
      Authorization: `Bearer ${OPENAI_API_KEY}`
    },
    payload: JSON.stringify(payload)
  };

  try {
    const response = UrlFetchApp.fetch(apiUrl, options);
    const json = JSON.parse(response.getContentText());
    const fairytalePart = json.choices[0].message.content.trim();
    return fairytalePart;
  } catch (error) {
    Logger.log('Error during API request: ' + error);
    return `동화책 ${startPage}~${endPage} 페이지 작성 실패`;
  }
}

// 전체 동화책을 나누어서 생성하는 함수
function fairytale(cellText) {
  if (!cellText) {
    return "내용이 없습니다"; 
  }

  let fullStory = "";
  
  // 예: 1~3페이지, 4~6페이지, 7~9페이지 나누어서 생성
  fullStory += callGPTForFairytalePart(cellText, 1, 3) + "\n\n";
  fullStory += callGPTForFairytalePart(cellText, 4, 6) + "\n\n";
  fullStory += callGPTForFairytalePart(cellText, 7, 9) + "\n\n";

  return fullStory;  // 전체 동화책 반환
}


// GPT-4o 모델을 호출하여 미드저니 프롬프트를 생성하는 함수
function callGPTForFairytaleImagePrompts(text) {
  const apiUrl = 'https://api.openai.com/v1/chat/completions';
  const payload = {
    model: "gpt-4o",
    messages: [
      {
        role: "system", 
        content: "You are a prompt creator for Midjourney. Create image prompts for a warm, cute, and consistent storybook. Each page has a unique background image that matches the content. The image should be A4 portrait size."
      },
      {
        role: "user",
        content: `다음 내용을 바탕으로 각 페이지에 맞는 미드저니 프롬프트를 생성해줘. 각 프롬프트는 A4 세로 사이즈의 따뜻하고 귀여운 느낌이 있어야 해: ${text}`
      }
    ],
    max_tokens: 5000
  };

  const options = {
    method: 'post',
    contentType: 'application/json',
    headers: {
      Authorization: `Bearer ${OPENAI_API_KEY}`
    },
    payload: JSON.stringify(payload)
  };

  try {
    const response = UrlFetchApp.fetch(apiUrl, options);
    const json = JSON.parse(response.getContentText());
    const fairytaleImagePrompts = json.choices[0].message.content.trim();
    return fairytaleImagePrompts;
  } catch (error) {
    Logger.log('Error during API request: ' + error);
    return "미드저니 프롬프트 생성 실패";
  }
}

// 사용자 정의 함수: =fairytaleimage(S5)
function fairytaleimage(cellText) {
  if (!cellText) {
    return "내용이 없습니다"; 
  }
  return callGPTForFairytaleImagePrompts(cellText); 
}

결과물이 좋지 않았던 코드는 아래와 같이 내가 제시한 프롬프트가 매 열별로 되어 있지 않았고, 한글로 되어 있었어요.

 for (let row = 2; row <= lastRow; row++) {
    const isChecked = sheet.getRange(row, 1).getValue(); // A열 체크박스 값
    const text = sheet.getRange(row, 5).getValue(); // E열 대화 내용

    if (isChecked && text) { // 체크박스가 체크되고 E열에 내용이 있는 경우만 실행
      // 각 열의 내용 생성 및 입력
      sheet.getRange(row, 6).setValue(callGPTForStructuredSummary(text)); // F열 요약
      sheet.getRange(row, 7).setValue(callGPTForMainIssue(text)); // G열 주제 추출
      sheet.getRange(row, 8).setValue(callGPTForKeywords(text)); // H열 키워드 추출
      sheet.getRange(row, 9).setValue(callGPTForBlogPost(text, "믿음, 사랑, 스스로", "Truth in Mind", "친절한 코치")); // I열 블로그 글
      sheet.getRange(row, 10).setValue(callGPTForBrunchPost(text)); // J열 브런치 글
      sheet.getRange(row, 11).setValue(callGPTForThreads(text)); // K열 Thread 글
      sheet.getRange(row, 12).setValue(callGPTForHomepage(text)); // L열 홈페이지 글
      sheet.getRange(row, 13).setValue(callGPTForEnglishTranslation(sheet.getRange(row, 12).getValue())); // M열 영문 번역 (L열에서 번역)
      sheet.getRange(row, 14).setValue(callGPTForVOD(text)); // N열 유튜브 VOD 스크립트
      sheet.getRange(row, 15).setValue(callGPTForShorts(text)); // O열 유튜브 Shorts 스크립트
      sheet.getRange(row, 16).setValue(callGPTForMeditation(text)); // P열 명상 스크립트
      sheet.getRange(row, 17).setValue(fairytale(text)); // Q열 동화책 내용 (영어+한글 문장)
      sheet.getRange(row, 18).setValue(callGPTForFairytaleImagePrompt(text)); // R열 동화책 그림 프롬프트 (영어)
      sheet.getRange(row, 19).setValue(callGPTForBlogImagePrompt(text)); // S열 블로그 이미지 프롬프트 (영어)
      sheet.getRange(row, 20).setValue(callGPTForBrunchImagePrompt(text)); // T열 브런치 이미지 프롬프트 (영어)

      // 체크박스 해제
      sheet.getRange(row, 1).setValue(false);
    }
  }
}

// 텍스트를 요약하는 함수 (상황, 내담자의 고민, 코치의 제안으로 요약)
function callGPTForStructuredSummary(text) {
  return callOpenAI(text, `다음 코치와 내담자의 대화를 한글로 요약하고, (1) 상황 (2) 내담자의 고민 (3) 코치의 제안된 해결책 순서로 요약해줘:`);
}

// 주제를 추출하는 함수
function callGPTForMainIssue(text) {
  return callOpenAI(text, `다음 텍스트에서 주요 주제를 한글로 추출해줘:`);
}

// 키워드를 추출하는 함수 (최대 5개)
function callGPTForKeywords(text) {
  return callOpenAI(text, `다음 텍스트에서 최대 5개의 키워드를 한글로 추출해줘:`);
}

// 네이버 블로그 글을 생성하는 함수
function callGPTForBlogPost(subject, keywords, brandName, tone) {
  const prompt = `블로그 글을 작성해 주세요. 브랜드 이름은 "${brandName}"이고, 톤앤매너는 "${tone}"입니다. 주제는 "${subject}"이며, 키워드는 "${keywords}"입니다.`;
  return callOpenAI(subject, prompt);
}

// Brunch 글을 생성하는 함수
function callGPTForBrunchPost(text) {
  return callOpenAI(text, `다음 텍스트를 바탕으로 코치가 내담자의 고정관념을 전환하는 글을 써줘:`);
}

// Thread용 메시지를 생성하는 함수
function callGPTForThreads(text) {
  return callOpenAI(text, `다음 텍스트에서 인사이트가 넘치고 따뜻한 표현으로 10개의 메시지를 만들어줘. 한글은 반말로 써주고, 한글 다음에 영어로 번역해줘:`);
}

// 홈페이지 글을 생성하는 함수
function callGPTForHomepage(text) {
  return callOpenAI(text, `다음 내용을 바탕으로 홈페이지에 게시할 SEO 최적화된 글을 작성해줘. Call to Action과 고객 후기를 포함해줘:`);
}

// 영어로 번역하는 함수
function callGPTForEnglishTranslation(text) {
  return callOpenAI(text, `다음 내용을 영어로 번역해줘:`);
}

// YouTube VOD 스크립트를 생성하는 함수
function callGPTForVOD(text) {
  return callOpenAI(text, `다음 내용을 바탕으로 유튜브 VOD 스크립트를 작성해줘:`);
}

// YouTube Shorts 스크립트를 생성하는 함수
function callGPTForShorts(text) {
  return callOpenAI(text, `다음 내용을 바탕으로 유튜브 Shorts 스크립트를 작성해줘. 각 스크립트는 3초 안에 시청자가 문제 해결을 할 수 있다는 확신을 줄 수 있어야 합니다:`);
}

// 명상을 위한 스크립트를 생성하는 함수
function callGPTForMeditation(text) {
  return callOpenAI(text, `다음 내용을 바탕으로 상, 중, 하의 3단계 의식 수준에 따른 명상 스크립트를 작성해줘:`);
}

// 동화책의 내용을 생성하는 함수 (Q열: 한 페이지당 영어와 한글 문장 포함)
function fairytale(text) {
  return callOpenAI(text, `다음 내용을 바탕으로 미취학 아동을 위한 동화책을 작성해 주세요. 한 페이지당 한 문장의 영어 문장과 한 문장의 한글 문장으로 작성해 주세요. 코치와 내담자 관계는 친구의 고민을 해결해주는 친구 이야기로 만들어 주세요.`);
}

// 미드저니용 동화책 그림 프롬프트 생성 (R열, 영어로)
function callGPTForFairytaleImagePrompt(text) {
  return callOpenAI(text, `Based on the following story content, create a warm, cute, and consistent Midjourney prompt for a fairytale illustration. The image should be portrait A4 size: ${text}`);
}

// 미드저니용 블로그 이미지 프롬프트 생성 (S열, 영어로)
function callGPTForBlogImagePrompt(text) {
  return callOpenAI(text, `Based on the following blog content, create an English Midjourney prompt for a consistent, attractive blog image. Each prompt should capture the essence of the text. The first image should be a simple 600x600 thumbnail, three images at 886x590 for content sections, and one 1080x1080 image for a positive theme: ${text}`);
}

// 미드저니용 브런치 이미지 프롬프트 생성 (T열, 영어로)
function callGPTForBrunchImagePrompt(text) {
  return callOpenAI(text, `Based on the following Brunch blog content, create an English Midjourney prompt for three images at 1080x566 that maintain a warm, cohesive style. Each image should reflect the tone and message of the blog post: ${text}`);
}

// OpenAI API 호출 공통 함수
function callOpenAI(text, promptContent) {
  const apiUrl = 'https://api.openai.com/v1/chat/completions';
  const payload = {
    model: "gpt-4o",
    messages: [
      { role: "system", content: '당신은 다양한 형식의 콘텐츠를 한국어로 생성하는 어시스턴트입니다.' },
      { role: "user", content: `${promptContent} ${text}` }
    ],
    max_tokens: 1000,  // 적절한 토큰 수 설정
    temperature: 0.7   // 조금 더 창의적이지만 안정적인 결과를 위한 설정
  };

  const options = {
    method: 'post',
    contentType: 'application/json',
    headers: { Authorization: `Bearer ${OPENAI_API_KEY}` },
    payload: JSON.stringify(payload)
  };

  try {
    const response = UrlFetchApp.fetch(apiUrl, options);
    const json = JSON.parse(response.getContentText());
    return json.choices[0].message.content.trim();
  } catch (error) {
    Logger.log('Error during API request: ' + error);
    return "처리 실패";
  }
}

‎​(내용 입력)

결과와 배운 점

도움 주신 모든 분들께 감사합니다.😁

4
7개의 답글

👉 이 게시글도 읽어보세요