Last active
December 31, 2023 11:12
-
-
Save Psyda/50d3e01b4098a09d35cec5c3a604e7cc to your computer and use it in GitHub Desktop.
Starcraft Map GPT4 Korean Translator - Google Sheets AppScript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
How it works: https://i.imgur.com/LQCs8Y6.mp4 | |
Once Setup as a script for your current doc, use =StarcraftTranslator(Cellnumber of Korean string) | |
Requires GPT4 API Key. It uses a GPT Assistant which i made prior for you to use. Its fairly well understood of naming conventions like color codes and works to keep them logical. | |
Feel free to use your own Assistant, but here is mine: | |
Assistant ID: asst_2nsFaTZZ9nA8I86LpLPM4OX8 | |
Designed to be used with https://github.com/Tarferi/Starcraft-Translation-Tool | |
If you have any issues feel free to reach out. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Get the script properties | |
var scriptProperties = PropertiesService.getScriptProperties(); | |
// Retrieve the value for a specific property | |
const SECRET_KEY = scriptProperties.getProperty('SECRET_KEY'); | |
const assistantID = scriptProperties.getProperty('assistantID'); | |
//const inputPrompt = "<6>악마 <6>점프뒷차기!"; | |
function StarcraftTranslator(inputPrompt) { | |
if (!inputPrompt) { | |
//inputPrompt = "<6>악마 <6>점프뒷차기!"; | |
inputPrompt = "<6>악마 <6>점프뒷차기..."; | |
return "" // Return nothing for when a field is just empty to avoid sending to OpenAI. | |
console.log("No input prompt provided. Using default:", inputPrompt); | |
} | |
// Check if the input string contains Korean characters | |
const koreanCharacterRegex = /[\uAC00-\uD7AF]/; | |
if (!koreanCharacterRegex.test(inputPrompt)) { | |
// If no Korean characters are found, skip the GPT request | |
console.log("No Korean characters found in:", inputPrompt); | |
return inputPrompt; // or handle as needed | |
} | |
// Checking if Cached input in last 25 mins. | |
var cache = CacheService.getScriptCache(); | |
var cached = cache.get(inputPrompt); | |
if (cached != null) { | |
console.log(cached) | |
// Return the cached result if it's available | |
return cached; | |
} | |
const url = `https://api.openai.com/v1/threads/runs`; | |
const payload = { | |
assistant_id: assistantID, | |
thread: { | |
messages: [ | |
{ "role": "user", "content": inputPrompt } | |
] | |
} | |
}; | |
const options = { | |
method: "post", | |
contentType: "application/json", | |
headers: { | |
Authorization: "Bearer " + SECRET_KEY, | |
"OpenAI-Beta": "assistants=v1" | |
}, | |
payload: JSON.stringify(payload), | |
muteHttpExceptions: true | |
}; | |
try { | |
const response = UrlFetchApp.fetch(url, options); | |
const res = JSON.parse(response.getContentText()); | |
const threadID = res.thread_id; | |
const runID = res.id; | |
console.log(res) // Debugging | |
// Check for an error in the response | |
if (res.error) { | |
console.error("API Error:", res.error.message); // Log the error message | |
return "Error: " + res.error.message; // Return the error message to the caller | |
} | |
console.log("Thread ID:", threadID, "Run ID:", runID); | |
Utilities.sleep(1000); // Pause for a second | |
// Capture the translated text by returning the result from checkStatus | |
var result = checkStatus(threadID, runID); // This will now wait for and then return the result | |
console.log("Logging input " + result) | |
// Cache the result before returning | |
if (result !== "Error: Could not translate text") { // Make sure it's a valid result | |
console.log("Logging input " + result) | |
cache.put(inputPrompt, result, 12000); // Cache it for 25 minutes | |
} | |
return result; // Return the result here | |
} catch (error) { | |
console.error("Error contacting the API", error); | |
return "Error: Could not translate text"; // Handle error scenario | |
} | |
} | |
function checkStatus(threadID, runID) { | |
const statusUrl = `https://api.openai.com/v1/threads/${threadID}/runs/${runID}`; | |
const statusOptions = { | |
method: "get", | |
contentType: "application/json", | |
headers: { | |
Authorization: "Bearer " + SECRET_KEY, | |
"OpenAI-Beta": "assistants=v1" | |
}, | |
muteHttpExceptions: false | |
}; | |
let completed = false; | |
while (!completed) { | |
try { | |
const statusRes = UrlFetchApp.fetch(statusUrl, statusOptions); | |
const statusObj = JSON.parse(statusRes.getContentText()); | |
const apiStatus = statusObj.status; // This could be undefined if not present in response | |
console.log("Checking status:", apiStatus); | |
if (apiStatus === "completed") { | |
completed = true; | |
} else if (typeof apiStatus === "undefined" || apiStatus === "error") { | |
console.error("Error or undefined status encountered."); | |
break; // Exit the loop on undefined or error status | |
} | |
// Handle other statuses as needed | |
} catch (error) { | |
console.error("Error during status check:", error); | |
break; // Exit loop if there's an error in the try block | |
} | |
Utilities.sleep(1000); // Pause for a second | |
} | |
// After confirming completion | |
if (completed) { | |
// Define the URL for fetching messages from the thread | |
const messageUrl = `https://api.openai.com/v1/threads/${threadID}/messages`; | |
const messageOptions = { | |
method: "get", | |
contentType: "application/json", | |
headers: { | |
Authorization: "Bearer " + SECRET_KEY, | |
"OpenAI-Beta": "assistants=v1" | |
}, | |
muteHttpExceptions: false | |
}; | |
// Fetch the messages | |
const messageRes = UrlFetchApp.fetch(messageUrl, messageOptions); | |
const messages = JSON.parse(messageRes.getContentText()); | |
//console.log(messages.data[0].content) | |
// Navigating through the response to get the text value | |
if (messages && messages.data && messages.data.length > 0) { | |
const firstContent = messages.data[0].content; | |
if (firstContent && firstContent.length > 0 && firstContent[0].type === "text") { | |
const textValue = firstContent[0].text.value; | |
console.log(textValue); | |
//cache.put(inputPrompt, textValue, 1500); // Cache it for 25 minutes | |
return textValue; // Make sure to return the text value | |
} | |
} | |
} | |
// return "Translation incomplete or no content found."; // Handle scenario when translation isn't successful | |
} | |
//StarcraftTranslator("<6>악마 <6>점프뒷차기!"); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment