Skip to content

Instantly share code, notes, and snippets.

@Psyda
Last active December 31, 2023 11:12
Show Gist options
  • Save Psyda/50d3e01b4098a09d35cec5c3a604e7cc to your computer and use it in GitHub Desktop.
Save Psyda/50d3e01b4098a09d35cec5c3a604e7cc to your computer and use it in GitHub Desktop.
Starcraft Map GPT4 Korean Translator - Google Sheets AppScript
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.
// 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