Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

notion (new) #143

Merged
merged 57 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
dfce08c
notion connector
sayam-nasir Aug 7, 2024
27988e2
Merge branch 'dev' into notion-MCGA
sayam-nasir Aug 7, 2024
e0c2c50
ListDatabases and NewDatabaseItemTrigger
sayam-nasir Aug 7, 2024
457d787
es-lint1
sayam-nasir Aug 7, 2024
43ebb87
es-lint2
sayam-nasir Aug 7, 2024
41d9a5b
Merge branch 'clientIO:dev' into notion-MCGA
sayam-nasir Aug 8, 2024
99ea41d
commonsfile and UpdatedItem Trigger
sayam-nasir Aug 8, 2024
e3bfc21
Merge branch 'clientIO:dev' into notion-MCGA
sayam-nasir Aug 9, 2024
5cd7938
RetreiveDatabase
sayam-nasir Aug 9, 2024
90e55c5
Merge branch 'clientIO:dev' into notion-MCGA
sayam-nasir Aug 15, 2024
35f5408
Retrieve Database and page
sayam-nasir Aug 15, 2024
e8981eb
removing zip
sayam-nasir Aug 15, 2024
b712dfe
Merge branch 'clientIO:dev' into notion-MCGA
sayam-nasir Aug 20, 2024
9f66232
Merge branch 'clientIO:dev' into notion-MCGA
sayam-nasir Aug 22, 2024
460a29c
updating name of commons file to lib
sayam-nasir Aug 22, 2024
7d36bbd
Merge branch 'clientIO:dev' into notion-MCGA
sayam-nasir Aug 26, 2024
711e716
Updated output ports
sayam-nasir Aug 27, 2024
1b4ff83
Merge branch 'dev' into notion-MCGA
sayam-nasir Aug 27, 2024
f956ce9
remove zip
sayam-nasir Aug 27, 2024
717d52d
Merge branch 'notion-MCGA' of https://github.com/sayam-nasir/appmixer…
sayam-nasir Aug 27, 2024
619376e
Merge branch 'clientIO:dev' into notion-MCGA
sayam-nasir Aug 27, 2024
500ee89
Added Create Page, List Pages
sayam-nasir Aug 27, 2024
4cf99e4
LINT FIXES
sayam-nasir Aug 27, 2024
ed00419
es-lint2
sayam-nasir Aug 27, 2024
e0adc0a
Merge branch 'clientIO:dev' into notion-MCGA
sayam-nasir Aug 29, 2024
d1c9d2c
FindPageByTitle component added
sayam-nasir Aug 29, 2024
1f72a8b
Merge branch 'clientIO:dev' into notion-MCGA
sayam-nasir Sep 2, 2024
f10a28a
Create Database Item
sayam-nasir Sep 2, 2024
492c5eb
Merge branch 'clientIO:dev' into notion-MCGA
sayam-nasir Sep 3, 2024
3cc6a42
updated output port options
sayam-nasir Sep 4, 2024
e4d9167
CreateDatabaseItem
sayam-nasir Sep 6, 2024
0dfb9ba
Merge branch 'clientIO:dev' into notion-MCGA
sayam-nasir Sep 9, 2024
16eda81
Merge branch 'clientIO:dev' into notion-MCGA
sayam-nasir Sep 17, 2024
01a5c96
notion updates to CreateDatabaseItem and CreatPage
sayam-nasir Sep 17, 2024
9072c44
es-lint
sayam-nasir Sep 17, 2024
2ddf8c9
notion-outputs updates
sayam-nasir Sep 18, 2024
9cce54a
Merge branch 'dev' into notion-MCGA
sayam-nasir Sep 18, 2024
0f09161
lint
sayam-nasir Sep 18, 2024
c26db9e
Merge branch 'clientIO:dev' into notion-MCGA
sayam-nasir Sep 20, 2024
d2cc15b
Update Database Item and List Database Items
sayam-nasir Sep 20, 2024
4b46c27
Merge branch 'clientIO:dev' into notion-MCGA
sayam-nasir Sep 20, 2024
547b03d
component.jsons udpates
sayam-nasir Sep 20, 2024
00b8b27
component.json
sayam-nasir Sep 23, 2024
9e391d5
Make API call and Find Database Item
sayam-nasir Sep 23, 2024
7655a0e
Quotas
sayam-nasir Sep 23, 2024
788b827
adding not found port
sayam-nasir Sep 24, 2024
487a5f7
test-flow
sayam-nasir Sep 24, 2024
3b92a46
Merge branch 'clientIO:dev' into notion-MCGA
sayam-nasir Sep 25, 2024
1ced6a0
Adding config file and removing typos
sayam-nasir Sep 25, 2024
6ee7f40
add config refere to aut.js for api version
sayam-nasir Sep 25, 2024
af2e765
es-lint
sayam-nasir Sep 25, 2024
84fbb6e
added api version to lib and removed config.js
sayam-nasir Sep 25, 2024
5cd30c6
Merge branch 'dev' into notion-MCGA
sayam-nasir Sep 26, 2024
c53b958
Merge branch 'clientIO:dev' into notion-MCGA
sayam-nasir Sep 27, 2024
57c26b0
Retrieve renamed to Get
sayam-nasir Sep 27, 2024
7f2776a
test-flow update
sayam-nasir Sep 27, 2024
18f04b9
Merge branch 'dev' into notion-MCGA
sayam-nasir Sep 27, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions src/appmixer/notion/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
'use strict';

const { API_VERSION } = require('./lib');

module.exports = {
type: 'oauth2',

definition: () => {
const apiVersion = API_VERSION; //api version from lib.js;
return {
accountNameFromProfileInfo: 'name',

authUrl: 'https://api.notion.com/v1/oauth/authorize',

requestAccessToken: async (context) => {
const encoded = Buffer.from(`${context.clientId}:${context.clientSecret}`).toString('base64');

const { data } = await context.httpRequest({
url: 'https://api.notion.com/v1/oauth/token',
method: 'POST',
headers: {
Authorization: `Basic ${encoded}`,
'Content-Type': 'application/json'
},
data: {
grant_type: 'authorization_code',
redirect_uri: context.callbackUrl,
code: context.authorizationCode
}
});

return {
accessToken: data['access_token']
};
},

requestProfileInfo: {
method: 'GET',
url: 'https://api.notion.com/v1/users/me',
headers: {
Authorization: 'Bearer {{accessToken}}',
'User-Agent': 'AppMixer',
'Notion-Version': apiVersion
}
},

validateAccessToken: {
method: 'GET',
url: 'https://api.notion.com/v1/users/me',
headers: {
Authorization: 'Bearer {{accessToken}}',
'User-Agent': 'AppMixer',
'Notion-Version': apiVersion
}
}
};
}
};
9 changes: 9 additions & 0 deletions src/appmixer/notion/bundle.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "appmixer.notion",
"version": "1.0.0",
"changelog": {
"1.0.0": [
"Initial release"
]
}
}
287 changes: 287 additions & 0 deletions src/appmixer/notion/core/CreateDatabaseItem/CreateDatabaseItem.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,287 @@
'use strict';

const lib = require('../../lib');

module.exports = {
async receive(context) {
if (context.properties.generateInspector) {
return generateInspector(context);
}

const { databaseId, content } = context.messages.in.content;

const itemData = await formatPropertiesForNotion(context, databaseId, context.messages.in.content);

const requestData = {
parent: { database_id: databaseId },
properties: itemData
};

// Add content if provided
if (content) {
requestData.children = [
{
object: 'block',
type: 'paragraph',
paragraph: {
rich_text: [
{
type: 'text',
text: {
content: content
}
}
]
}
}
];
}

const response = await lib.callEndpoint(context, '/pages', {
method: 'POST',
data: requestData
});

return context.sendJson(response.data, 'out');
}
};

async function generateInspector(context) {
const { databaseId } = context.properties;

const schema = {
type: 'object',
properties: {
databaseId: { type: 'string' },
content: { type: 'string' }
},
required: ['databaseId']
};

let fieldsInputs = {};

if (databaseId) {
const { data: databaseDetails } = await lib.callEndpoint(context, `/databases/${databaseId}`);

fieldsInputs = Object.keys(databaseDetails.properties).reduce((res, propertyName, index) => {
const property = databaseDetails.properties[propertyName];
if (isSupportedPropertyType(property.type)) {
const inputConfig = {
index: index + 2,
type: getInputType(property),
name: propertyName,
label: propertyName,
tooltip: getTooltipText(property),
...(property.type === 'select' || property.type === 'multi_select' || property.type === 'status' ? { options: getSelectOptions(property) } : {})
};

if (property.type === 'people') {
inputConfig.type = 'multiselect';
inputConfig.source = {
url: '/component/appmixer/notion/core/ListUsers?outPort=out',
data: {
transform: './ListUsers#usersToSelectArray'
}
};
inputConfig.mergeVariables = false;
}

res[propertyName] = inputConfig;
}
return res;
}, {});
}

const inputs = {
databaseId: {
label: 'Database ID',
index: 1,
type: 'select',
source: {
url: '/component/appmixer/notion/core/ListDatabases?outPort=out',
data: {
transform: './ListDatabases#databaseToSelectArray'
}
},
tooltip: 'Select the Notion database or insert a Database ID where you want to create a new item.'
},
content: {
label: 'Content',
index: 999, // Ensure this appears last in the form
type: 'text',
tooltip: 'Enter the content for the item.'
},
...fieldsInputs
};

return context.sendJson({ schema, inputs }, 'out');
}

async function formatPropertiesForNotion(context, databaseId, content) {
const { data: databaseDetails } = await lib.callEndpoint(context, `/databases/${databaseId}`);

const formattedProperties = {};

for (const propertyName in databaseDetails.properties) {
if (databaseDetails.properties.hasOwnProperty(propertyName)) {
const property = databaseDetails.properties[propertyName];
const userInput = content[propertyName];

if (userInput !== undefined && userInput !== null) {
formattedProperties[propertyName] = formatProperty(property, userInput);
}
}
}

return formattedProperties;
}

function formatProperty(property, userInput) {
switch (property.type) {
case 'title':
return {
'title': [{ 'text': { 'content': userInput } }]
};
case 'rich_text':
return {
'rich_text': [{ 'text': { 'content': userInput } }]
};
case 'multi_select':
return {
'multi_select': Array.isArray(userInput) ? userInput.map(option => ({ 'name': option })) : [{ 'name': userInput }]
};
case 'select':
return {
'select': { 'name': userInput }
};
case 'status':
return {
'status': { 'name': userInput }
};
case 'people':
return {
'people': Array.isArray(userInput) ? userInput.map(personId => ({ 'id': personId })) : [{ 'id': userInput }]
};
case 'date':
return {
'date': { 'start': userInput }
};
case 'checkbox':
return {
'checkbox': Boolean(userInput)
};
case 'number':
return {
'number': parseFloat(userInput)
};
case 'email':
return {
'email': userInput
};
case 'url':
return {
'url': userInput
};
case 'phone_number':
return {
'phone_number': userInput
};
case 'files':
const files = [];
if (Array.isArray(userInput)) {
for (const fileUrl of userInput) {
files.push({
'name': fileUrl.split('/').pop(),
'external': { 'url': fileUrl.trim() }
});
}
} else {
files.push({
'name': userInput.split('/').pop(),
'external': { 'url': userInput.trim() }
});
}
return { 'files': files };
default:
return {
[property.type]: userInput
};
}
}

function getInputType(property) {
switch (property.type) {
case 'title':
case 'rich_text':
case 'url':
case 'email':
case 'phone_number':
return 'text';
case 'number':
return 'number';
case 'checkbox':
return 'toggle';
case 'date':
return 'date-time';
case 'multi_select':
return 'multiselect';
case 'status':
case 'select':
return 'select';
case 'people':
return 'multiselect';
case 'files':
return 'text';
default:
return 'text';
}
}

function getSelectOptions(property) {
if (property.type === 'select' || property.type === 'multi_select' || property.type === 'status') {
return property[property.type].options.map(option => ({
value: option.name,
content: option.name
}));
}
return [];
}

function getTooltipText(property) {
switch (property.type) {
case 'title':
return 'Enter the title for the item. This is the main heading.';
case 'rich_text':
return 'Enter the text content.';
case 'multi_select':
case 'status':
return 'Select one option from the list';
case 'select':
return 'Select a single option from the dropdown.';
case 'people':
return 'Select people by their user ID. Use the dropdown to search for users.';
case 'date':
return 'Enter a date with or without time.';
case 'checkbox':
return 'Toggle the checkbox on or off.';
case 'number':
return 'Enter a numerical value.';
case 'email':
return 'Enter an email address.';
case 'url':
return 'Enter a URL.';
case 'phone_number':
return 'Enter a phone number.';
case 'files':
return 'Enter URLs for files, separated by commas.';
default:
return `Enter the value for the ${property.name} field.`;
}
}

function isSupportedPropertyType(type) {
return [
'title', 'rich_text', 'multi_select', 'select', 'people', 'date',
'checkbox', 'number', 'email', 'url', 'phone_number', 'files', 'status'
].includes(type);
}
Loading
Loading