|
const linearKey = "<LINEAR_KEY>"; |
|
function Initialize() { |
|
const triggers = ScriptApp.getProjectTriggers(); |
|
|
|
for (var i in triggers) { |
|
ScriptApp.deleteTrigger(triggers[i]); |
|
} |
|
|
|
ScriptApp.newTrigger("FileLinearIssue") |
|
.forSpreadsheet(SpreadsheetApp.getActiveSpreadsheet()) |
|
.onFormSubmit() |
|
.create(); |
|
} |
|
|
|
const questions = { |
|
TIMESTAMP: 0, |
|
EMAIL_ADDRESS: 1, |
|
TITLE: 2, |
|
STEPS_TO_REPRODUCE: 3, |
|
EXPECTED_RESULTS: 4, |
|
ACTUAL_RESULTS: 5, |
|
SCREENSHOTS: 6, |
|
}; |
|
|
|
function FileLinearIssue(e) { |
|
const s = SpreadsheetApp.getActiveSheet(); |
|
const formResponse = s |
|
.getRange(s.getLastRow(), 1, 1, s.getLastColumn()) |
|
.getValues()[0]; |
|
const screenshots = formResponse[questions.SCREENSHOTS].split(","); |
|
const assetUrls = []; |
|
for (let idx = 0; idx < screenshots.length; idx++) { |
|
const screenshotBlob = DriveApp.getFileById( |
|
screenshots[idx].split("id=")[1] |
|
).getBlob(); |
|
const screenshotBytes = screenshotBlob.getBytes(); |
|
const size = screenshotBytes.length; |
|
const responseJson = UrlFetchApp.fetch("https://api.linear.app/graphql", { |
|
contentType: "application/json", |
|
method: "post", |
|
headers: { Authorization: linearKey }, |
|
muteHttpExceptions: true, |
|
payload: JSON.stringify({ |
|
query: `mutation { |
|
fileUpload( |
|
filename: "${screenshotBlob.getName()}", |
|
contentType: "${screenshotBlob.getContentType()}", |
|
size: ${size} |
|
) { |
|
success |
|
uploadFile { |
|
uploadUrl, |
|
headers { |
|
key, |
|
value |
|
}, |
|
assetUrl |
|
} |
|
} |
|
} |
|
`, |
|
}), |
|
}); |
|
const response = JSON.parse(responseJson); |
|
const header = response.data.fileUpload.uploadFile.headers[0]; |
|
const imageUploadResponse = UrlFetchApp.fetch( |
|
response.data.fileUpload.uploadFile.uploadUrl, |
|
{ |
|
method: "PUT", |
|
headers: { |
|
[header.key]: header.value, |
|
"cache-control": "max-age=31536000", |
|
}, |
|
contentLength: size, |
|
contentType: screenshotBlob.getContentType(), |
|
payload: screenshotBytes, |
|
muteHttpExceptions: true, |
|
} |
|
); |
|
assetUrls.push(response.data.fileUpload.uploadFile.assetUrl); |
|
} |
|
|
|
const assets = assetUrls |
|
.map((assetUrl) => `})`) |
|
.join("\n"); |
|
const response = UrlFetchApp.fetch("https://api.linear.app/graphql", { |
|
contentType: "application/json", |
|
method: "post", |
|
headers: { Authorization: linearKey }, |
|
muteHttpExceptions: true, |
|
payload: JSON.stringify({ |
|
query: `mutation { |
|
issueCreate( |
|
input: { |
|
title: "${formResponse[questions.TITLE]}" |
|
projectId: "<REPORTED_BUG_PROJECT_ID>" |
|
labelIds: ["<BUG_LABEL_ID>", "<NEEDS_TRIAGE_LABEL_ID>"] |
|
description: """ |
|
### Steps to Reproduce |
|
${formResponse[questions.STEPS_TO_REPRODUCE]} |
|
|
|
### Expected Result |
|
${formResponse[questions.EXPECTED_RESULTS]} |
|
|
|
### Actual Result |
|
${formResponse[questions.ACTUAL_RESULTS]} |
|
|
|
${assets} |
|
""" |
|
teamId: "<TEAM_ID>" |
|
} |
|
) { |
|
success |
|
issue { |
|
id |
|
} |
|
} |
|
} |
|
`, |
|
}), |
|
}); |
|
Logger.log(response); |
|
} |