-
-
Save astoiccoder/77577ea58eaf2a9b91cee8ca78c0a6f0 to your computer and use it in GitHub Desktop.
const GMAIL_LABEL_NAME = 'NotionToSync'; | |
const SYNCED_LABEL = 'SyncedToNotion'; | |
// if you set this, the attachments will be copied over to google drive and the links added to the notion page | |
const GDRIVE_FOLDER_ID = ''; | |
const gmailToNotion = () => { | |
const label = GmailApp.getUserLabelByName(GMAIL_LABEL_NAME); | |
const successLabel = GmailApp.getUserLabelByName(SYNCED_LABEL); | |
label.getThreads(0, 20).forEach((thread) => { | |
const [message] = thread.getMessages().reverse(); | |
postToNotion(message); | |
thread.removeLabel(label); | |
thread.addLabel(successLabel) | |
}); | |
}; | |
function getRichTextChunks(messageBody) { | |
let remainingString = messageBody; | |
const content = []; | |
while (remainingString.length > 0) { | |
// https://developers.notion.com/reference/request-limits#limits-for-property-values | |
if (remainingString.length <= 2000) { | |
content.push(getRichTextObjectForChunk(remainingString)); | |
remainingString = ''; | |
} else { | |
const maximalChunk = remainingString.substring(0, 2000); | |
const lastLineBreakInChunk = maximalChunk.lastIndexOf('\n'); | |
const actualChunk = remainingString.substring(0, lastLineBreakInChunk); | |
content.push(getRichTextObjectForChunk(actualChunk)); | |
remainingString = remainingString.substring(lastLineBreakInChunk + 1); | |
} | |
} | |
return content; | |
} | |
function getRichTextObjectForChunk(messageChunk) { | |
return { | |
type: 'text', | |
text: { | |
content: messageChunk | |
}, | |
} | |
} | |
function getPdfBlocksForAttachments(message) { | |
var attachments = message.getAttachments(); | |
var pdfBlocks = []; | |
for (var k = 0; k < attachments.length; k++) { | |
Logger.log('Message contains the attachment "%s" (%s bytes)', attachments[k].getName(), attachments[k].getSize()); | |
var folder = DriveApp.getFolderById(GDRIVE_FOLDER_ID); | |
var ts = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "yyMMddHHmmss"); | |
var createdFile = folder.createFile(attachments[k].copyBlob()).setName(attachments[k].getName() + ts); | |
pdfBlocks.push({ | |
"object": "block", | |
"type": "paragraph", | |
"paragraph": { | |
"rich_text": [ | |
{ | |
"type": "text", | |
"text": { | |
"content": attachments[k].getName(), | |
"link": { | |
"url": createdFile.getUrl() | |
} | |
}, | |
"annotations": { | |
"bold": false, | |
"italic": false, | |
"strikethrough": false, | |
"underline": false, | |
"code": false, | |
"color": "default" | |
}, | |
"plain_text": attachments[k].getName(), | |
"href": createdFile.getUrl() | |
} | |
], | |
"color": "default" | |
} | |
}) | |
} | |
} | |
function postToNotion(message) { | |
const richTextChunks = getRichTextChunks(message.getPlainBody()); | |
const pdfBlocks = GDRIVE_FOLDER_ID ? getPdfBlocksForAttachments(message) : []; | |
const url = 'https://api.notion.com/v1/pages'; | |
const body = { | |
parent: { | |
type: "database_id", | |
database_id: "<Your Target Notion Database Id>", | |
}, | |
icon: { | |
type: "emoji", | |
emoji: "📝" | |
}, | |
children: [ | |
...pdfBlocks, | |
{ | |
object: 'block', | |
type: 'paragraph', | |
paragraph: { | |
rich_text: richTextChunks, | |
}, | |
} | |
], | |
properties: { | |
Name: { | |
title: [ | |
{ | |
text: { | |
content: message.getSubject(), | |
}, | |
}, | |
], | |
} | |
} | |
} | |
UrlFetchApp.fetch(url, { | |
method: 'post', | |
contentType: "application/json", | |
muteHttpExceptions: false, | |
headers: { | |
Authorization: `Bearer <Your Notion Secret>`, | |
'Notion-Version': '2022-02-22' | |
}, | |
payload: JSON.stringify(body) | |
}); | |
} |
Thanks for doing this @astoiccoder! I love notion and recently gotten my hands on Remarkable. Two truly amazing tools which will be even better if integrated OOTB.
Thanks for building this integration!
Using the latest code, I face a slightly different error.
"Exception: Request failed for https://api.notion.com returned code 400. Truncated server response: {"object":"error","status":400,"code":"validation_error","message":"body failed validation. Fix one:\nbody.parent.page_id should be defined, instea... (use muteHttpExceptions option to examine full response)"
Upon looking into this link "ramnes/notion-sdk-py#72", it seems like property values of the new page in the properties parameter must conform to the parent database's property schema. Any suggestion how to do this?
Thanks in advanced!
Exception: Request failed for https://api.notion.com/ returned code 400. Truncated server response: {"object":"error","status":400,"code":"validation_error","message":"body failed validation. Fix one:\nbody.parent.page_id should be defined, instea... (use muteHttpExceptions option to examine full response)
hello! i'm struggling with this right now,
Exception: Request failed for https://api.notion.com returned code 401. Truncated server response: {"object":"error","status":401,"code":"unauthorized","message":"API token is invalid.","request_id":
getting the above response. nothing shows up in the database. i use convert to text and when emailing "text to email"