Created
January 20, 2024 03:36
-
-
Save idoleat/e02367bbc682a4a89ec204c4869300bf to your computer and use it in GitHub Desktop.
version 3
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 = 'your note id'; | |
let HACKMD_API_KEY = 'your api key'; | |
let EMAIL = { | |
'recipient': '', | |
'subject': 'Thanks for handing in your home work!', | |
'body': '' | |
} | |
let PUBLISHED_LINKS = []; // kind of ugly but it works | |
function setupForm() { | |
let currentForm = FormApp.getActiveForm(); | |
let usernameValidation = FormApp.createTextValidation() // To prevent injection | |
.setHelpText('Please provide a valid usename') | |
.requireTextMatchesPattern('[a-zA-Z0-9\-_]+') | |
.build(); | |
let noteValidation = FormApp.createTextValidation() | |
.setHelpText('Please provide a valid hackmd note link') | |
.requireTextMatchesPattern('https:\/\/hackmd\.io\/[a-zA-Z0-9\-_]+') | |
.build(); | |
let githubValidation = FormApp.createTextValidation() | |
.setHelpText('Please provide a valid github repository link') | |
.requireTextMatchesPattern('https:\/\/github\.com\/[a-zA-Z0-9\-_]+\/\[a-zA-Z0-9\-_]+') | |
.build(); | |
let emailValidation = FormApp.createTextValidation() | |
.setHelpText('Please provide a valid email address') | |
.requireTextIsEmail() | |
.build(); | |
let item = currentForm.addTextItem(); | |
item.setTitle('username'); | |
item.setRequired(true); | |
item.setValidation(usernameValidation); | |
item = currentForm.addTextItem(); | |
item.setTitle('Note link 1'); | |
item.setRequired(true); | |
item.setValidation(noteValidation); | |
item = currentForm.addTextItem(); | |
item.setTitle('GitHub repo'); | |
item.setRequired(true); | |
item.setValidation(githubValidation); | |
item = currentForm.addTextItem(); | |
item.setTitle('Note link 2'); | |
item.setRequired(true); | |
item.setValidation(noteValidation); | |
item = currentForm.addTextItem(); | |
item.setTitle('Email'); | |
item.setRequired(true); | |
item.setValidation(emailValidation); | |
// Optional. Deletes all triggers in the current project. | |
//let triggers = ScriptApp.getProjectTriggers(); // why sometimes get an error on no permission? | |
//for (var i = 0; i < triggers.length; i++) { | |
// ScriptApp.deleteTrigger(triggers[i]); | |
//} | |
ScriptApp.newTrigger('onSubmit') | |
.forForm(currentForm) | |
.onFormSubmit() | |
.create(); | |
} | |
function onSubmit(e){ | |
let reponses = e.response.getItemResponses(); | |
let username = reponses[0].getResponse(); // should be sanitized | |
let note_1 = reponses[1].getResponse(); | |
let repo = reponses[2].getResponse(); | |
let note_2 = reponses[3].getResponse(); | |
EMAIL.recipient = reponses[4].getResponse(); | |
if(logError(checkNotePermission(note_1)) && logError(checkNotePermission(note_2))){ | |
// second one won't be check if failed on the first one | |
let content_to_insert = ` * [開發紀錄](${PUBLISHED_LINKS[0]}) / [GitHub](${repo})\n * [開發紀錄 (Quiz)](${PUBLISHED_LINKS[1]})`; | |
logError(updateNote(HOMEWORK_NOTE_ID, username, content_to_insert)); // May fail | |
} | |
GmailApp.sendEmail(EMAIL.recipient, EMAIL.subject, EMAIL.body); | |
console.log('Email sent!'); | |
} | |
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(`https://api.hackmd.io/v1/notes/${url.substring(18, url.length)}`, 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'){ | |
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 reponse; | |
let data = { | |
'content': '', | |
'readPermission': '', | |
'writePermission': '', | |
'permalink': '' | |
} | |
let GET_options = { | |
'method': 'get', | |
'muteHttpExceptions': true, | |
'headers': { | |
'Authorization': `Bearer ${HACKMD_API_KEY}` | |
} | |
}; | |
reponse = UrlFetchApp.fetch(`https://api.hackmd.io/v1/notes/${noteID}`, GET_options); // May fail | |
if(reponse.getResponseCode() !== 200){ | |
return 13; | |
} | |
let body = JSON.parse(reponse); | |
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){ | |
// Update the existed links | |
const toReplace = new RegExp(`- \\[ \\] ${username}\n.*\n.*\n`); // wildcard does not include \n | |
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}` | |
} | |
}; | |
reponse = UrlFetchApp.fetch(`https://api.hackmd.io/v1/notes/${noteID}`, PATCH_options); // May fail | |
if(reponse.getResponseCode() !== 202){ | |
return 15; | |
} | |
console.log('Updated successfully.'); | |
return 200; | |
} | |
function logError(result){ | |
switch(result){ | |
case 200: | |
console.log('ok. continue'); | |
return true; | |
case 403: | |
console.log('We do not have permisison to view the note.'); | |
EMAIL.body += 'We do not have permisison to view the note.'; | |
break; | |
case 404: | |
console.log('We can not find your note.'); | |
EMAIL.body += 'We can not find your note.'; | |
break; | |
case 10: | |
console.log('Read permission should be set to everyone.'); | |
EMAIL.body += 'Read permission should be set to everyone.'; | |
break; | |
case 11: | |
console.log('Write permission should be set to signed-in user.'); | |
EMAIL.body += 'Write permission should be set to signed-in user.'; | |
break; | |
case 12: | |
console.log('Note should be published.'); | |
EMAIL.body += 'Note should be published.'; | |
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; | |
default: | |
console.log(`Unexpected error code ${result}. Please report this problem.`); | |
EMAIL.body += `Unexpected error code ${result}. Please report this problem.`; | |
} | |
return false; | |
} | |
// Sometimes it won't work, with no error message attached..... | |
function test(){ | |
let currentForm = FormApp.getActiveForm(); | |
const formResponse = currentForm.createResponse(); | |
const items = currentForm.getItems(); | |
formResponse.withItemResponse(items[0].asTextItem().createResponse('superman4')); | |
formResponse.withItemResponse(items[1].asTextItem().createResponse('https://hackmd.io/qEM29uBkQ3C-iXSFdcPa6w')); | |
formResponse.withItemResponse(items[2].asTextItem().createResponse('https://github.com/idoleat/Christmas-card')); | |
formResponse.withItemResponse(items[3].asTextItem().createResponse('https://hackmd.io/qEM29uBkQ3C-iXSFdcPa6w')); | |
formResponse.withItemResponse(items[4].asTextItem().createResponse('[email protected]')); | |
formResponse.submit(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment