Skip to content

Commit 99bdbe5

Browse files
committed
Updated to v2.0.0
1 parent 2d95102 commit 99bdbe5

20 files changed

+2013
-560
lines changed
Lines changed: 289 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,289 @@
1+
const apiKey = "###"; // Please set your API key for using Gemini API.
2+
const agentCardUrls = [];
3+
4+
/**
5+
* This is a sample agent card.
6+
* You can see the specification of the agent card at the following official site.
7+
* Ref: https://google.github.io/A2A/specification/
8+
*/
9+
const getAgentCard_ = _ => (
10+
{
11+
"name": "Google Sheets Manager Agent",
12+
"description": [
13+
`Provide management for using Google Sheets.`,
14+
`- Get values from cells.`,
15+
`- Put values to cells.`,
16+
'- Put an image into a cell on Google Sheets.',
17+
].join("\n"),
18+
"provider": {
19+
"organization": "Tanaike",
20+
"url": "https://github.com/tanaikech"
21+
},
22+
"version": "1.0.0",
23+
"url": `${ScriptApp.getService().getUrl()}?accessKey=sample`,
24+
"defaultInputModes": ["text/plain"],
25+
"defaultOutputModes": ["text/plain"],
26+
"capabilities": {
27+
"streaming": false,
28+
"pushNotifications": false,
29+
"stateTransitionHistory": false,
30+
},
31+
"skills": [
32+
{
33+
"id": "get_values_from_cells",
34+
"name": "Get values from cells",
35+
"description": "From the given cell range, get values from cells on Google Sheets and return the values.",
36+
"tags": ["Google Sheets", "Google Spreadsheet", "range", "cells", "get"],
37+
"examples": [
38+
'Get a value from the active cell.',
39+
'What are the values of the active cell?',
40+
'Get a value from Google Sheets.',
41+
`Get values from Google Sheets. The condition is as follows. Spreadsheet ID is "123456789abcde". Sheet name is "Sheet1". Cell range is "A1:D5".`
42+
],
43+
"inputModes": ["text/plain"],
44+
"outputModes": ["text/plain"]
45+
},
46+
{
47+
"id": "put_values_to_cells",
48+
"name": "Put values to cells",
49+
"description": "By giving the values and the cell range, put the values to the cells on Google Sheets.",
50+
"tags": ["Google Sheets", "Google Spreadsheet", "range", "cells", "put"],
51+
"examples": [
52+
'Put a value to the active cell.',
53+
'Put values to Google Sheets.',
54+
`Put values to Google Sheets. The condition is as follows. Spreadsheet ID is "123456789abcde". Sheet name is "Sheet1". Cell range is "A1". Values are '[["a1", "b1"],["a2", "b2"],["a3", "b3"]]'.`
55+
],
56+
"inputModes": ["text/plain"],
57+
"outputModes": ["text/plain"]
58+
},
59+
{
60+
"id": "put_image_into_cell",
61+
"name": "Put image into cell",
62+
"description": "By giving the values and the cell range, put an image of Base64 data or an image URL into the cell on Google Sheets.",
63+
"tags": ["Google Sheets", "Google Spreadsheet", "range", "cells", "put", "image"],
64+
"examples": [
65+
'Put an image into the active cell.',
66+
'Put an image into Google Sheets.',
67+
`Put an image into Google Sheets. The condition is as follows. Spreadsheet ID is "123456789abcde". Sheet name is "Sheet1". Cell range is "A1". Image is retrieved from Google Drive.`,
68+
`Put an image into Google Sheets. The condition is as follows. Spreadsheet ID is "123456789abcde". Sheet name is "Sheet1". Cell range is "A1". Image URL is is "https://sampleURL.com/sample.png".`,
69+
],
70+
"inputModes": ["text/plain"],
71+
"outputModes": ["text/plain"]
72+
}
73+
]
74+
}
75+
);
76+
77+
/**
78+
* This is an object including sample functions. These functions are used for creating the response data to the A2A client.
79+
* You can see the specification of this object as follows.
80+
* Ref: https://github.com/tanaikech/GeminiWithFiles?tab=readme-ov-file#use-function-calling
81+
*
82+
* get_exchange_rate is from the Google's sample as follows.
83+
* Ref: https://github.com/google/A2A/blob/main/samples/python/agents/langgraph/agent.py#L19
84+
*/
85+
const getFunctionsA2A_ = _ => (
86+
{
87+
params_: {
88+
get_values_from_cells: {
89+
description: "Use this to get values from cells on Google Sheets.",
90+
parameters: {
91+
type: "object",
92+
properties: {
93+
spreadsheetId: {
94+
type: "string",
95+
description: `Spreadsheet ID.`
96+
},
97+
sheetName: {
98+
type: "string",
99+
description: `Sheet name.`
100+
},
101+
cellRange: {
102+
type: "string",
103+
description: `Cell range for getting values. This is required to be A1Notation like "A1", "A1:B5". The sheet name is not required to be included in the A1Notation.`
104+
}
105+
},
106+
required: ["spreadsheetId", "sheetName", "cellRange"]
107+
}
108+
},
109+
put_values_into_cells: {
110+
description: "Use this to put values into cells on Google Sheets.",
111+
parameters: {
112+
type: "object",
113+
properties: {
114+
spreadsheetId: {
115+
type: "string",
116+
description: `Spreadsheet ID.`
117+
},
118+
sheetName: {
119+
type: "string",
120+
description: `Sheet name.`
121+
},
122+
cellRange: {
123+
type: "string",
124+
description: `Cell range for getting values. This is required to be A1Notation like "A1", "A1:B5". The sheet name is not required to be included in the A1Notation.`
125+
},
126+
values: {
127+
type: "array",
128+
items: {
129+
type: "array",
130+
items: {
131+
type: "string",
132+
description: "Values for putting into cells. This is required to be 2-dimensional array."
133+
}
134+
}
135+
}
136+
},
137+
required: ["spreadsheetId", "sheetName", "cellRange", "values"]
138+
}
139+
},
140+
put_image_into_cell: {
141+
description: "Use this to put an image into a cell on Google Sheets.",
142+
parameters: {
143+
type: "object",
144+
properties: {
145+
spreadsheetId: {
146+
type: "string",
147+
description: `Spreadsheet ID.`
148+
},
149+
sheetName: {
150+
type: "string",
151+
description: `Sheet name.`
152+
},
153+
cellRange: {
154+
type: "string",
155+
description: `Cell range for getting values. This is required to be A1Notation like "A1", "A1:B5". The sheet name is not required to be included in the A1Notation.`
156+
},
157+
imageData: {
158+
type: "string",
159+
description: "Base64 data of the image data."
160+
},
161+
imageUrl: {
162+
type: "string",
163+
description: "Direct link of the image."
164+
},
165+
},
166+
required: ["spreadsheetId", "sheetName", "cellRange", "imageData", "imageUrl"]
167+
}
168+
}
169+
},
170+
171+
get_values_from_cells: (object) => {
172+
console.log("Run the function get_values_from_cells.");
173+
const { spreadsheetId, sheetName, cellRange } = object;
174+
let res;
175+
try {
176+
if (spreadsheetId && sheetName && cellRange) {
177+
const values = SpreadsheetApp.openById(spreadsheetId).getSheetByName(sheetName).getRange(cellRange).getDisplayValues();
178+
res = JSON.stringify(values);
179+
} else {
180+
const r = [{ spreadsheetId }, { sheetName }, { cellRange }].filter(e => Object.values(e)[0]);
181+
const rr = r.flatMap(e => Object.keys(e)).join(",");
182+
res = `There is no value of "${rr}".`;
183+
}
184+
} catch ({ stack }) {
185+
res = stack;
186+
}
187+
console.log(res); // Check response.
188+
return { result: res };
189+
// return { result: { type: "text", text: res, metadata: null } };
190+
},
191+
192+
put_values_into_cells: (object) => {
193+
console.log("Run the function put_values_to_cells.");
194+
const { spreadsheetId, sheetName, cellRange, values } = object;
195+
let res;
196+
try {
197+
if (spreadsheetId && sheetName && cellRange && values && Array.isArray(values) && Array.isArray(values[0])) {
198+
const range = SpreadsheetApp.openById(spreadsheetId).getSheetByName(sheetName).getRange(cellRange).offset(0, 0, values.length, values[0].length).setValues(values);
199+
res = `Values ${JSON.stringify(values)} were put into ${range.getA1Notation()} in ${sheetName} on Google Sheets ${spreadsheetId}.`;
200+
} else {
201+
const r = [{ spreadsheetId }, { sheetName }, { cellRange }, { values }].filter(e => Object.values(e)[0]);
202+
const rr = r.flatMap(e => Object.keys(e)).join(",");
203+
res = `There is no value of "${rr}".`;
204+
}
205+
} catch ({ stack }) {
206+
res = stack;
207+
}
208+
console.log(res); // Check response.
209+
return { result: res };
210+
// return { result: { type: "text", text: res, metadata: null } };
211+
},
212+
213+
put_image_into_cell: (object) => {
214+
console.log("Run the function put_values_to_cells.");
215+
const { spreadsheetId, sheetName, cellRange, imageData, imageUrl } = object;
216+
let res;
217+
try {
218+
if (spreadsheetId && sheetName && cellRange && (imageData || imageUrl)) {
219+
let data;
220+
if (imageData) {
221+
data = `data:${MimeType.PNG};base64,${Utilities.base64Encode(imageData)}`;
222+
} else if (imageUrl) {
223+
data = imageUrl;
224+
}
225+
if (data) {
226+
const value = SpreadsheetApp.newCellImage().setSourceUrl(data).build();
227+
const range = SpreadsheetApp.openById(spreadsheetId).getSheetByName(sheetName).getRange(cellRange).offset(0, 0, 1, 1).setValues([[value]]);
228+
res = `Image data was put into ${range.getA1Notation()} in ${sheetName} on Google Sheets ${spreadsheetId}.`;
229+
} else {
230+
res = "Image couldn't be put into the cell.";
231+
}
232+
} else {
233+
const r = [{ spreadsheetId }, { sheetName }, { cellRange }, { imageData }].filter(e => Object.values(e)[0]);
234+
const rr = r.flatMap(e => Object.keys(e)).join(",");
235+
res = `There is no value of "${rr}".`;
236+
}
237+
} catch ({ stack }) {
238+
res = stack;
239+
}
240+
console.log(res); // Check response.
241+
return { result: res };
242+
// return { result: { type: "text", text: res, metadata: null } };
243+
}
244+
}
245+
);
246+
247+
// doGet and doPost are used for connecting between the A2A server and the A2A client with the HTTP request.
248+
const doGet = (e) => main(e);
249+
const doPost = (e) => main(e);
250+
251+
function main(eventObject) {
252+
try {
253+
const object = {
254+
eventObject,
255+
agentCard: getAgentCard_,
256+
functions: getFunctionsA2A_,
257+
apiKey,
258+
agentCardUrls,
259+
};
260+
const res = new A2AApp({ accessKey: "sample" }).server(object);
261+
console.log(res.getContent()); // Check response.
262+
return res;
263+
} catch ({ stack }) {
264+
console.log(stack);
265+
return ContentService.createTextOutput(stack);
266+
}
267+
}
268+
269+
/**
270+
* This function is used for retrieving the URL of the Web Apps.
271+
* Please directly run this function and copy the URL from the log.
272+
*/
273+
function getServerURL() {
274+
const serverURL = `${ScriptApp.getService().getUrl()}?accessKey=sample`;
275+
console.log(serverURL);
276+
277+
278+
// The following comment line is used for automatically detecting the scope of "https://www.googleapis.com/auth/drive.readonly". This scope is used for accessing Web Apps. So, please don't remove the comment.
279+
// DriveApp.getFiles();
280+
}
281+
282+
/**
283+
* This function is used for retrieving the URL for registering the AgentCard to Python demo script.
284+
* Please directly run this function and copy the URL from the log.
285+
*/
286+
function getRegisteringAgentCardURL() {
287+
const registeringAgentCardURL = `${ScriptApp.getService().getUrl()}?access_token=${ScriptApp.getOAuthToken()}&accessKey=sample`;
288+
console.log(registeringAgentCardURL);
289+
}

0 commit comments

Comments
 (0)