Apps Script公式リファレンス: Apps Script Reference |障害・課題追跡: IssueTracker |Google Workspace: Status Dashboard - Summary

2024年5月31日金曜日

Gemini APIでsafetySettingsを指定したい - Adjust safetySettings in Gemini API


Gemini APIを利用しているときに以下のエラーが出て回答を得られないケースがありました。
I encountered the following error while using the Gemini API and was unable to obtain a response in some cases.

TypeError: Cannot read properties of undefined (reading 'parts') 


原因を探っていたところ、safetySettings が関係しているようでした。
While investigating the cause, I found that safetySettings seems to be related.


今回はGemini APIでsafetySettings の変更を試したコードです。
This time, I tried using code to change the safety settings in the Gemini API.


Safety settingsについての詳細は以下の公式ドキュメントを確認してください。
Please refer to the official documentation below for more details on Safety settings.

Safety settings



Google AI Studioで設定する場合
When setting up in Google AI Studio.


①create new prompt > Chat prompt > ②Safety settings > ③Run safety settings



Apps Script

GeminiのAPI keyはスクリプト プロパティにapiKeyとして保存しておきます。
Store the Gemini API key in a script property named 'apiKey'.
以下のコードはおそらくエラーを出します。
The following code will likely produce an error.


Code.gs
function runGeminiApi() {
const text = "examples of unsafe words";

const payload = {
"contents": [{
"parts":[{
"text": text
}]
}],
"safetySettings": [
{
"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
"threshold": "BLOCK_LOW_AND_ABOVE"
},
{
"category": "HARM_CATEGORY_HATE_SPEECH",
"threshold": "BLOCK_LOW_AND_ABOVE"
},
{
"category": "HARM_CATEGORY_HARASSMENT",
"threshold": "BLOCK_LOW_AND_ABOVE"
},
{
"category": "HARM_CATEGORY_DANGEROUS_CONTENT",
"threshold": "BLOCK_LOW_AND_ABOVE"
}
]
};

const options = {
"method": "POST",
"headers": {
"x-goog-api-key": getProp("apiKeyGemini"),
"Content-Type": "application/json"
},
"payload": JSON.stringify(payload)
};

const url = "https://generativelanguage.googleapis.com/v1/models/gemini-pro:generateContent";
const response = UrlFetchApp.fetch(url, options);
Logger.log(response);
const responseText= JSON.parse(response).candidates[0].content.parts[0].text;
return responseText;
}

function getProp(key) {
return PropertiesService.getScriptProperties().getProperty(key);
}


実行ログ - Execution log
16:13:39
お知らせ
実行開始
16:13:44
情報
{ "candidates": [ { "finishReason": "SAFETY", "index": 0, "safetyRatings": [ { "category": "HARM_CATEGORY_SEXUALLY_EXPLICIT", "probability": "MEDIUM" }, { "category": "HARM_CATEGORY_HATE_SPEECH", "probability": "NEGLIGIBLE" }, { "category": "HARM_CATEGORY_HARASSMENT", "probability": "LOW" }, { "category": "HARM_CATEGORY_DANGEROUS_CONTENT", "probability": "LOW" } ] } ], "usageMetadata": { "promptTokenCount": 4, "totalTokenCount": 4 } }
16:13:44
エラー
TypeError: Cannot read properties of undefined (reading 'parts')

probabilityにMEDIUMやLOWが含まれているため、以下の箇所で content.parts[0].text が存在せずエラーとなっています。
The error occurred because the "probability" field contained values like "MEDIUM" or "LOW," and the "content.parts[0].text" did not exist.

const responseText= JSON.parse(response).candidates[0].content.parts[0].text;


このエラーを回避するには、Code.gs内の "threshold": "BLOCK_LOW_AND_ABOVE" で、BLOCK_LOW_AND_ABOVE を BLOCK_ONLY_HIGH か BLOCK_NONE に変更します。
To avoid this error, change BLOCK_LOW_AND_ABOVE to BLOCK_ONLY_HIGH or BLOCK_NONE in Code.gs.


Tips


HarmBlockThreshold

https://ai.google.dev/api/rest/v1/SafetySetting#harmblockthreshold
HARM_BLOCK_THRESHOLD_UNSPECIFIED
BLOCK_LOW_AND_ABOVE
BLOCK_MEDIUM_AND_ABOVE
BLOCK_ONLY_HIGH
BLOCK_NONE


Reference

GeminiのAPIをApps Scriptで利用したい - Using Gemini API in Apps Script

Safety settings

HarmBlockThreshold

2024年5月30日木曜日

Shiftキーの有無で処理が変わるボタンを作りたい - Create buttons affected by the Shift key


Google Apps ScriptのHTML Serviceで、e.shiftKey のtrue / false を判定し、ボタンの処理を分岐する仕組みを作ったときに書いたコードです。
I tried code in Google Apps Script's HTML Service to check whether e.shiftKey is true or false and handle the button's actions accordingly.

Demo






下記のApps ScriptをデプロイしてWebアプリを起動すると、テキストエリアが横に2つ、左下にsubmitボタンが表示されます。
After launching the deployed web app, two text areas will be displayed side by side, with a submit button in the lower left corner.


左のinputテキストエリアに任意の英文を入力します。
Input any English text into the left text area.


submitボタンをクリックすると、その下に英文内の単語がボタンに分かれて表示されます。
After clicking the submit button, the words from the English text will be displayed as individual buttons below it.


単語のボタンをクリックすると、ボタンがハイライトされて右のテキストエリアにその単語が入力されます。
After clicking a word button, the button will be highlighted, and the word will be input into the right text area.


Shiftキーを押しながらボタンをクリックすると、その単語が右のテキストエリアに入力されます。
The words clicked while holding the Shift key will be input into the right text area.


Shiftキーを押さずに別の単語ボタンをクリックすると、ハイライトと右のテキストエリアがクリアされ、クリックした単語が入力されます
Clicking another word button without Shift clears the highlight and the right text area, then inputs the clicked word.



Apps Script

Code.gs
function doGet() {
return HtmlService.createTemplateFromFile('index')
.evaluate()
.setTitle("Title");
}

function include(filename) {
return HtmlService.createHtmlOutputFromFile(filename).getContent();
}


index.html
<!DOCTYPE html>
<html>
<head>
<?!= include("css"); ?>
</head>
<body>
<textarea id="input"></textarea>
<textarea id="result"></textarea>
<br>
<button id="submit">submit</button>
<br>
<div id="wordButtons"></div>
<?!= include("javascript"); ?>
</body>
</html>


css.html
<style>
textarea {
width: 30vw;
height: 20vh;
font-size: 20px;
}

.wordButtons {
font-size: 18px;
background-color: white;
border: solid 1px gray;
border-radius: 2px;
margin: 5px;
padding: 5px;
cursor: pointer;
}

.buttonHighlight {
background-color: aqua;
}
</style>


javascript.html
<script>
function elem(id) {
return document.getElementById(id);
}

elem("submit").onclick = createButtonsClicked;

function createButtonsClicked() {
const value = elem("input").value.trim();
const records = value.split("\n");
for(let i = 0; i < records.length; i++) {
const record = records[i].trim();
const words = record.split(" ");
createWordButtons(words);
}
}

function createWordButtons(words) {
const parent = elem("wordButtons");
const span = document.createElement("span");
const br = document.createElement("br");
for(let i = 0; i < words.length; i++) {
const word = words[i].match(/[a-zA-Z0-9'\s-]/g, "").join("");
const button = document.createElement("button");
button.textContent = word;
button.setAttribute("class", "wordButtons");
button.onclick = function(e){ wordButtonClicked(e, this)}
span.appendChild(button);
}
span.setAttribute("data-words", words.join(" "));
parent.appendChild(span);
parent.appendChild(br);
}

function wordButtonClicked(e, button) {
button.classList.add("buttonHighlight");
if(e.shiftKey) {
elem("result").value = elem("result").value + " " + button.textContent;
} else {
elem("result").value = button.textContent;
clearHighlight();
button.classList.add("buttonHighlight");
}
}

function clearHighlight() {
const parent = elem("wordButtons");
const buttons = parent.getElementsByTagName("button");
for(let i = 0; i < buttons.length; i++) {
buttons[i].classList.remove("buttonHighlight");
}
}
</script>



Reference

KeyboardEvent: shiftKey プロパティ

2024年5月29日水曜日

Google Slidesで表の枠線を設定したい - Set table borders in Google Slides


この記事で実行するコードは、以下のリンク先でも利用したGoogle Slides APIを追加する必要があります。
The code executed in this article requires the Google Slides API, which was also used in the link below.


今回は、Google Slidesで現在選択している表の枠線を操作するコードを試しました。
This time, I tried a script to manipulate the borders of the currently selected table in Google Slides.


今回の例では、選択した表の外側の枠線を4ptにします。
In this example, the outer border of the selected table is set to 4pt.



手動でやる場合、「枠線の色」「枠線の太さ」は上部メニューの下にあるアイコンから設定できます。
When doing it manually, you can set the 'border color' and 'border weight' from the icons located below the top menu.

枠線の範囲は表の右上の▼ボタンをクリックして表示される中から選択できます。
You can select the border range from the options that appear when you click the ▼ button located at the top right of the table.



実行手順 - Procedures


コードを実行する前に、3行3列の表を配置して選択しておきます。
Before running the code, place and select a 3-row, 3-column table on the slide.


Apps Script > エディタ > サービス > Google Slides API > 追加
Apps Script > Editor > Services > Google Slides API > Add


エディタに以下のCode.gsを書いて保存し、setTableBorders()を実行します。
Write the Code.gs below in the editor, save it, and then execute the setTableBorders() function.


選択した表の枠線が4ptになります。
The border of the selected table will be set to 4pt.



Code.gs
function setTableBorders() {
var presentation = SlidesApp.getActivePresentation();
var selection = presentation.getSelection();
var pageElement = selection.getPageElementRange().getPageElements()[0];
var table = pageElement.asTable();
var presentationId = presentation.getId();
var objectId = table.getObjectId();
var resource = {
"requests": [
{
"updateTableBorderProperties": {
"objectId": objectId,
"borderPosition": "OUTER",
"tableBorderProperties": {
"tableBorderFill": {
"solidFill": {
"color": {
"rgbColor": {
"red": 0,
"green": 0,
"blue": 0,
}
// "themeColor": "DARK1"// instead of rgbColor
},
"alpha": 1
}
},
"weight": {
"magnitude": 4,
"unit": "pt"
}
},
"fields": "tableBorderFill.solidFill.color,tableBorderFill.solidFill.alpha,weight"
}
}
]
}
Slides.Presentations.batchUpdate(resource, presentationId);
}


Reference

Is it possible to update table cell borders in Google Slides using Google App Script?

UpdateTableBorderPropertiesRequest

TableBorderProperties

TableBorderFill

SolidFill

OpaqueColor

RgbColor

ThemeColorType

BorderPosition

Google Slidesの表でセルを結合したい - merge cells in a table on Google Slides


Latest post

Google Apps Scriptの障害時はIssueTrackerを見てみる - Incidents for Apps Script are reported on Issue Tracker

IssueTracker > Apps Script issues https://issuetracker.google.com/savedsearches/566234 Google Apps Scriptの障害時は IssueTracker に課題が上がっていることが...