Hi @nelson, I discover this thread while I was myself building a script in google sheet to connect from gSheet to OpenAI.
The basic objective was to:
- rewrite a column of description
- generate keywords
- assign a business function related to the description.
Since I don’t know anything about coding, my “trainee” was chatGpt 4. However, after hours of prompting, it does not deliver the proper results yet, even if we are very close.
I don’t know if this code can be useful to the community; in case of it is, find below the .gs and .html script (or access to all via the gSheet file attached. Note the added on menu “AyS Script”).
-------------------------- [.gs script]
// Load OpenAI API library
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu(‘ AyS Scripts’)
.addItem(‘Analyze Rows’, ‘showDialog’)
.addToUi();
}
function showDialog() {
var htmlOutput = HtmlService.createHtmlOutputFromFile(‘GptDialogDisplay’)
.setWidth(400)
.setHeight(300);
SpreadsheetApp.getUi().showModalDialog(htmlOutput, ‘Analyze Rows’);
}
function getColumnIndexByLetter(sheet, letter) {
var column = sheet.getRange(letter + “1”).getColumn();
return column;
}
function callOpenAiApi(promptTexts, openAiApiKey) {
var api_url = “https://api.openai.com/v1/engines/davinci/completions”;
var prompt_text = promptTexts.join(“\n\n”);
var data = {
“prompt”: prompt_text,
“max_tokens”: 1024,
“temperature”: 0.5,
“n”: promptTexts.length
};
var options = {
“method”: “post”,
“headers”: {
“Authorization”: "Bearer " + openAiApiKey,
“Content-Type”: “application/json”
},
“payload”: JSON.stringify(data)
};
return UrlFetchApp.fetch(api_url, options);
}
function prepareAnalysis(startRow, endRow) {
// Calculate the number of rows selected
var numRowsSelected = endRow - startRow + 1;
// Limit rows processed to a maximum of 20
var maxRows = 20;
if (numRowsSelected > maxRows) {
endRow = startRow + maxRows - 1;
numRowsSelected = maxRows;
}
// Update your API key in Project properties
var scriptProperties = PropertiesService.getScriptProperties();
var openAiApiKey = scriptProperties.getProperty(‘openai_api_key’);
return { numRowsSelected, openAiApiKey };
}
function fetchBatchResults(toolDescriptions, promptTemplate, numRowsSelected, openAiApiKey) {
var batchSize = 10;
var numBatches = Math.ceil(numRowsSelected / batchSize);
var allResults = ;
for (var batchIndex = 0; batchIndex < numBatches; batchIndex++) {
var startIndex = batchIndex * batchSize;
var endIndex = Math.min(startIndex + batchSize - 1, numRowsSelected - 1);
var batch = toolDescriptions.slice(startIndex, endIndex + 1);
var promptTexts = batch.map(function(description, index) {
return `AI Tool Description ${index + 1}: ${description[0]}\n`;
});
var prompt = promptTemplate.replace("{prompt_texts}", promptTexts.join(''));
var content = JSON.parse(callOpenAiApi([prompt], openAiApiKey).getContentText());
if (content.choices && content.choices.length > 0) {
var resultText = content.choices[0].text.trim();
var extractedDataArray = resultText.split("\n\n");
allResults.push(...extractedDataArray);
}
}
return allResults;
}
function processResults(sheet, allResults, startRow, htmlField1, htmlField2, htmlField3, rewrittenDescriptionColumnIndex, keywordsColumnIndex, criteria1ColumnIndex) {
allResults.forEach(function(extractedData, index) {
var rowIndex = startRow + index;
// Extract information
var extractedLines = extractedData.split("\n");
if (extractedLines.length >= 3) { // Add this check to ensure there are at least 3 lines
var rewrittenDescription = extractedLines[0].replace(new RegExp(`column ${htmlField1}: `), "");
var keywords = extractedLines[1].replace(new RegExp(`column ${htmlField2}: `), "").split(", ").join(", ");
var criteria1 = extractedLines[2].replace(new RegExp(`column ${htmlField3}: `), "");
// Set information in sheet with new column indexes
sheet.getRange(rowIndex, rewrittenDescriptionColumnIndex).setValue(rewrittenDescription);
sheet.getRange(rowIndex, keywordsColumnIndex).setValue(keywords);
sheet.getRange(rowIndex, criteria1ColumnIndex).setValue(criteria1);
} else {
Logger.log('Not enough information extracted for row: ' + rowIndex);
}
});
}
-------------------------------- [.html script]
Start row:
End row:
<!-- Indicate the destination columns -->
<label for="${htmlField1}">Rewritten Description column letter?:</label>
<input type="text" id="rewrittenDescriptionColumn" name="rewrittenDescriptionColumn" required><br><br>
<label for="${htmlField2}">Keywords column letter?</label>
<input type="text" id="keywordsColumn" name="keywordsColumn" required><br><br>
<label for="${htmlField3}">Criteria 1 column letter?</label>
<input type="text" id="criteria1Column" name="criteria1Column" required><br><br>
<div>
<button id="analyze" onclick="analyze()">Analyze Rows</button>
<button onclick="google.script.host.close()">Cancel</button>
</div>
<script>
function analyze() {
var startRow = document.getElementById('startRow').value;
var endRow = document.getElementById('endRow').value;
var rewrittenDescriptionColumn = document.getElementById('rewrittenDescriptionColumn').value;
var keywordsColumn = document.getElementById('keywordsColumn').value;
var criteria1Column = document.getElementById('criteria1Column').value;
if (startRow && endRow && startRow <= endRow && isValidColumn(keywordsColumn) && isValidColumn(criteria1Column) && isValidColumn(rewrittenDescriptionColumn)) {
google.script.run.analyzeRows(parseInt(startRow), parseInt(endRow), rewrittenDescriptionColumn, keywordsColumn, criteria1Column);
google.script.host.close();
} else {
alert('Please enter valid start-end rows or column letters');
}
}
function isValidColumn(column) {
return /^[A-Za-z]+$/.test(column);
}
</script>