Migrating and Documenting Templates for Buildship V2 - verified

Sebastian Avelar →

Verified

BuildShip Developer

Low-Code/No-Code

BuildShip

Firebase

Supabase

BuildShip Developer
Low-Code/No-Code
Web Developer
BuildShip
BuildShip

Project Overview

Migrated and created new Buildship templates that leverage V2 features, including template creation, documentation, and trigger setup.

Role and Responsibilities

Migrated templates from V1 to V2 of Buildship.
Created new templates that integrated with tools like Notion, Supabase, and Firestore.
Documented templates and workflows, including visual assets like GIFs and detailed guides.
Developed and tested Triggers for various integrations.

Key Contributions

Template Creation
Designed workflows showcasing Firestore CRUD operations and other integrations.
Ensured templates were user-friendly and ready for immediate implementation.
2. Documentation Improvements
Created clear, visual instructions using GIFs and concise written steps.
Provided examples for triggers to enhance understanding.
3. Trigger Development
Developed and implemented Notion triggers, with well-structured and reusable code.
Assisted in bug identification and improvements to node instructions.

Documentation Example

Assisted with documentation for various triggers, including writing, GIF creation, and examples:

Template Examples

Read Me Documentation:
Included step-by-step examples, GIFs, and clear instructions for users to understand workflows seamlessly.
Flow Previews:
Visual representations of workflows to help users grasp the logic and structure quickly.
Inline Notes in Templates:
Added contextual notes within templates to provide additional explanations and usage tips.

Code Showcase

Here’s a sample of the Notion Trigger Code implemented for Buildship:
import {Logging} from "@google-cloud/logging";
import parser from "co-body";

// Helper function to convert Notion properties to clean data
const convertNotionProperties = (notionData) => {
const properties = notionData.properties || {};
const data = {
pageID: notionData.id,
};

Object.entries(properties).forEach(([fieldName, prop]) => {
if (prop.type === 'button') return;

switch(prop.type) {
case 'title':
data[fieldName] = prop.title[0]?.plain_text || '';
break;
case 'email':
data[fieldName] = prop.email || '';
break;
case 'select':
data[fieldName] = prop.select?.name || '';
break;
case 'status':
data[fieldName] = prop.status?.name || '';
break;
case 'rich_text':
data[fieldName] = prop.rich_text[0]?.plain_text || '';
break;
case 'number':
data[fieldName] = prop.number || 0;
break;
case 'checkbox':
data[fieldName] = prop.checkbox || false;
break;
case 'multi_select':
data[fieldName] = prop.multi_select?.map(item => item.name).join(', ') || '';
break;
case 'date':
data[fieldName] = prop.date?.start || '';
break;
case 'url':
data[fieldName] = prop.url || '';
break;
case 'phone_number':
data[fieldName] = prop.phone_number || '';
break;
}
});

return data;
};

const getAccessToken = async () => {
const response = await fetch(
"http://metadata/computeMetadata/v1/instance/service-accounts/default/token",
{
headers: { "Metadata-Flavor": "Google" },
}
);

if (!response.ok) {
throw new Error(`Failed to obtain access token: ${response.statusText}`);
}

const data = await response.json();
return data.access_token;
};

const fetchLogEntries = async (triggerId, retries = 3, delay = 1000) => {
const projectId = process.env.GCLOUD_PROJECT;
const accessToken = await getAccessToken();

const filter = `logName="projects/${projectId}/logs/buildship-node-io" AND jsonPayload.nId="${triggerId}"`;

const requestBody = {
resourceNames: [`projects/${projectId}`],
filter: filter,
pageSize: 1,
orderBy: "timestamp desc",
};

for (let attempt = 1; attempt <= retries; attempt++) {
try {
const response = await fetch(
"https://logging.googleapis.com/v2/entries:list",
{
method: "POST",
headers: {
Authorization: `Bearer ${accessToken}`,
"Content-Type": "application/json",
},
body: JSON.stringify(requestBody),
}
);

if (!response.ok) {
const errorText = await response.text();
throw new Error(
`Error fetching log entries: ${response.statusText} - ${errorText}`
);
}

const data = await response.json();
const entries = data.entries || [];

if (entries.length > 0) {
return entries;
}

if (attempt < retries) {
await new Promise((resolve) => setTimeout(resolve, delay));
}
} catch (error) {
console.error(`Attempt ${attempt} failed due to an error:`, error);
if (attempt < retries) {
await new Promise((resolve) => setTimeout(resolve, delay));
} else {
throw new Error(
`Failed to get data after ${retries} attempts.`
);
}
}
}

throw new Error("No data found. Send a request to the API and try again.");
};

const getData = async (inputs, { trigger, workflow }) => {
try {
const entries = await fetchLogEntries(trigger.id, 5, 2000);

if (entries.length > 0 && entries[0].jsonPayload && entries[0].jsonPayload.o) {
return {
success: true,
message: "",
data: entries[0].jsonPayload.o
};
}

return {
success: false,
message: "No valid log entry found",
data: null
};
} catch (err) {
return {
success: false,
message: err?.message,
data: null
};
}
};

const onExecution = async ({ _ }, { req, logging, env, nodeReq, auth }) => {
try {
const webhookData = await parser.json(nodeReq);


const pageData = webhookData?.data
if (!pageData) {
throw new Error("No page data found in the webhook payload");
}


const processedData = convertNotionProperties(pageData);
return processedData;

} catch (error) {
console.error('Notion Trigger Error:', error);
throw error;
}
};



// Export the required functions
export default { onExecution, getData };
Like this project
0

The project focused on migrating and creating new templates for Buildship V2, leveraging its enhanced features for improved workflows.

Likes

0

Views

1

Timeline

Oct 28, 2024 - Dec 10, 2024

Clients

BuildShip

Tags

BuildShip Developer

Low-Code/No-Code

BuildShip

Firebase

Supabase

Sebastian Avelar →

Web Developer for Low-Code Projects (Buildship & Bubble)

How to 'chat' with your database using Buildship and OpenAi
How to 'chat' with your database using Buildship and OpenAi
Chat Based Pokemon AI Team Builder
Chat Based Pokemon AI Team Builder
Contra 3D Buinsess Card
Contra 3D Buinsess Card
#06 - allpokemon.info | Ai-Team builder |
#06 - allpokemon.info | Ai-Team builder |