Created
May 27, 2025 06:46
-
-
Save ttlg/31815dd121efcfd806f69bc257951ca1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* LINE → GitHub Issue → Google Sheets Logger (signature-less robust版) | |
* ※ Google Apps Script Webアプリでは HTTP ヘッダーを直接取得できないため、 | |
* LINE 署名検証は割愛しています(Webhook URL を秘匿できる環境前提)。 | |
* @license MIT | |
*/ | |
/* ---------- 設定 ---------- */ | |
const CONF = { | |
LINE_ACCESS_TOKEN: PropertiesService.getScriptProperties().getProperty('LINE_ACCESS_TOKEN'), | |
GH_OWNER: PropertiesService.getScriptProperties().getProperty('GH_OWNER'), | |
GH_REPO: PropertiesService.getScriptProperties().getProperty('GH_REPO'), | |
GH_TOKEN: PropertiesService.getScriptProperties().getProperty('GH_TOKEN'), | |
SPREADSHEET_ID: PropertiesService.getScriptProperties().getProperty('SPREADSHEET_ID'), | |
}; | |
/* ---------- エントリポイント ---------- */ | |
function doPost(e) { | |
try { | |
if (!e || !e.postData || !e.postData.contents) throw new Error('Empty POST body'); | |
const payload = JSON.parse(e.postData.contents); | |
if (!payload.events || !Array.isArray(payload.events)) throw new Error('Invalid LINE payload'); | |
payload.events | |
.filter(evt => evt.type === 'message' && evt.message && evt.message.type === 'text') | |
.forEach(evt => handleTextMessage(evt)); | |
return ContentService.createTextOutput('OK'); // 200 OK | |
} catch (err) { | |
console.error(`doPost error: ${err.message}\n${err.stack}`); | |
logToSheet({ status: 'ERROR', message: err.message }); | |
return ContentService.createTextOutput('Error').setHttpStatusCode(500); | |
} | |
} | |
/* ---------- メッセージ処理 ---------- */ | |
function handleTextMessage(event) { | |
const userText = (event.message.text || '').trim() || 'Hello!'; | |
const issueTitle = `@claude ${userText}`; | |
const issueUrl = createGithubIssue(issueTitle, issueTitle); | |
logToSheet({ | |
userId: event.source && event.source.userId, | |
message: userText, | |
url: issueUrl, | |
status: issueUrl ? 'OK' : 'NG', | |
}); | |
const replyText = issueUrl | |
? `✅ Issue を作成しました:\n${issueUrl}` | |
: `❌ Issue 作成に失敗しました`; | |
replyToLine(event.replyToken, replyText); | |
} | |
/* ---------- GitHub Issue 作成 ---------- */ | |
function createGithubIssue(title, body) { | |
try { | |
const url = `https://api.github.com/repos/${CONF.GH_OWNER}/${CONF.GH_REPO}/issues`; | |
const res = UrlFetchApp.fetch(url, { | |
method: 'post', | |
contentType: 'application/json', | |
headers: { Authorization: `token ${CONF.GH_TOKEN}` }, | |
payload: JSON.stringify({ title, body }), | |
muteHttpExceptions: true, | |
}); | |
if (res.getResponseCode() !== 201) { | |
throw new Error(`GitHub ${res.getResponseCode()}: ${res.getContentText()}`); | |
} | |
return JSON.parse(res.getContentText()).html_url; | |
} catch (err) { | |
console.error(`createGithubIssue error: ${err.message}`); | |
return null; | |
} | |
} | |
/* ---------- LINE 返信 ---------- */ | |
function replyToLine(replyToken, text) { | |
try { | |
UrlFetchApp.fetch('https://api.line.me/v2/bot/message/reply', { | |
method: 'post', | |
contentType: 'application/json', | |
headers: { Authorization: `Bearer ${CONF.LINE_ACCESS_TOKEN}` }, | |
payload: JSON.stringify({ | |
replyToken, | |
messages: [{ type: 'text', text }], | |
}), | |
muteHttpExceptions: true, | |
}); | |
} catch (err) { | |
console.error(`replyToLine error: ${err.message}`); | |
} | |
} | |
/* ---------- Google Sheets へのログ ---------- */ | |
function logToSheet(obj) { | |
try { | |
if (!CONF.SPREADSHEET_ID) return; | |
const ss = SpreadsheetApp.openById(CONF.SPREADSHEET_ID); | |
const sheet = ss.getSheets()[0]; | |
if (sheet.getLastRow() === 0) { | |
sheet.appendRow(['Timestamp', 'UserId', 'Message', 'IssueURL', 'Status']); | |
} | |
sheet.appendRow([ | |
new Date(), | |
obj.userId || '', | |
obj.message || '', | |
obj.url || '', | |
obj.status || 'NG', | |
]); | |
} catch (err) { | |
console.error(`logToSheet error: ${err.message}`); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment