請選擇一個 .md 或 .txt 檔案上傳:
或
直接貼上 Markdown 文字到下方:
請貼上您從 Google Apps Script 取得的網路應用程式 URL。
請輸入您的名稱或代號 (選填)
您可以選擇以下兩種方式來設定您的 Google Apps Script (GAS) 網址:
方法一:直接寫入 HTML (推薦)
優點:最簡單、一勞永逸。只要修改 HTML 檔,所有使用者都能直接使用,無需額外設定。
缺點:每次更新 GAS 網址時,都需要重新修改並分發 HTML 檔案。
方法二:使用「設定」介面
優點:靈活,使用者可以在不修改程式碼的情況下,自行更換 GAS 網址。
缺點:每個使用者都需要手動設定一次。網址儲存在瀏覽器的 Local Storage 中,若清除瀏覽器資料或更換電腦,就需要重新設定。
下方的區塊是您需要用到的完整 GAS 程式碼。請點擊右上角的按鈕將其複製。
/**
* @OnlyCurrentDoc
* 心智圖資料雲端儲存 Google Apps Script (ES5 相容版)
* 作者: 阿剛老師 (修改 by Gemini)
* 功能: 接收來自心智圖工具的資料,並存儲/讀取/刪除在綁定的 Google 試算表中。
*/
// --- 常數設定 ---
var SHEET_LIST_NAME = '心智圖列表';
var SHEET_DATA_NAME = '心智圖資料';
var LIST_HEADERS = ['心智圖名稱', '上傳者', '更新時間', '資料ID'];
var DATA_HEADERS = ['資料ID', '心智圖內容 (JSON)'];
/**
* 當此 Script 作為 Web App 接收到 GET 請求時執行
*/
function doGet(e) {
try {
var action = e.parameter.action;
var ss = setupSheets();
var listSheet = ss.listSheet;
var dataSheet = ss.dataSheet;
if (action === 'getList') {
var listData = listSheet.getDataRange().getValues();
listData.shift(); // 移除標頭
var result = [];
for (var i = 0; i < listData.length; i++) {
result.push({
name: listData[i][0],
uploader: listData[i][1],
updateTime: listData[i][2],
id: listData[i][3]
});
}
return createJsonResponse({ status: 'success', data: result.reverse() });
} else if (action === 'getMap' && e.parameter.id) {
var dataId = e.parameter.id;
var dataSheetData = dataSheet.getDataRange().getValues();
dataSheetData.shift(); // 移除標頭
var foundRow = null;
for (var j = 0; j < dataSheetData.length; j++) {
if (dataSheetData[j][0] === dataId) {
foundRow = dataSheetData[j];
break;
}
}
if (foundRow) {
return createJsonResponse({ status: 'success', data: foundRow[1] });
} else {
throw new Error('找不到對應的資料ID: ' + dataId);
}
} else {
throw new Error('無效的操作或缺少參數 (action=getList 或 action=getMap&id=...)');
}
} catch (error) {
return createJsonResponse({ status: 'error', message: error.message });
}
}
/**
* 當此 Script 作為 Web App 接收到 POST 請求時執行
*/
function doPost(e) {
try {
var ss = setupSheets();
var listSheet = ss.listSheet;
var dataSheet = ss.dataSheet;
if (!e || !e.postData || !e.postData.contents) {
throw new Error('無效的請求資料。');
}
var postData = JSON.parse(e.postData.contents);
var action = postData.action || 'save'; // 預設 action 為 'save'
if (action === 'save') {
return handleSave(postData, listSheet, dataSheet);
} else if (action === 'deleteMap') {
return handleDelete(postData, listSheet, dataSheet);
} else {
throw new Error('無效的 POST 操作。');
}
} catch (error) {
return createJsonResponse({ status: 'error', message: error.message, stack: error.stack });
}
}
/**
* 處理儲存心智圖的邏輯
*/
function handleSave(postData, listSheet, dataSheet) {
var mindMapName = postData.name;
var mindMapContent = postData.content;
var uploader = postData.uploader || '';
if (!mindMapName || !mindMapContent) {
throw new Error('傳入的資料格式不正確,缺少 \'name\' 或 \'content\'.');
}
var listData = listSheet.getDataRange().getValues();
var nameExists = false;
for (var i = 1; i < listData.length; i++) {
if (listData[i][0] === mindMapName) {
nameExists = true;
break;
}
}
var now = new Date();
if (nameExists) {
// If name exists, append timestamp to make it unique
var timestamp = Utilities.formatDate(now, Session.getScriptTimeZone(), " (yyyy-MM-dd HH:mm:ss)");
mindMapName += timestamp;
}
// Always create a new entry
var dataId = generateUUID();
listSheet.appendRow([mindMapName, uploader, now, dataId]);
dataSheet.appendRow([dataId, mindMapContent]);
return createJsonResponse({ status: 'success', message: "心智圖 '" + mindMapName + "' 已成功新增。" });
}
/**
* 處理刪除心智圖的邏輯
*/
function handleDelete(postData, listSheet, dataSheet) {
var dataId = postData.id;
if (!dataId) {
throw new Error('缺少要刪除的資料ID。');
}
var listData = listSheet.getDataRange().getValues();
var listRowToDelete = -1;
for (var i = 1; i < listData.length; i++) {
if (listData[i][3] === dataId) {
listRowToDelete = i + 1;
break;
}
}
if (listRowToDelete > -1) {
listSheet.deleteRow(listRowToDelete);
}
var dataSheetData = dataSheet.getDataRange().getValues();
var dataRowToDelete = -1;
for (var j = 1; j < dataSheetData.length; j++) {
if (dataSheetData[j][0] === dataId) {
dataRowToDelete = j + 1;
break;
}
}
if (dataRowToDelete > -1) {
dataSheet.deleteRow(dataRowToDelete);
}
if (listRowToDelete > -1 || dataRowToDelete > -1) {
return createJsonResponse({ status: 'success', message: '資料已成功刪除。' });
} else {
throw new Error('在試算表中找不到要刪除的資料ID: ' + dataId);
}
}
/**
* 檢查並初始化所需的工作表和標頭
*/
function setupSheets() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var listSheet = ss.getSheetByName(SHEET_LIST_NAME);
if (!listSheet) {
listSheet = ss.insertSheet(SHEET_LIST_NAME);
listSheet.appendRow(LIST_HEADERS);
listSheet.setFrozenRows(1);
listSheet.getRange('A:D').applyRowBanding();
listSheet.setColumnWidth(1, 250);
listSheet.setColumnWidth(2, 150);
listSheet.setColumnWidth(3, 200);
listSheet.setColumnWidth(4, 300);
}
var dataSheet = ss.getSheetByName(SHEET_DATA_NAME);
if (!dataSheet) {
dataSheet = ss.insertSheet(SHEET_DATA_NAME);
dataSheet.appendRow(DATA_HEADERS);
dataSheet.setFrozenRows(1);
dataSheet.setColumnWidth(1, 300);
dataSheet.setColumnWidth(2, 800);
}
return { listSheet: listSheet, dataSheet: dataSheet };
}
/**
* 產生一個簡易的唯一ID (UUID v4)
*/
function generateUUID() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
/**
* 建立一個標準的 JSON 回應
*/
function createJsonResponse(data) {
return ContentService.createTextOutput(JSON.stringify(data))
.setMimeType(ContentService.MimeType.JSON);
}
完成以上步驟後,您就可以將複製的 URL,透過前面提到的兩種方式之一,設定到本工具中。
請貼上要連結的網址 (留空則清除連結):
請貼上圖片的網址 (留空則清除圖片):
或從已發佈的 Google 文件網址提取圖片: