function doGet(e) { const primaryBase = "https://siawaseok.duckdns.org"; const fallbackBase = "https://siatube.wjg.jp"; const routes = { video: id => `/api/video2/${encodeURIComponent(id)}`, stream: id => `/api/stream/${encodeURIComponent(id)}`, stream2: id => `/api/stream/${encodeURIComponent(id)}/type2`, channel: id => `/api/channel/${encodeURIComponent(id)}`, q: q => `/api/search2?q=${encodeURIComponent(q)}`, comments: id => `/api/comments/${encodeURIComponent(id)}`, trend: () => `/api/trend`, playlist: id => `/api/playlist/${encodeURIComponent(id)}` }; let targetPath = null; for (let key in routes) { if (e.parameter[key] !== undefined) { targetPath = routes[key](e.parameter[key]); break; } } if (!targetPath) { return createResponse({ error: "No valid parameter provided" }, e.parameter.callback); } const maxRetries = 3; for (let attempt = 1; attempt <= maxRetries; attempt++) { try { const primaryUrl = primaryBase + targetPath; let response = UrlFetchApp.fetch(primaryUrl, { method: "get", muteHttpExceptions: true, timeoutSeconds: 40 }); if (response.getResponseCode() === 200) { return createResponse(response.getContentText(), e.parameter.callback); } const fallbackUrl = fallbackBase + targetPath; response = UrlFetchApp.fetch(fallbackUrl, { method: "get", muteHttpExceptions: true, timeoutSeconds: 30 }); if (response.getResponseCode() === 200) { return createResponse(response.getContentText(), e.parameter.callback); } } catch (err) {} } return createResponse({ error: "失敗しました" }, e.parameter.callback); } /** * JSONP対応レスポンス生成 * - callback が指定されていれば JSONP * - 指定されていなければ通常の JSON */ function createResponse(content, callback) { let text; try { const obj = typeof content === "string" ? JSON.parse(content) : content; if (callback) { text = `${callback}(${JSON.stringify(obj)})`; return ContentService.createTextOutput(text).setMimeType(ContentService.MimeType.JAVASCRIPT); } else { text = JSON.stringify(obj); return ContentService.createTextOutput(text).setMimeType(ContentService.MimeType.JSON); } } catch (e) { if (callback) { text = `${callback}(${JSON.stringify({ raw: content })})`; return ContentService.createTextOutput(text).setMimeType(ContentService.MimeType.JAVASCRIPT); } else { return ContentService.createTextOutput(content).setMimeType(ContentService.MimeType.JSON); } } }