Last active
May 3, 2024 22:01
-
-
Save idoleat/21752e2ec0a5d1e0283390abe27466e2 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
let HOMEWORK_NOTE_ID = '' // hackmd note to write to | |
let HACKMD_API_KEY = '' // your hackmd api key | |
let GITHUB_PERSONAL_ACCESS_TOKEN = '' // currently not in use | |
let EMAIL = { | |
'recipient': '', | |
'subject': 'Linux 核心課程: 已收到第 4 次作業的提交', | |
'body': '(本信件是自動產生,請不要回覆)\n請詳閱 https://hackmd.io/@sysprog/linux2024-lab0 的說明,確認 HackMD 筆記的存取權限及內容規範符合預期,若登記成功,應可在 https://hackmd.io/@sysprog/linux2024-homework4 見到你提交的 GitHub/HackMD 超連結。\n\n' | |
} | |
let PUBLISHED_LINKS = []; // kind of ugly but it works | |
// Exexcute this once to subscribe onSubmit event | |
function setTrigger() { | |
let currentForm = FormApp.getActiveForm(); | |
ScriptApp.newTrigger('onSubmit') | |
.forForm(currentForm) | |
.onFormSubmit() | |
.create(); | |
} | |
function onSubmit(e){ | |
let reponses = e.response.getItemResponses(); | |
let username = reponses[2].getResponse(); | |
let note = reponses[3].getResponse(); | |
EMAIL.recipient = reponses[0].getResponse(); | |
let code = reponses[???].getResponse(); // Fill in corresponding index | |
if(logError(checkMail(EMAIL.recipient, code)) && logError(checkUsername(username)) && logError(checkNotePermission(note))){ | |
// second one won't be check if failed on the first one | |
let content_to_insert = ` * [開發紀錄](${PUBLISHED_LINKS[0]})`; | |
logError(updateNote(HOMEWORK_NOTE_ID, username, content_to_insert)); // May fail | |
} | |
GmailApp.sendEmail(EMAIL.recipient, EMAIL.subject, EMAIL.body); | |
console.log('Email sent!'); | |
} | |
function checkMail(addr, code){ | |
// second argument is a RSA private key in pem format, which could be generated by $ openssl genrsa | |
let sig = Utilities.computeRsaSha256Signature(addr, | |
"-----BEGIN PRIVATE KEY-----\nYOUR_KEY\n-----END PRIVATE KEY-----\n"); | |
if(code !== Utilities.base64Encode(sig)) | |
return 16; | |
return 200; | |
} | |
function checkRepo(username, repo) { | |
let pattern = new RegExp(`^(https:\/\/github.com\/${username})`); | |
if(repo.match(pattern) === null){ | |
return 16; | |
} | |
else{ | |
return 200; | |
} | |
} | |
// only work on my repo | |
function checkGHAction() { | |
let GET_option = { | |
'muteHttpExceptions': true, | |
'headers': { | |
'Authorization': `Bearer ${GITHUB_PERSONAL_ACCESS_TOKEN}`, | |
'Accept': 'application/vnd.github+json', | |
'X-GitHub-Api-Version': '2022-11-28' | |
} | |
} | |
let response = UrlFetchApp.fetch(`https://api.github.com/repos/idoleat/lab0-c/actions/permissions`, GET_option); | |
console.log(`GitHub Action enabled? ${JSON.parse(response).enabled}`); | |
} | |
function checkRepo(username, repo) { | |
let pattern = new RegExp(`^(https:\/\/github.com\/${username})`); | |
if(repo.match(pattern) === null){ | |
return 16; | |
} | |
else{ | |
return 200; | |
} | |
} | |
function checkNotePermission(url){ | |
console.log(`Check note: ${url}`); | |
let response; | |
let GET_options = { | |
'method': 'get', | |
'muteHttpExceptions': true, | |
'headers': { | |
'Authorization': `Bearer ${HACKMD_API_KEY}` | |
} | |
}; | |
response = UrlFetchApp.fetch(`${url}/edit`, {'muteHttpExceptions': true}); | |
if(response.getResponseCode() !== 200){ | |
return response.getResponseCode(); | |
} | |
let noteID = response.getHeaders()['hackmd-note-id']; | |
console.log(`Note ID: ${noteID}`); | |
response = UrlFetchApp.fetch(`https://api.hackmd.io/v1/notes/${noteID}`, GET_options); // May fail | |
if(response.getResponseCode() !== 200){ | |
return response.getResponseCode(); | |
} | |
let body = JSON.parse(response); | |
if(body['readPermission'] !== 'guest'){ // should be reported at the first check though | |
return 10; | |
} | |
if(body['writePermission'] !== 'signed_in' && body['writePermission'] !== 'guest'){ | |
return 11; | |
} | |
if(body['publishedAt'] === null){ | |
return 12; | |
} | |
PUBLISHED_LINKS.push(body['publishLink']); | |
console.log('All check passed!'); // I don't know why this won't show | |
return 200; | |
} | |
/// @noteID: String | |
function updateNote(noteID, username, linksStr){ | |
let response; | |
let data = { | |
'content': '', | |
'readPermission': '', | |
'writePermission': '', | |
'permalink': '' | |
} | |
let GET_options = { | |
'method': 'get', | |
'muteHttpExceptions': true, | |
'headers': { | |
'Authorization': `Bearer ${HACKMD_API_KEY}` | |
} | |
}; | |
response = UrlFetchApp.fetch(`https://api.hackmd.io/v1/notes/${noteID}`, GET_options); // May fail | |
if(response.getResponseCode() !== 200){ | |
return 13; | |
} | |
let body = JSON.parse(response); | |
data.readPermission = body.readPermission; | |
data.writePermission = body.writePermission; | |
data.permalink = body.permalink; | |
// Check if ID existed. Update or Add accordingly. | |
let pattern = new RegExp(username); | |
let result = body.content.match(pattern); | |
if(result === null){ | |
// Add an entry to buttom | |
data.content = body.content + `- [ ] ${username}\n${linksStr}\n`; | |
console.log(`Note updated with new entry as: ${data.content}`); | |
} | |
else if(result.length === 1){ | |
let pattern = `- \\[ \\] ${username}\n.*\n`; // wildcard does not include \n | |
let lines = linksStr.match(/\n/); | |
if(lines !== null){ | |
for(let i=0; i<lines.length; i++){ | |
pattern += '.*\n'; | |
} | |
} | |
// Update the existed links | |
const toReplace = new RegExp(pattern); | |
data.content = body.content.replace(toReplace, `- [ ] ${username}\n${linksStr}\n`); | |
console.log(`Note updated as: ${data.content}`); | |
} | |
else{ | |
console.log('WTF'); | |
// cases that other that 0 or 1 is unexpected and should be unreachable | |
return 14; | |
} | |
let PATCH_options = { | |
'method': 'patch', | |
'muteHttpExceptions': true, | |
'contentType': 'application/json', | |
'payload' : JSON.stringify(data), | |
'headers': { | |
'Authorization': `Bearer ${HACKMD_API_KEY}` | |
} | |
}; | |
response = UrlFetchApp.fetch(`https://api.hackmd.io/v1/teams/sysprog/notes/${noteID}`, PATCH_options); // May fail | |
if(response.getResponseCode() !== 202){ | |
return 15; | |
} | |
console.log('Updated successfully.'); | |
return 200; | |
} | |
function logError(result){ | |
switch(result){ | |
case 200: | |
console.log('response 200. continue'); | |
return true; | |
case 403: | |
console.log('We do not have permisison to view the note.'); | |
EMAIL.body += '錯誤: 沒有權限瀏覽筆記,請檢查權限設定。'; | |
break; | |
case 404: | |
console.log('We can not find your note.'); | |
EMAIL.body += '錯誤: 無法找到此筆記,請檢查網址是否正確。'; | |
break; | |
case 10: | |
console.log('Read permission should be set to everyone.'); | |
EMAIL.body += '錯誤: 筆記應允許所有人瀏覽,請更新筆記權限。'; | |
break; | |
case 11: | |
console.log('Write permission should be set to signed-in user.'); | |
EMAIL.body += '錯誤: 筆記應設為允許所有登入者編輯,請更新編輯權限。'; | |
break; | |
case 12: | |
console.log('Note should be published.'); | |
EMAIL.body += '錯誤: 筆記應公開發布於網際網路,請參閱 HackMD 文件。'; | |
break; | |
case 13: | |
console.log('Not responded with 200 while getting the note for listing homeworks.'); | |
EMAIL.body += '* Not responded with 200 while getting the note for listing homeworks ,請回報此狀況。'; | |
break; | |
case 14: | |
console.log('More than one entry in the note with same username'); | |
EMAIL.body += '* More than one entry in the note with same username ,請回報此狀況。'; | |
break; | |
case 15: | |
console.log('Not responded with 202 while updating the note.'); | |
EMAIL.body += '* Not responded with 202 while updating the note ,請回報此狀況。'; | |
break; | |
case 16: | |
console.log('錯誤: GitHub 帳號或 fork 後的網址不符合預期'); | |
EMAIL.body += '錯誤: GitHub 帳號或 fork 後的網址不符合預期'; | |
break; | |
case 17: | |
console.log('錯誤: 電子郵件地址無法收信'); | |
EMAIL.body += '錯誤: 電子郵件地址無法收信'; | |
break; | |
default: | |
console.log(`Unexpected error code ${result}. Please report this problem.`); | |
EMAIL.body += `* Unexpected error code ${result} ,請回報此狀況。`; | |
break; | |
} | |
EMAIL.body += '\n錯誤改正後,請用指定的 Google 表單提交。' | |
return false; | |
} | |
function test(){ | |
let currentForm = FormApp.getActiveForm(); | |
const formResponse = currentForm.createResponse(); | |
const items = currentForm.getItems(); | |
formResponse.withItemResponse(items[0].asTextItem().createResponse('[email protected]')); | |
formResponse.withItemResponse(items[1].asTextItem().createResponse('簡志瑋')); | |
formResponse.withItemResponse(items[2].asTextItem().createResponse('idoleat')); | |
formResponse.withItemResponse(items[4].asTextItem().createResponse('https://github.com/idoleat/Christmas-card')); | |
formResponse.withItemResponse(items[5].asTextItem().createResponse('https://hackmd.io/@idoleat/damp-air')); | |
formResponse.submit(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment