구글 앱 스크립트 (Google Apps Script)
구글 앱 스크립트는 JavaScript 기반의 클라우드 스크립팅 언어로, 구글 워크스페이스 제품군(Google Sheets, Docs, Forms 등)을 자동화할 수 있는 도구입니다. 이를 통해 사용자는 다양한 작업을 자동화하고, 반복적인 작업을 쉽게 처리할 수 있습니다.
구글 앱 스크립트로 스프레드시트 자동화
구글 스프레드시트에서 반복적인 데이터 입력이나 복잡한 데이터 처리 작업은 시간이 많이 소요될 수 있습니다. 구글 앱 스크립트를 사용하면 이러한 작업을 자동화하여 생산성을 높일 수 있습니다.
예를 들어, 데이터를 자동으로 정리하거나 특정 조건에 따라 데이터를 필터링하는 스크립트를 작성할 수 있습니다.
구글 스프레드시트 자동화에 ChatGPT를 사용하면 더욱 유용할 것입니다. 그래서 앱 스크립트에 사용할 간단한 ChatGPT 연동 함수를 만들어봤습니다.
구글 앱 스크립트 & ChatGPT 연동 유틸 함수
function getOpenAIResponse(prompt) {
// 시스템 프롬프트 정의
const systemPrompt = `
여기에 시스템 프롬프트를 입력합니다.
`;
// 메시지 배열 생성
const message = [
{ role: "system", content: systemPrompt }, // 시스템 메시지
{ role: "user", content: prompt } // 사용자 프롬프트
];
// API 요청 URL 정의
const url = 'https://api.openai.com/v1/chat/completions';
// API 요청 옵션 설정
const options = {
'method': 'post', // HTTP 메서드
'contentType': 'application/json', // 콘텐츠 타입
'headers': {
'Authorization': `Bearer ${OPENAI_API_KEY}` // API 키 포함
},
'payload': JSON.stringify({
'model': 'gpt-4o-mini-2024-07-18', // 최신 모델 사용
'messages': message, // 메시지 배열 포함
'temperature': 0.7 // 온도 설정
})
};
// API 요청 보내기
const response = UrlFetchApp.fetch(url, options);
// 응답 JSON 파싱
const json = JSON.parse(response.getContentText());
// 응답에서 내용 추출 및 반환
if (json && json.choices && json.choices.length > 0) {
return json.choices[0]?.message?.content?.trim() || ""; // 첫 번째 선택지의 내용 반환
}
// 응답이 없을 경우 null 반환
return null;
}
위 코드는 앱 스크립트에서 사용할 GPT 통신 유틸 함수입니다. 위의 함수를 이용하여 ChatGPT를 통해 다양한 앱 스크립트 자동화를 구현할 수 있습니다.
예시
저는 다국어 번역이 되어 있는 스프레드시트에 위의 함수를 사용했습니다. 다국어는 여러 언어로 번역된 문장들이 있으며, 사람이 스프레드시트에 실수를 하여 내용을 잘못 입력하거나, 오역을 할 수 있습니다. 이러한 실수를 사람이 찾는 것은 인력 낭비이기 때문에, GPT를 이용하여 자동화를 할 수 있습니다.
예시코드
const col = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"];
const lang = ['Language code', 'Korean', 'US', 'English', 'Japanese', 'Vietnamese', 'Spanish', 'Deutsch', 'French', 'Portuguese', 'Chinese(Simplified)', 'Chinese(Traditional)'];
// 번역 체크 함수.
function checkTranslations() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
const data = sheet.getDataRange().getValues();
const koreanColumn = 1; // B열 (index 1)
for (let i = 1; i < data.length; i++) {
const koreanText = data[i][koreanColumn];
for (let j = 2; j < col.length; j++) { // C부터 L열까지
const translatedText = data[i][j];
const language = lang[j];
// OpenAI API 호출을 통해 번역 검토
const prompt = `The Korean sentence "${koreanText}" is translated to ${language} as "${translatedText}"`;
const correctedTranslation = getOpenAIResponse(prompt);
// 번역이 일치하지 않는 경우 콘솔에 표시
if (correctedTranslation && correctedTranslation.toUpperCase() !== "YES") {
console.log(`[정합성 확인 필요] - 위치: ${col[j]}${i + 1} | 내용: (${language}) - ${koreanText} / ${translatedText}`);
}
}
}
}
// 유틸 함수
function getOpenAIResponse(prompt) {
const systemPrompt = `
You will receive Korean sentences and other language sentences from users. You should check whether the translated sentence is empty or completely incorrect. Even if the translation is slightly different, if a similar meaning can be conveyed, it has been translated and should be judged as 'YES'. If it is judged to have been paraphrased, the answer is ‘YES’. If it is completely unrelated, the answer is 'NO'. You must only answer YES or NO.
`;
const message = [
{ role: "system", content: systemPrompt },
{ role: "assistant", content: `The Korean sentence "내용을 확인하려면 앱 잠금을 해제하세요" is translated to English as "Please check your file extension."` },
{ role: "assistant", content: "NO"},
{ role: "assistant", content: `The Korean sentence "내용을 확인하려면 앱 잠금을 해제하세요" is translated to English as "Unlock your app to view message".` },
{ role: "assistant", content: "YES"},
{ role: "assistant", content: `The Korean sentence "내용을 확인하려면 앱 잠금을 해제하세요" is translated to English as "".` },
{ role: "assistant", content: "NO"},
{ role: "assistant", content: `The Korean sentence "내용을 확인하려면 앱 잠금을 해제하세요" is translated to English as "내용을 확인하려면 앱 잠금을 해제하세요".` },
{ role: "assistant", content: "NO"},
{ role: "user", content: prompt }
];
const url = 'https://api.openai.com/v1/chat/completions';
const options = {
'method': 'post',
'contentType': 'application/json',
'headers': {
'Authorization': `Bearer ${OPENAI_API_KEY}`
},
'payload': JSON.stringify({
'model': 'gpt-4o-mini-2024-07-18', // 최신 모델 사용
'messages': message,
'temperature': 0.7
})
};
const response = UrlFetchApp.fetch(url, options);
const json = JSON.parse(response.getContentText());
if (json && json.choices && json.choices.length > 0) {
return json.choices[0]?.message?.content?.trim() || "";
}
return null;
}
위 코드는 한국어와 번역된 다른 언어를 GPT에게 보여주고, 번역이 제대로 이루어졌는지 검사하는 코드입니다. GPT가 어떻게 판단해야 하는지 시스템 프롬프트와 예시를 제공하여 ‘*퓨샷 러닝’을 했습니다. 위의 코드를 통해 GPT가 스프레드시트의 빈 셀이나 *언어 언매치, 오역, 의역들을 잡아낼 수 있습니다.
(*언어 언매치: 프랑스어로 번역되어 들어가야 하는 셀에 한국어나 영어 등 다른 언어가 들어가 있는 경우)
(*퓨샷 러닝(Few-shot Learning): AI에게 매우 적은 수의 학습 데이터(샘플)만을 가지고도 원하는 답변을 이끌어 내는 기술 [참고])
최적화에 대한 고찰
위의 코드는 솔직히 최적화된 코드가 아닙니다. 셀 하나씩 GPT에게 비교하도록 요청하면 많은 토큰이 소비될 것입니다.
이를 방지하기 위해 빈 셀이나 언어 언매치 같은 경우는 GPT 없이 정규식을 이용하여 자동화 할 수 있습니다.
그리고 셀 하나씩 비교하지 않고, 한 row 단위로 정합성 검사를 요청하면 좀 더 토큰 낭비를 줄일 수 있습니다.
위의 예시는 GPT를 이용한 개발 예시로 봐주시면 좋을 것 같습니다.
끝!
'개발 아카이브 > Javascript' 카테고리의 다른 글
JavaScript에서 export { }와 export default의 차이점 (0) | 2024.05.15 |
---|---|
Shadow DOM - DOM을 캡슐화 하자! (0) | 2023.05.14 |
[자바스크립트] String에 대해 알아보자. (0) | 2023.02.12 |
자바스크립트 객체 관리와 V8엔진 히든클래스 (0) | 2022.06.16 |
자바스크립트 맵 객체 (Javascript Map Object) (0) | 2022.06.15 |