
Claude Google Apps Script MCP Guide
β 1from shawntony
Integrate Claude AI with Google Apps Script to automate tasks in Google Sheets and Gmail.
Claude MCP Google Apps Script μ°λ μμ κ°μ΄λ
Claudeμ Google Apps Scriptλ₯Ό MCP(Model Context Protocol)λ‘ μ°κ²°νμ¬ κ°λ ₯ν μ 무 μλν μμ€ν ꡬμΆνκΈ°
π λͺ©μ°¨
- κ°μ
- μμ€ν μꡬμ¬ν
- 1λ¨κ³: Google Apps Script νλ‘μ νΈ μμ±
- 2λ¨κ³: MCP μλ² μ½λ μμ±
- 3λ¨κ³: μΉ μ± λ°°ν¬
- 4λ¨κ³: ν μ€νΈ μ€νλ λμνΈ μμ±
- 5λ¨κ³: MCP μλ² ν μ€νΈ
- 6λ¨κ³: λ‘컬 MCP ν΄λΌμ΄μΈνΈ μ€μ
- 7λ¨κ³: Claude Desktop μ°κ²°
- μ¬μ© μμ
- κ³ κΈ νμ©λ²
- λ¬Έμ ν΄κ²°
κ°μ
μ΄ κ°μ΄λλ Claude AIμ Google Apps Scriptλ₯Ό MCP νλ‘ν μ½μ ν΅ν΄ μ°κ²°νλ μμ ν λ°©λ²μ μ 곡ν©λλ€. μ°κ²° ν λ€μκ³Ό κ°μ κ°λ ₯ν κΈ°λ₯μ μ¬μ©ν μ μμ΅λλ€:
π μ£Όμ κΈ°λ₯
- π Google Sheets μλν: μ€μκ° λ°μ΄ν° μ½κΈ°/μ°κΈ°, λΆμ, 리ν¬νΈ μμ±
- π§ Gmail ν΅ν©: μ€λ§νΈ μ΄λ©μΌ λΆλ₯, μλ μλ΅, λλ λ°μ‘
- π€ μ 무 μλν: μΌμ κ΄λ¦¬, λ°μ΄ν° λΆμ, μλ¦Ό μμ€ν
- π μ€μκ° λμ보λ: μ¬λ¬ λ°μ΄ν° μμ€ ν΅ν© λͺ¨λν°λ§
μμ€ν μꡬμ¬ν
νμ μ€λΉμ¬ν
- Google κ³μ (Gmail)
- Node.js (v18 μ΄μ) - λ€μ΄λ‘λ
- Claude Desktop μ± - λ€μ΄λ‘λ
μ€μΉ νμΈ
node -v # v18.0.0 μ΄μ
npm -v # 9.0.0 μ΄μ1λ¨κ³: Google Apps Script νλ‘μ νΈ μμ±
1.1 μ νλ‘μ νΈ μμ±
- Google Apps Script μ μ
- "μ νλ‘μ νΈ" ν΄λ¦
- νλ‘μ νΈ μ΄λ¦μ **"Claude MCP Server"**λ‘ λ³κ²½
- κΈ°λ³Έ
myFunction()μ½λλ₯Ό λͺ¨λ μμ
1.2 νμΈ μ¬ν
- β νλ‘μ νΈ μ΄λ¦μ΄ "Claude MCP Server"λ‘ νμ
- β μ½λ μλν°κ° μμ ν λΉμ΄μλ μν
2λ¨κ³: MCP μλ² μ½λ μμ±
2.1 μ½λ λ³΅μ¬ λ° λΆμ¬λ£κΈ°
Google Apps Script μλν°μ λ€μ μ½λλ₯Ό 볡μ¬νμ¬ λΆμ¬λ£μΌμΈμ:
/**
* Claude MCP Server for Google Apps Script
* ν΄λ‘λμ κ΅¬κΈ μν¬μ€νμ΄μ€λ₯Ό μ°κ²°νλ MCP μλ²
*/
// MCP μλ² μ€μ
const MCP_CONFIG = {
name: "google-workspace-mcp",
version: "1.0.0",
description: "Google Workspace integration for Claude via MCP",
};
// λꡬ λͺ©λ‘ μ μ
const TOOLS = {
READ_SHEET: {
name: "read_google_sheet",
description: "Google Sheetsμμ λ°μ΄ν°λ₯Ό μ½μ΄μ΅λλ€",
inputSchema: {
type: "object",
properties: {
spreadsheetId: {
type: "string",
description: "μ€νλ λμνΈ ID",
},
range: {
type: "string",
description: "μ½μ λ²μ (μ: A1:C10)",
default: "A:Z",
},
},
required: ["spreadsheetId"],
},
},
WRITE_SHEET: {
name: "write_google_sheet",
description: "Google Sheetsμ λ°μ΄ν°λ₯Ό μλλ€",
inputSchema: {
type: "object",
properties: {
spreadsheetId: {
type: "string",
description: "μ€νλ λμνΈ ID",
},
range: {
type: "string",
description: "μΈ λ²μ (μ: A1:C10)",
},
values: {
type: "array",
description: "μΈ λ°μ΄ν° (2μ°¨μ λ°°μ΄)",
},
},
required: ["spreadsheetId", "range", "values"],
},
},
SEND_EMAIL: {
name: "send_gmail",
description: "Gmailμ ν΅ν΄ μ΄λ©μΌμ λ°μ‘ν©λλ€",
inputSchema: {
type: "object",
properties: {
to: {
type: "string",
description: "λ°λ μ¬λ μ΄λ©μΌ",
},
subject: {
type: "string",
description: "μ΄λ©μΌ μ λͺ©",
},
body: {
type: "string",
description: "μ΄λ©μΌ λ΄μ©",
},
},
required: ["to", "subject", "body"],
},
},
};
/**
* MCP μλ² λ©μΈ νΈλ€λ¬
*/
function doPost(e) {
try {
const request = JSON.parse(e.postData.contents);
console.log("MCP Request:", request);
// μμ² νμ
μ λ°λ₯Έ μ²λ¦¬
switch (request.method) {
case "tools/list":
return createResponse(handleToolsList());
case "tools/call":
return createResponse(handleToolCall(request.params));
default:
return createErrorResponse("Unknown method: " + request.method);
}
} catch (error) {
console.error("MCP Error:", error);
return createErrorResponse("Server error: " + error.message);
}
}
/**
* λꡬ λͺ©λ‘ λ°ν
*/
function handleToolsList() {
return {
tools: Object.values(TOOLS),
};
}
/**
* λꡬ μ€ν
*/
function handleToolCall(params) {
const { name, arguments: args } = params;
try {
switch (name) {
case "read_google_sheet":
return readGoogleSheet(args);
case "write_google_sheet":
return writeGoogleSheet(args);
case "send_gmail":
return sendGmail(args);
default:
throw new Error("Unknown tool: " + name);
}
} catch (error) {
return {
isError: true,
content: [
{
type: "text",
text: `λꡬ μ€ν μ€λ₯: ${error.message}`,
},
],
};
}
}
/**
* Google Sheets λ°μ΄ν° μ½κΈ°
*/
function readGoogleSheet(args) {
const { spreadsheetId, range = "A:Z" } = args;
try {
const spreadsheet = SpreadsheetApp.openById(spreadsheetId);
const sheet = spreadsheet.getActiveSheet();
const data = sheet.getRange(range).getValues();
// λΉ ν μ κ±°
const filteredData = data.filter((row) => row.some((cell) => cell !== ""));
return {
content: [
{
type: "text",
text: `μ€νλ λμνΈ λ°μ΄ν° (${
filteredData.length
}ν):\n${JSON.stringify(filteredData, null, 2)}`,
},
],
};
} catch (error) {
throw new Error(`Sheets μ½κΈ° μ€ν¨: ${error.message}`);
}
}
/**
* Google Sheets λ°μ΄ν° μ°κΈ°
*/
function writeGoogleSheet(args) {
const { spreadsheetId, range, values } = args;
try {
const spreadsheet = SpreadsheetApp.openById(spreadsheetId);
const sheet = spreadsheet.getActiveSheet();
if (values.length > 0) {
sheet.getRange(range).setValues(values);
}
return {
content: [
{
type: "text",
text: `μ±κ³΅μ μΌλ‘ ${values.length}νμ λ°μ΄ν°λ₯Ό ${range} λ²μμ μ μ₯νμ΅λλ€.`,
},
],
};
} catch (error) {
throw new Error(`Sheets μ°κΈ° μ€ν¨: ${error.message}`);
}
}
/**
* Gmail μ΄λ©μΌ λ°μ‘
*/
function sendGmail(args) {
const { to, subject, body } = args;
try {
GmailApp.sendEmail(to, subject, body);
return {
content: [
{
type: "text",
text: `μ΄λ©μΌμ΄ μ±κ³΅μ μΌλ‘ ${to}μκ² λ°μ‘λμμ΅λλ€.`,
},
],
};
} catch (error) {
throw new Error(`μ΄λ©μΌ λ°μ‘ μ€ν¨: ${error.message}`);
}
}
/**
* μλ΅ μμ± ν¬νΌ
*/
function createResponse(data) {
return ContentService.createTextOutput(JSON.stringify(data)).setMimeType(
ContentService.MimeType.JSON
);
}
function createErrorResponse(message) {
return ContentService.createTextOutput(
JSON.stringify({
error: {
code: -1,
message: message,
},
})
).setMimeType(ContentService.MimeType.JSON);
}
/**
* ν
μ€νΈ ν¨μ
*/
function testMCPServer() {
console.log("MCP μλ² ν
μ€νΈ μμ");
// λꡬ λͺ©λ‘ ν
μ€νΈ
const toolsList = handleToolsList();
console.log("λꡬ λͺ©λ‘:", toolsList);
console.log("MCP μλ²κ° μ μμ μΌλ‘ μ€μ λμμ΅λλ€!");
}2.2 μ μ₯
Ctrl + Sλλ πΎ μ μ₯ λ²νΌ ν΄λ¦- λ¬Έλ² μ€λ₯κ° μλμ§ νμΈ (λΉ¨κ° λ°μ€μ΄ μμ΄μΌ ν¨)
3λ¨κ³: μΉ μ± λ°°ν¬
3.1 λ°°ν¬ μ€μ
- μ°μλ¨ "λ°°ν¬" λ²νΌ ν΄λ¦
- "μ λ°°ν¬" μ ν
- ν±λλ°ν΄ βοΈ μμ΄μ½ ν΄λ¦ β "μΉ μ±" μ ν
- μ€μ κ° μ
λ ₯:
- μ€λͺ : "Claude MCP Server v1.0"
- λ€μ μ¬μ©μλ‘ μ€ν: "λ"
- μ‘μΈμ€ κΆν: "λͺ¨λ μ¬μ©μ"
3.2 κΆν μΉμΈ
- "λ°°ν¬" λ²νΌ ν΄λ¦
- "μ‘μΈμ€ μΉμΈ" νμ μμ ν΄λ¦
- Google κ³μ μ ν
- "κ³ κΈ" β "μμ νμ§ μμ(unsafe)" β "μ΄λ" ν΄λ¦
- "νμ©" λ²νΌ ν΄λ¦
3.3 μΉ μ± URL 볡μ¬
- λ°°ν¬ μλ£ ν λνλλ μΉ μ± URLμ 볡μ¬ν΄μ μ μ₯
- νν:
https://script.google.com/macros/s/ABC...XYZ/exec
4λ¨κ³: ν μ€νΈ μ€νλ λμνΈ μμ±
4.1 μ μ€νλ λμνΈ μμ±
- Google Sheets μ μ
- "μλ‘ λ§λ€κΈ°" β "λΉ μ€νλ λμνΈ" ν΄λ¦
- μ€νλ λμνΈ μ΄λ¦μ **"Claude MCP Test Sheet"**λ‘ λ³κ²½
4.2 ν μ€νΈ λ°μ΄ν° μ λ ₯
A1 μ λΆν° λ€μ λ°μ΄ν°λ₯Ό 볡μ¬ν΄μ λΆμ¬λ£μΌμΈμ:
μ΄λ¦ λΆμ μ§κΈ κΈμ¬
κΉμ² μ κ°λ°ν κ³Όμ₯ 5000
μ΄μν¬ λ§μΌν
ν λ리 4000
λ°λ―Όμ μΈμ¬ν μ°¨μ₯ 6000
μ΅μμ μ¬λ¬΄ν μ¬μ 35004.3 μ€νλ λμνΈ μ€μ
-
μ€νλ λμνΈ ID 볡μ¬
- λΈλΌμ°μ μ£Όμμ°½μμ ID λΆλΆ 볡μ¬
https://docs.google.com/spreadsheets/d/[μ΄λΆλΆμ΄ID]/edit
-
곡μ μ€μ
- μ°μλ¨ "곡μ " λ²νΌ ν΄λ¦
- "λ§ν¬κ° μλ λͺ¨λ μ¬μ©μ" β "νΈμ§μ" κΆνμΌλ‘ λ³κ²½
- "μλ£" ν΄λ¦
5λ¨κ³: MCP μλ² ν μ€νΈ
5.1 κΈ°λ³Έ ν μ€νΈ
- Google Apps Scriptλ‘ λμκ°κΈ°
- ν¨μ μ ν λλ‘λ€μ΄μμ
testMCPServerμ ν - βΆοΈ "μ€ν" λ²νΌ ν΄λ¦
- κΆν μΉμΈ (μ²μ μ€νμ)
5.2 μ€νλ λμνΈ μ½κΈ° ν μ€νΈ
κΈ°μ‘΄ μ½λ 맨 μλμ λ€μ ν¨μλ₯Ό μΆκ°:
/**
* μ€μ μ€νλ λμνΈ μ½κΈ° ν
μ€νΈ
*/
function testReadSheet() {
const spreadsheetId = "YOUR_SHEET_ID"; // μ€μ μ€νλ λμνΈ IDλ‘ λ³κ²½
try {
const result = readGoogleSheet({
spreadsheetId: spreadsheetId,
range: "A1:D10",
});
console.log("μ€νλ λμνΈ μ½κΈ° μ±κ³΅!");
console.log("κ²°κ³Ό:", result);
} catch (error) {
console.error("μ€νλ λμνΈ μ½κΈ° μ€ν¨:", error);
}
}5.3 ν μ€νΈ μ€ν
testReadSheetν¨μ μ ν ν μ€ν- μ€ν λ‘κ·Έμμ ν μ€νΈ λ°μ΄ν°κ° μΆλ ₯λλμ§ νμΈ
6λ¨κ³: λ‘컬 MCP ν΄λΌμ΄μΈνΈ μ€μ
6.1 νλ‘μ νΈ ν΄λ μμ±
μνλ μμΉμ λ€μ κ΅¬μ‘°λ‘ ν΄λλ₯Ό μμ±νμΈμ:
mkdir claude-gas-mcp
cd claude-gas-mcp
mkdir src
mkdir config6.2 package.json μμ±
νλ‘μ νΈ λ£¨νΈμ package.json νμΌμ μμ±:
{
"name": "claude-gas-mcp",
"version": "1.0.0",
"description": "Claudeμ Google Apps Script μ°κ²°μ μν MCP ν΄λΌμ΄μΈνΈ",
"main": "src/server.js",
"type": "module",
"scripts": {
"start": "node src/server.js",
"dev": "node --watch src/server.js"
},
"keywords": ["claude", "mcp", "google-apps-script"],
"author": "",
"license": "MIT",
"dependencies": {
"@modelcontextprotocol/sdk": "^0.4.0",
"axios": "^1.6.0"
}
}6.3 μμ‘΄μ± μ€μΉ
npm install6.4 μ€μ νμΌ μμ±
config/mcp-config.json νμΌμ μμ±:
{
"name": "Google Apps Script MCP Server",
"version": "1.0.0",
"description": "Google Workspaceμ Claude μ°κ²°",
"config": {
"webAppUrl": "YOUR_WEB_APP_URL_HERE",
"testSpreadsheetId": "YOUR_SPREADSHEET_ID_HERE"
},
"tools": ["read_google_sheet", "write_google_sheet", "send_gmail"]
}6.5 MCP μλ² μ½λ μμ±
src/server.js νμΌμ μμ±:
#!/usr/bin/env node
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
import axios from "axios";
import fs from "fs";
import path from "path";
import { fileURLToPath } from "url";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// μ€μ νμΌ λ‘λ
const configPath = path.join(__dirname, "../config/mcp-config.json");
const config = JSON.parse(fs.readFileSync(configPath, "utf8"));
class GoogleAppsScriptMCPServer {
constructor() {
this.server = new Server(
{
name: "google-apps-script-mcp",
version: "1.0.0",
},
{
capabilities: {
tools: {},
},
}
);
this.setupToolHandlers();
this.setupErrorHandling();
}
setupErrorHandling() {
this.server.onerror = (error) => {
console.error("[MCP Error]", error);
};
process.on("SIGINT", async () => {
await this.server.close();
process.exit(0);
});
}
setupToolHandlers() {
// λꡬ λͺ©λ‘ μ 곡
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: "read_google_sheet",
description: "Google Sheetsμμ λ°μ΄ν°λ₯Ό μ½μ΄μ΅λλ€",
inputSchema: {
type: "object",
properties: {
spreadsheetId: {
type: "string",
description: "μ€νλ λμνΈ ID",
},
range: {
type: "string",
description: "μ½μ λ²μ (μ: A1:C10)",
default: "A:Z",
},
},
required: ["spreadsheetId"],
},
},
{
name: "write_google_sheet",
description: "Google Sheetsμ λ°μ΄ν°λ₯Ό μλλ€",
inputSchema: {
type: "object",
properties: {
spreadsheetId: {
type: "string",
description: "μ€νλ λμνΈ ID",
},
range: {
type: "string",
description: "μΈ λ²μ (μ: A1:C10)",
},
values: {
type: "array",
description: "μΈ λ°μ΄ν° (2μ°¨μ λ°°μ΄)",
},
},
required: ["spreadsheetId", "range", "values"],
},
},
{
name: "send_gmail",
description: "Gmailμ ν΅ν΄ μ΄λ©μΌμ λ°μ‘ν©λλ€",
inputSchema: {
type: "object",
properties: {
to: {
type: "string",
description: "λ°λ μ¬λ μ΄λ©μΌ",
},
subject: {
type: "string",
description: "μ΄λ©μΌ μ λͺ©",
},
body: {
type: "string",
description: "μ΄λ©μΌ λ΄μ©",
},
},
required: ["to", "subject", "body"],
},
},
],
};
});
// λꡬ μ€ν
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
try {
switch (name) {
case "read_google_sheet":
return await this.readGoogleSheet(args);
case "write_google_sheet":
return await this.writeGoogleSheet(args);
case "send_gmail":
return await this.sendGmail(args);
default:
throw new Error(`μ μ μλ λꡬ: ${name}`);
}
} catch (error) {
return {
content: [
{
type: "text",
text: `μ€λ₯ λ°μ: ${error.message}`,
},
],
isError: true,
};
}
});
}
async callGoogleAppsScript(toolName, params) {
const payload = {
method: "tools/call",
params: {
name: toolName,
arguments: params,
},
};
try {
console.log(`[MCP] Google Apps Script νΈμΆ: ${toolName}`, params);
const response = await axios.post(config.config.webAppUrl, payload, {
headers: {
"Content-Type": "application/json",
},
timeout: 30000,
});
console.log(`[MCP] μλ΅ λ°μ:`, response.data);
return response.data;
} catch (error) {
console.error(`[MCP] μμ² μ€ν¨:`, error.message);
throw new Error(`Google Apps Script νΈμΆ μ€ν¨: ${error.message}`);
}
}
async readGoogleSheet(args) {
const result = await this.callGoogleAppsScript("read_google_sheet", args);
return {
content: [
{
type: "text",
text: result.content?.[0]?.text || "λ°μ΄ν°λ₯Ό μ½μ΄μμ΅λλ€.",
},
],
};
}
async writeGoogleSheet(args) {
const result = await this.callGoogleAppsScript("write_google_sheet", args);
return {
content: [
{
type: "text",
text: result.content?.[0]?.text || "λ°μ΄ν°λ₯Ό μ μ₯νμ΅λλ€.",
},
],
};
}
async sendGmail(args) {
const result = await this.callGoogleAppsScript("send_gmail", args);
return {
content: [
{
type: "text",
text: result.content?.[0]?.text || "μ΄λ©μΌμ λ°μ‘νμ΅λλ€.",
},
],
};
}
async run() {
const transport = new StdioServerTransport();
await this.server.connect(transport);
console.error("Google Apps Script MCP μλ²κ° μμλμμ΅λλ€.");
console.error(`μΉ μ± URL: ${config.config.webAppUrl}`);
console.error(
"μ¬μ© κ°λ₯ν λꡬ: read_google_sheet, write_google_sheet, send_gmail"
);
}
}
// μλ² μμ
const server = new GoogleAppsScriptMCPServer();
server.run().catch(console.error);6.6 ν μ€νΈ μ€ν¬λ¦½νΈ μμ±
src/test.js νμΌμ μμ±:
import axios from "axios";
import fs from "fs";
import path from "path";
import { fileURLToPath } from "url";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// μ€μ νμΌ λ‘λ
const configPath = path.join(__dirname, "../config/mcp-config.json");
const config = JSON.parse(fs.readFileSync(configPath, "utf8"));
async function testGoogleAppsScript() {
console.log("π§ͺ Google Apps Script MCP μ°κ²° ν
μ€νΈ μμ\n");
// ν
μ€νΈ 1: μ€νλ λμνΈ μ½κΈ°
console.log("π ν
μ€νΈ 1: μ€νλ λμνΈ λ°μ΄ν° μ½κΈ°");
try {
const readPayload = {
method: "tools/call",
params: {
name: "read_google_sheet",
arguments: {
spreadsheetId: config.config.testSpreadsheetId,
range: "A1:D10",
},
},
};
const readResponse = await axios.post(
config.config.webAppUrl,
readPayload,
{
headers: { "Content-Type": "application/json" },
timeout: 10000,
}
);
console.log("β
μ€νλ λμνΈ μ½κΈ° μ±κ³΅!");
console.log("π μλ΅:", readResponse.data);
} catch (error) {
console.log("β μ€νλ λμνΈ μ½κΈ° μ€ν¨:", error.message);
}
console.log("\nπ ν
μ€νΈ μλ£!");
}
// ν
μ€νΈ μ€ν
testGoogleAppsScript().catch(console.error);6.7 μ°κ²° ν μ€νΈ
node src/test.js7λ¨κ³: Claude Desktop μ°κ²°
7.1 Claude Desktop μ€μ νμΌ μμ
Windowsμμ μ€μ νμΌ μμΉ:
%APPDATA%\Claude\claude_desktop_config.json7.2 μ€μ νμΌ λ΄μ©
κΈ°μ‘΄ μ€μ μ λ€μ λ΄μ©μ μΆκ°:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"@modelcontextprotocol/server-filesystem",
"C:\\Users\\[μ¬μ©μλͺ
]\\Desktop"
],
"env": {}
},
"google-apps-script": {
"command": "node",
"args": ["C:\\[νλ‘μ νΈκ²½λ‘]\\claude-gas-mcp\\src\\server.js"],
"env": {
"NODE_ENV": "production"
}
}
},
"darkMode": "dark",
"scale": 0,
"locale": "ko-KR"
}7.3 Claude Desktop μ¬μμ
- Claude Desktop μ±μ μμ ν μ’ λ£
- μ±μ λ€μ μμ
- μ λν μμ
7.4 μ°κ²° ν μ€νΈ
Claude Desktopμμ λ€μκ³Ό κ°μ΄ ν μ€νΈ:
Google Apps Script MCP μλ²κ° μ°κ²°λμλμ§ νμΈνκ³ ,
μ€νλ λμνΈ ID [YOUR_SHEET_ID]μ λ°μ΄ν°λ₯Ό μ½μ΄μ 보μ¬μ€.μ¬μ© μμ
π κΈ°λ³Έ λ°μ΄ν° μ‘°μ
μ€νλ λμνΈ μ½κΈ°
"μ€νλ λμνΈ ID 13Qy45cJ6oDJsyS007bml2GAyklGAiY7EGd1GZ1vO7roμμ
μ§μ λ°μ΄ν°λ₯Ό μ½μ΄μ λΆμλ³ νκ· κΈμ¬λ₯Ό κ³μ°ν΄μ€"λ°μ΄ν° μΆκ°
"μ μ§μ μ 보λ₯Ό μΆκ°ν΄μ€:
μ΄λ¦-νκΈΈλ, λΆμ-ITν, μ§κΈ-μ¬μ, κΈμ¬-3200"μ΄λ©μΌ λ°μ‘
"λΆμλ³ κΈμ¬ νν©μ μμ½ν΄μ manager@company.comμΌλ‘ 보λ΄μ€"π€ κ³ κΈ μλν μμ²
μ 무 μλν ν¨μ μμ±
"λ§€μΌ μμΉ¨ 8μμ μ λ λ§€μΆ λ°μ΄ν°λ₯Ό λΆμν΄μ
μ΄λ©μΌλ‘ 보λ΄μ£Όλ GAS ν¨μλ₯Ό λ§λ€μ΄μ€"μ€λ§νΈ μ΄λ©μΌ μμ€ν
"Gmailμμ νΉμ ν€μλκ° ν¬ν¨λ μ΄λ©μΌμ μλμΌλ‘ λΆλ₯νκ³
μ μ ν ν
νλ¦ΏμΌλ‘ λ΅λ³νλ ν¨μλ₯Ό λ§λ€μ΄μ€"κ²°κ³Ό: ν΄λ‘λκ° ν€μλ κΈ°λ° λΆλ₯ μκ³ λ¦¬μ¦, μλ μλ΅ μμ€ν , λΌλ²¨λ§ κΈ°λ₯μ ν¬ν¨ν μμ ν μ΄λ©μΌ μλν μμ€ν μ μμ±ν©λλ€.
μ€μκ° λμ보λ
"μ¬λ¬ μνΈμ λ°μ΄ν°λ₯Ό μ’
ν©ν΄μ μ€μκ° λμ보λλ₯Ό
λ§λ€μ΄μ£Όλ ν¨μλ₯Ό μμ±ν΄μ€"κ²°κ³Ό: λ€μ€ λ°μ΄ν° μμ€λ₯Ό ν΅ν©νμ¬ μ€μκ° μ λ°μ΄νΈλλ HTML λμ보λμ μλ κ°±μ μμ€ν μ ꡬμΆν©λλ€.
λ°μ΄ν° λΆμ μλν
"λ§€μΆ λ°μ΄ν°λ₯Ό λΆμν΄μ νΈλ λ μμΈ‘νκ³
μΈμ¬μ΄νΈλ₯Ό μμ½ν΄μ κ²½μμ§μκ² λ³΄κ³ νλ μμ€ν
μ λ§λ€μ΄μ€"κ²°κ³Ό: ν΅κ³ λΆμ, μμΈ‘ λͺ¨λΈλ§, μκ°ν μ°¨νΈ, μλ 리ν¬νΈ μμ± κΈ°λ₯μ ν¬ν¨ν BI μμ€ν μ ꡬμΆν©λλ€.
npm installNo common issues documented yet. If you hit a problem, the repository's GitHub Issues page is the best place to look.