@mcpher/gas-fakes 2.3.14 → 2.3.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/README.md +11 -5
  2. package/gf_agent/README.md +101 -0
  3. package/gf_agent/SKILL.md +397 -0
  4. package/gf_agent/documentation.md +105 -0
  5. package/gf_agent/gf-agent-contributor/SKILL.md +56 -0
  6. package/gf_agent/index.md +21 -0
  7. package/gf_agent/knowledge/00-execution-context.md +4 -0
  8. package/gf_agent/knowledge/01-drive.md +12 -0
  9. package/gf_agent/knowledge/02-syntax.md +13 -0
  10. package/gf_agent/knowledge/03-auth.md +15 -0
  11. package/gf_agent/knowledge/04-advanced.md +24 -0
  12. package/gf_agent/knowledge/05-sheets-forms.md +25 -0
  13. package/gf_agent/knowledge/06-jdbc-cloudsql.md +21 -0
  14. package/gf_agent/knowledge/07-jdbc-auth-details.md +30 -0
  15. package/gf_agent/knowledge/08-docs-limitations.md +4 -0
  16. package/gf_agent/knowledge/09-orchestrator-pattern.md +54 -0
  17. package/gf_agent/knowledge/10-sandbox-security.md +62 -0
  18. package/gf_agent/knowledge/11-chart-builder-limitations.md +15 -0
  19. package/gf_agent/knowledge/12-gmail-eventual-consistency.md +13 -0
  20. package/gf_agent/knowledge/README.md +16 -0
  21. package/gf_agent/scripts/SKILL.template.md +65 -0
  22. package/gf_agent/skills/base.md +156 -0
  23. package/gf_agent/skills/cache.md +20 -0
  24. package/gf_agent/skills/calendar.md +780 -0
  25. package/gf_agent/skills/charts.md +127 -0
  26. package/gf_agent/skills/document.md +6752 -0
  27. package/gf_agent/skills/drive.md +423 -0
  28. package/gf_agent/skills/forms.md +4036 -0
  29. package/gf_agent/skills/gmail.md +576 -0
  30. package/gf_agent/skills/jdbc.md +3101 -0
  31. package/gf_agent/skills/lock.md +20 -0
  32. package/gf_agent/skills/properties.md +19 -0
  33. package/gf_agent/skills/script.md +50 -0
  34. package/gf_agent/skills/slides.md +5054 -0
  35. package/gf_agent/skills/spreadsheet.md +56075 -0
  36. package/gf_agent/skills/urlfetch.md +28 -0
  37. package/gf_agent/skills/utilities.md +33 -0
  38. package/gf_agent/skills/xml.md +270 -0
  39. package/package.json +1 -1
  40. package/src/cli/mcp.js +82 -67
  41. package/src/services/advgmail/fakeadvgmailmessages.js +85 -3
  42. package/src/services/documentapp/fakecontainerelement.js +88 -0
  43. package/src/services/driveapp/fakedrivemeta.js +1 -1
  44. package/src/services/gmailapp/fakegmailapp.js +217 -1
  45. package/src/services/gmailapp/fakegmailattachment.js +5 -0
  46. package/src/services/gmailapp/fakegmaildraft.js +32 -4
  47. package/src/services/gmailapp/fakegmaillabel.js +45 -0
  48. package/src/services/gmailapp/fakegmailmessage.js +212 -9
  49. package/src/services/gmailapp/fakegmailthread.js +151 -1
  50. package/src/services/slidesapp/fakecolorscheme.js +29 -10
  51. package/src/services/slidesapp/fakepresentation.js +0 -8
  52. package/src/services/spreadsheetapp/fakeembeddedchartbuilder.js +113 -28
  53. package/src/services/spreadsheetapp/fakespreadsheetapp.js +15 -1
  54. package/src/support/sxgmail.js +22 -2
  55. package/src/support/sxjdbc.js +16 -3
  56. package/src/support/utils.js +2 -2
  57. package/docs_discovery.json +0 -4939
  58. package/drive_tools.js +0 -20
@@ -0,0 +1,28 @@
1
+ # Service: urlfetch
2
+
3
+ ## Class: HTTPResponse
4
+
5
+ Supported Methods:
6
+ - `getAllHeaders()`
7
+ - `getAs(String)`
8
+ - `getBlob()`
9
+ - `getContent()`
10
+ - `getContentText()`
11
+ - `getContentText(String)`
12
+ - `getHeaders()`
13
+ - `getResponseCode()`
14
+ - `fetch(String,Object)`
15
+ - `fetch(String)`
16
+ - `fetchAll(Object)`
17
+ - `getRequest(String,Object)`
18
+ - `getRequest(String)`
19
+
20
+ ## Class: UrlFetchApp
21
+
22
+ Supported Methods:
23
+ - `fetch(String,Object)`
24
+ - `fetch(String)`
25
+ - `fetchAll(Object)`
26
+ - `getRequest(String,Object)`
27
+ - `getRequest(String)`
28
+
@@ -0,0 +1,33 @@
1
+ # Service: utilities
2
+
3
+ ## Class: Utilities
4
+
5
+ Supported Methods:
6
+ - `base64Decode(String,Charset)`
7
+ - `base64Decode(String)`
8
+ - `base64DecodeWebSafe(String,Charset)`
9
+ - `base64DecodeWebSafe(String)`
10
+ - `base64Encode(Byte)`
11
+ - `base64Encode(String,Charset)`
12
+ - `base64Encode(String)`
13
+ - `base64EncodeWebSafe(Byte)`
14
+ - `base64EncodeWebSafe(String,Charset)`
15
+ - `base64EncodeWebSafe(String)`
16
+ - `computeHmacSha256Signature(Byte,Byte)`
17
+ - `computeHmacSha256Signature(String,String,Charset)`
18
+ - `computeHmacSha256Signature(String,String)`
19
+ - `getUuid()`
20
+ - `gzip(BlobSource,String)`
21
+ - `gzip(BlobSource)`
22
+ - `newBlob(Byte,String,String)`
23
+ - `newBlob(Byte,String)`
24
+ - `newBlob(Byte)`
25
+ - `newBlob(String,String,String)`
26
+ - `newBlob(String,String)`
27
+ - `newBlob(String)`
28
+ - `sleep(Integer)`
29
+ - `ungzip(BlobSource)`
30
+ - `unzip(BlobSource)`
31
+ - `zip(BlobSource,String)`
32
+ - `zip(BlobSource)`
33
+
@@ -0,0 +1,270 @@
1
+ # Service: xml
2
+
3
+ ## Class: Attribute
4
+
5
+ Supported Methods:
6
+ - `getName()`
7
+ - `getNamespace()`
8
+ - `getRootElement()`
9
+ - `getAttribute(String,Namespace)`
10
+ - `getAttribute(String)`
11
+ - `getChild(String,Namespace)`
12
+ - `getChild(String)`
13
+ - `getChildren()`
14
+ - `getChildren(String,Namespace)`
15
+ - `getChildren(String)`
16
+ - `getChildText(String,Namespace)`
17
+ - `getChildText(String)`
18
+ - `getName()`
19
+ - `getNamespace()`
20
+ - `getNamespace(String)`
21
+ - `getQualifiedName()`
22
+ - `getText()`
23
+ - `getValue()`
24
+ - `getName()`
25
+ - `format(Document)`
26
+ - `format(Element)`
27
+ - `getPrefix()`
28
+ - `getURI()`
29
+ - `getText()`
30
+ - `getValue()`
31
+ - `getNamespace(String,String)`
32
+ - `getNamespace(String)`
33
+ - `getPrettyFormat()`
34
+ - `getRawFormat()`
35
+ - `parse(String)`
36
+
37
+ ## Class: Cdata
38
+
39
+ Supported Methods:
40
+ - `getRootElement()`
41
+ - `getAttribute(String,Namespace)`
42
+ - `getAttribute(String)`
43
+ - `getChild(String,Namespace)`
44
+ - `getChild(String)`
45
+ - `getChildren()`
46
+ - `getChildren(String,Namespace)`
47
+ - `getChildren(String)`
48
+ - `getChildText(String,Namespace)`
49
+ - `getChildText(String)`
50
+ - `getName()`
51
+ - `getNamespace()`
52
+ - `getNamespace(String)`
53
+ - `getQualifiedName()`
54
+ - `getText()`
55
+ - `getValue()`
56
+ - `getName()`
57
+ - `format(Document)`
58
+ - `format(Element)`
59
+ - `getPrefix()`
60
+ - `getURI()`
61
+ - `getText()`
62
+ - `getValue()`
63
+ - `getNamespace(String,String)`
64
+ - `getNamespace(String)`
65
+ - `getPrettyFormat()`
66
+ - `getRawFormat()`
67
+ - `parse(String)`
68
+
69
+ ## Class: Comment
70
+
71
+ Supported Methods:
72
+ - `getRootElement()`
73
+ - `getAttribute(String,Namespace)`
74
+ - `getAttribute(String)`
75
+ - `getChild(String,Namespace)`
76
+ - `getChild(String)`
77
+ - `getChildren()`
78
+ - `getChildren(String,Namespace)`
79
+ - `getChildren(String)`
80
+ - `getChildText(String,Namespace)`
81
+ - `getChildText(String)`
82
+ - `getName()`
83
+ - `getNamespace()`
84
+ - `getNamespace(String)`
85
+ - `getQualifiedName()`
86
+ - `getText()`
87
+ - `getValue()`
88
+ - `getName()`
89
+ - `format(Document)`
90
+ - `format(Element)`
91
+ - `getPrefix()`
92
+ - `getURI()`
93
+ - `getText()`
94
+ - `getValue()`
95
+ - `getNamespace(String,String)`
96
+ - `getNamespace(String)`
97
+ - `getPrettyFormat()`
98
+ - `getRawFormat()`
99
+ - `parse(String)`
100
+
101
+ ## Class: DocType
102
+
103
+ Supported Methods:
104
+ - `getRootElement()`
105
+ - `getAttribute(String,Namespace)`
106
+ - `getAttribute(String)`
107
+ - `getChild(String,Namespace)`
108
+ - `getChild(String)`
109
+ - `getChildren()`
110
+ - `getChildren(String,Namespace)`
111
+ - `getChildren(String)`
112
+ - `getChildText(String,Namespace)`
113
+ - `getChildText(String)`
114
+ - `getName()`
115
+ - `getNamespace()`
116
+ - `getNamespace(String)`
117
+ - `getQualifiedName()`
118
+ - `getText()`
119
+ - `getValue()`
120
+ - `getName()`
121
+ - `format(Document)`
122
+ - `format(Element)`
123
+ - `getPrefix()`
124
+ - `getURI()`
125
+ - `getText()`
126
+ - `getValue()`
127
+ - `getNamespace(String,String)`
128
+ - `getNamespace(String)`
129
+ - `getPrettyFormat()`
130
+ - `getRawFormat()`
131
+ - `parse(String)`
132
+
133
+ ## Class: Document
134
+
135
+ Supported Methods:
136
+ - `getRootElement()`
137
+ - `getAttribute(String,Namespace)`
138
+ - `getAttribute(String)`
139
+ - `getChild(String,Namespace)`
140
+ - `getChild(String)`
141
+ - `getChildren()`
142
+ - `getChildren(String,Namespace)`
143
+ - `getChildren(String)`
144
+ - `getChildText(String,Namespace)`
145
+ - `getChildText(String)`
146
+ - `getName()`
147
+ - `getNamespace()`
148
+ - `getNamespace(String)`
149
+ - `getQualifiedName()`
150
+ - `getText()`
151
+ - `getValue()`
152
+ - `getName()`
153
+ - `format(Document)`
154
+ - `format(Element)`
155
+ - `getPrefix()`
156
+ - `getURI()`
157
+ - `getText()`
158
+ - `getValue()`
159
+ - `getNamespace(String,String)`
160
+ - `getNamespace(String)`
161
+ - `getPrettyFormat()`
162
+ - `getRawFormat()`
163
+ - `parse(String)`
164
+
165
+ ## Class: Element
166
+
167
+ Supported Methods:
168
+ - `getAttribute(String,Namespace)`
169
+ - `getAttribute(String)`
170
+ - `getChild(String,Namespace)`
171
+ - `getChild(String)`
172
+ - `getChildren()`
173
+ - `getChildren(String,Namespace)`
174
+ - `getChildren(String)`
175
+ - `getChildText(String,Namespace)`
176
+ - `getChildText(String)`
177
+ - `getName()`
178
+ - `getNamespace()`
179
+ - `getNamespace(String)`
180
+ - `getQualifiedName()`
181
+ - `getText()`
182
+ - `getValue()`
183
+ - `getName()`
184
+ - `format(Document)`
185
+ - `format(Element)`
186
+ - `getPrefix()`
187
+ - `getURI()`
188
+ - `getText()`
189
+ - `getValue()`
190
+ - `getNamespace(String,String)`
191
+ - `getNamespace(String)`
192
+ - `getPrettyFormat()`
193
+ - `getRawFormat()`
194
+ - `parse(String)`
195
+
196
+ ## Class: EntityRef
197
+
198
+ Supported Methods:
199
+ - `getName()`
200
+ - `format(Document)`
201
+ - `format(Element)`
202
+ - `getPrefix()`
203
+ - `getURI()`
204
+ - `getText()`
205
+ - `getValue()`
206
+ - `getNamespace(String,String)`
207
+ - `getNamespace(String)`
208
+ - `getPrettyFormat()`
209
+ - `getRawFormat()`
210
+ - `parse(String)`
211
+
212
+ ## Class: Format
213
+
214
+ Supported Methods:
215
+ - `format(Document)`
216
+ - `format(Element)`
217
+ - `getPrefix()`
218
+ - `getURI()`
219
+ - `getText()`
220
+ - `getValue()`
221
+ - `getNamespace(String,String)`
222
+ - `getNamespace(String)`
223
+ - `getPrettyFormat()`
224
+ - `getRawFormat()`
225
+ - `parse(String)`
226
+
227
+ ## Class: Namespace
228
+
229
+ Supported Methods:
230
+ - `getPrefix()`
231
+ - `getURI()`
232
+ - `getText()`
233
+ - `getValue()`
234
+ - `getNamespace(String,String)`
235
+ - `getNamespace(String)`
236
+ - `getPrettyFormat()`
237
+ - `getRawFormat()`
238
+ - `parse(String)`
239
+
240
+ ## Class: ProcessingInstruction
241
+
242
+ Supported Methods:
243
+ - `getText()`
244
+ - `getValue()`
245
+ - `getNamespace(String,String)`
246
+ - `getNamespace(String)`
247
+ - `getPrettyFormat()`
248
+ - `getRawFormat()`
249
+ - `parse(String)`
250
+
251
+ ## Class: Text
252
+
253
+ Supported Methods:
254
+ - `getText()`
255
+ - `getValue()`
256
+ - `getNamespace(String,String)`
257
+ - `getNamespace(String)`
258
+ - `getPrettyFormat()`
259
+ - `getRawFormat()`
260
+ - `parse(String)`
261
+
262
+ ## Class: XmlService
263
+
264
+ Supported Methods:
265
+ - `getNamespace(String,String)`
266
+ - `getNamespace(String)`
267
+ - `getPrettyFormat()`
268
+ - `getRawFormat()`
269
+ - `parse(String)`
270
+
package/package.json CHANGED
@@ -40,7 +40,7 @@
40
40
  },
41
41
  "name": "@mcpher/gas-fakes",
42
42
  "author": "bruce mcpherson",
43
- "version": "2.3.14",
43
+ "version": "2.3.16",
44
44
  "license": "MIT",
45
45
  "main": "main.js",
46
46
  "description": "An implementation of the Google Workspace Apps Script runtime: Run native App Script Code on Node and Cloud Run",
package/src/cli/mcp.js CHANGED
@@ -2,8 +2,15 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
3
  import { z } from "zod";
4
4
  import { spawn } from "child_process";
5
+ import fs from "fs";
6
+ import os from "os";
7
+ import path from "path";
8
+ import { fileURLToPath } from "url";
5
9
  import { MCP_VERSION } from "./utils.js";
6
10
 
11
+ const __filename = fileURLToPath(import.meta.url);
12
+ const __dirname = path.dirname(__filename);
13
+
7
14
  /**
8
15
  * Executes a GAS script using the gas-fakes CLI logic.
9
16
  */
@@ -37,57 +44,11 @@ async function runGasFakes(script) {
37
44
  });
38
45
  }
39
46
 
40
- const SERVICES = [
41
- {
42
- name: "spreadsheet_service",
43
- description: "Automate Google Sheets: Create, read, and modify spreadsheets, ranges, and formatting.",
44
- example: "const ss = SpreadsheetApp.create('Test'); ss.getActiveSheet().getRange('A1').setValue('Hello');"
45
- },
46
- {
47
- name: "document_service",
48
- description: "Automate Google Docs: Create and edit documents, paragraphs, tables, and styles.",
49
- example: "const doc = DocumentApp.create('Hello'); doc.getBody().appendParagraph('World');"
50
- },
51
- {
52
- name: "drive_service",
53
- description: "Manage Google Drive: Search files, create folders, and handle permissions.",
54
- example: "const files = DriveApp.getFilesByName('Test'); while(files.hasNext()) console.log(files.next().getName());"
55
- },
56
- {
57
- name: "gmail_service",
58
- description: "Automate Gmail: Send emails, search threads, and manage labels.",
59
- example: "GmailApp.sendEmail('test@example.com', 'Subject', 'Body');"
60
- },
61
- {
62
- name: "calendar_service",
63
- description: "Manage Google Calendar: Create events, list calendars, and handle invitations.",
64
- example: "CalendarApp.getDefaultCalendar().createEvent('Meeting', new Date(), new Date());"
65
- },
66
- {
67
- name: "slides_service",
68
- description: "Automate Google Slides: Create and edit presentations, slides, and shapes.",
69
- example: "const deck = SlidesApp.create('Presentation'); deck.appendSlide().insertShape(SlidesApp.ShapeType.RECTANGLE);"
70
- },
71
- {
72
- name: "forms_service",
73
- description: "Automate Google Forms: Create forms, add items, and manage responses.",
74
- example: "const form = FormApp.create('Survey'); form.addTextItem().setTitle('Name');"
75
- },
76
- {
77
- name: "jdbc_service",
78
- description: "Connect to databases via JDBC: Execute SQL queries and manage connections.",
79
- example: "const conn = Jdbc.getConnection(url, user, pass); const stmt = conn.createStatement();"
80
- },
81
- {
82
- name: "utilities_service",
83
- description: "General utilities: Formatting, parsing, and base64 encoding/decoding.",
84
- example: "const base64 = Utilities.base64Encode('hello');"
85
- },
86
- {
87
- name: "urlfetch_service",
88
- description: "HTTP Requests: Fetch external resources and APIs via GET/POST.",
89
- example: "const res = UrlFetchApp.fetch('https://api.example.com'); console.log(res.getContentText());"
90
- }
47
+ // Available services mapping for the documentation lookup
48
+ const AVAILABLE_SERVICES = [
49
+ "base", "cache", "calendar", "charts", "document", "drive",
50
+ "forms", "gmail", "jdbc", "lock", "properties", "script",
51
+ "slides", "spreadsheet", "urlfetch", "utilities", "xml"
91
52
  ];
92
53
 
93
54
  export async function startMcpServer() {
@@ -96,27 +57,81 @@ export async function startMcpServer() {
96
57
  version: MCP_VERSION,
97
58
  });
98
59
 
99
- // Register a tool for each high-level service
100
- for (const service of SERVICES) {
101
- server.registerTool(
102
- service.name,
103
- {
104
- description: `${service.description}\nExample script:\n${service.example}`,
105
- inputSchema: {
106
- script: z.string().describe("The Google Apps Script code to execute locally."),
107
- },
60
+ // Documentation lookup tool
61
+ server.registerTool(
62
+ "lookup_docs",
63
+ {
64
+ description: "Lookup the available Google Apps Script classes and methods supported by gas-fakes for a specific service. You MUST use this tool to read the documentation before writing a script to ensure the methods you plan to use are actually implemented.",
65
+ inputSchema: {
66
+ service: z.enum(AVAILABLE_SERVICES).describe("The Google Apps Script service to look up (e.g., 'spreadsheet', 'drive', 'document')."),
108
67
  },
109
- async ({ script }) => {
110
- return await runGasFakes(script);
68
+ },
69
+ async ({ service }) => {
70
+ try {
71
+ const fileName = `${service.toLowerCase()}.md`;
72
+
73
+ // Define potential paths for the skills documentation
74
+ const potentialPaths = [
75
+ // 1. Local project installation (e.g. from gas-fakes init standalone)
76
+ path.resolve(process.cwd(), "gf_agent", "skills", fileName),
77
+ path.resolve(process.cwd(), "gf_agent_standalone", "gf_agent", "skills", fileName),
78
+
79
+ // 2. Global Gemini CLI skill installation
80
+ path.resolve(os.homedir(), ".gemini", "skills", "gf_agent", "skills", fileName),
81
+
82
+ // 3. Bundled inside the npm package
83
+ path.resolve(__dirname, "../../gf_agent/skills", fileName)
84
+ ];
85
+
86
+ let docsPath = null;
87
+ for (const p of potentialPaths) {
88
+ if (fs.existsSync(p)) {
89
+ docsPath = p;
90
+ break;
91
+ }
92
+ }
93
+
94
+ if (!docsPath) {
95
+ // If not found locally, try fetching from the GitHub repository
96
+ const githubRawUrl = `https://raw.githubusercontent.com/brucemcpherson/gas-fakes/main/gf_agent/skills/${fileName}`;
97
+ try {
98
+ const response = await fetch(githubRawUrl);
99
+ if (response.ok) {
100
+ const githubContent = await response.text();
101
+ return {
102
+ content: [{ type: "text", text: githubContent }],
103
+ isError: false,
104
+ };
105
+ }
106
+ } catch (fetchErr) {
107
+ // Silently fail the fetch and fall through to the local error message
108
+ }
109
+
110
+ return {
111
+ content: [{ type: "text", text: `Documentation not found for service: ${service}. Checked multiple standard locations and GitHub origin.` }],
112
+ isError: true,
113
+ };
114
+ }
115
+
116
+ const content = fs.readFileSync(docsPath, "utf-8");
117
+ return {
118
+ content: [{ type: "text", text: content }],
119
+ isError: false,
120
+ };
121
+ } catch (err) {
122
+ return {
123
+ content: [{ type: "text", text: `Failed to read documentation: ${err.message}` }],
124
+ isError: true,
125
+ };
111
126
  }
112
- );
113
- }
127
+ }
128
+ );
114
129
 
115
- // Also add a generic tool for tasks that span multiple services
130
+ // Consolidated execution tool
116
131
  server.registerTool(
117
- "workspace_agent",
132
+ "run_script",
118
133
  {
119
- description: "A general-purpose agent to automate tasks across multiple Google Workspace services (Sheets, Docs, Drive, etc.)",
134
+ description: "Executes Google Apps Script code locally using the gas-fakes emulator. You can interact with multiple Workspace services in a single script.",
120
135
  inputSchema: {
121
136
  script: z.string().describe("The Google Apps Script code to execute locally."),
122
137
  },
@@ -10,6 +10,20 @@ class FakeAdvGmailMessages extends FakeAdvResource {
10
10
  super(mainService, 'users', Syncit.fxGmail);
11
11
  this.gmail = mainService;
12
12
  this.__fakeObjectType = 'Gmail.Users.Messages';
13
+
14
+ const self = this;
15
+ this.Attachments = {
16
+ get(userId, messageId, id) {
17
+ const { data, response } = self._call(
18
+ 'attachments.get',
19
+ { userId, messageId, id },
20
+ null,
21
+ 'messages'
22
+ );
23
+ gError(response, 'gmail', 'users.messages.attachments.get', true);
24
+ return data;
25
+ }
26
+ };
13
27
  }
14
28
 
15
29
  /**
@@ -18,10 +32,10 @@ class FakeAdvGmailMessages extends FakeAdvResource {
18
32
  * @param {string} id - The ID of the message to retrieve.
19
33
  * @returns {object} The message resource.
20
34
  */
21
- get(userId, id) {
35
+ get(userId, id, optionalArgs) {
22
36
  const { data, response } = this._call(
23
37
  'get',
24
- { userId, id },
38
+ { userId, id, ...optionalArgs },
25
39
  null,
26
40
  'messages'
27
41
  );
@@ -39,11 +53,79 @@ class FakeAdvGmailMessages extends FakeAdvResource {
39
53
  send(resource, userId, media) {
40
54
  const { data, response } = this._call(
41
55
  'send',
42
- { userId, resource, media },
56
+ { userId, requestBody: resource, media },
43
57
  null,
44
58
  'messages'
45
59
  );
46
60
  gError(response, 'gmail', 'users.messages.send');
47
61
  return data;
48
62
  }
63
+
64
+ /**
65
+ * Modifies the labels on the specified message.
66
+ * @param {object} resource - The modifications to apply.
67
+ * @param {string} userId - The user's email address.
68
+ * @param {string} id - The ID of the message to modify.
69
+ * @returns {object} The modified message resource.
70
+ */
71
+ modify(resource, userId, id) {
72
+ const { data, response } = this._call(
73
+ 'modify',
74
+ { userId, id, requestBody: resource },
75
+ null,
76
+ 'messages'
77
+ );
78
+ gError(response, 'gmail', 'users.messages.modify');
79
+ return data;
80
+ }
81
+
82
+ /**
83
+ * Modifies the labels on the specified messages.
84
+ * @param {object} resource - The batch modifications to apply.
85
+ * @param {string} userId - The user's email address.
86
+ */
87
+ batchModify(resource, userId) {
88
+ const { data, response } = this._call(
89
+ 'batchModify',
90
+ { userId, requestBody: resource },
91
+ null,
92
+ 'messages'
93
+ );
94
+ gError(response, 'gmail', 'users.messages.batchModify');
95
+ return data;
96
+ }
97
+
98
+ /**
99
+ * Moves the specified message to the trash.
100
+ * @param {string} userId - The user's email address.
101
+ * @param {string} id - The ID of the message to trash.
102
+ * @returns {object} The trashed message resource.
103
+ */
104
+ trash(userId, id) {
105
+ const { data, response } = this._call(
106
+ 'trash',
107
+ { userId, id },
108
+ null,
109
+ 'messages'
110
+ );
111
+ gError(response, 'gmail', 'users.messages.trash');
112
+ return data;
113
+ }
114
+
115
+ /**
116
+ * Removes the specified message from the trash.
117
+ * @param {string} userId - The user's email address.
118
+ * @param {string} id - The ID of the message to untrash.
119
+ * @returns {object} The untrashed message resource.
120
+ */
121
+ untrash(userId, id) {
122
+ const { data, response } = this._call(
123
+ 'untrash',
124
+ { userId, id },
125
+ null,
126
+ 'messages'
127
+ );
128
+ gError(response, 'gmail', 'users.messages.untrash');
129
+ return data;
130
+ }
49
131
  }