When importing external data into Bika’s database, many users initially attempt Automation workflows combining “Send Http Request” actions with Loop + Create Record actions. While this approach works for simple data transfers, it reveals limitations when you need to:
- Clean raw data from external sources
- Transform formats (e.g., date normalization to ISO 8601)
- Implement complex business logic
- Handle API error cascading
This guide provides a script that shows you how the Run Script action empowers you to handle ETL (Extract, Transform, Load) operations through customizable scripting.
Example Script
You can copy the code snippet below and paste it into Run Script action.
// Variable declarations and assignments
const SPACE_ID = '{Your_space_id}';
const DATABASE_ID = '{Your_database_id}';
const API_KEY = '{Your_API_key}';
const BIKA_API_URL = 'https://bika.ai/api/openapi/bika/v1/spaces/' + SPACE_ID + '/resources/databases/' + DATABASE_ID + '/records/batch';
const BATCH_SIZE = 20; // API can create maximum 20 records per call
// Main function
async function main() {
// 1. Fetch data from third-party platform
const thirdPartyData = await fetchThirdPartyData();
// 2. Process and transform data
const processedRecords = processData(thirdPartyData.data);
// 3. Create records in batches
await createRecordsBatch(processedRecords);
return {
status: 'success',
message: 'All records created successfully!',
totalRecords: processedRecords.length
}
}
// Fetch data from third-party platform
async function fetchThirdPartyData() {
// Simulate fetching data from a third-party platform
return {
data: [
{ name: 'Store A', manager: 'john doe', performance: 'good', date: '2025-10-01' },
{ name: 'Store B', manager: 'jane smith', performance: 'average', date: '2025-10-02'},
{ name: 'Store C', manager: '', performance: 'poor', date: '2025-10-03'}
]
};
}
// Data processing function
function processData(rawDataArray) {
return rawDataArray.map((item, index) => {
// Process string data
const storeName = item.name ? item.name.trim() : `Store ${index + 1}`;
const managerName = item.manager || 'Unknown Manager';
// Build record structure required by API
return {
"Date": item.date ? new Date(item.date).toISOString() : new Date().toISOString(),
"Store Name": storeName,
"Manager": managerName,
};
});
}
// Create records in batches
async function createRecordsBatch(records) {
const totalBatches = Math.ceil(records.length / BATCH_SIZE);
for (let i = 0; i < totalBatches; i++) {
const startIndex = i * BATCH_SIZE;
const endIndex = Math.min(startIndex + BATCH_SIZE, records.length);
const batch = records.slice(startIndex, endIndex);
await createRecords(batch);
// Add delay to avoid frequent requests
if (i < totalBatches - 1) {
await sleep(1000);
}
}
}
// Call API to create records
async function createRecords(recordsBatch) {
const requestBody = {
cells: recordsBatch
};
const response = await fetch(BIKA_API_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + API_KEY
},
body: JSON.stringify(requestBody)
});
if (!response.ok) {
throw new Error('API request failed:' + response.statusText);
}
const result = await response.json();
return result;
}
// Helper function: sleep
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// Execute main function
main();
Key Advantages Over Basic Automation
Loop + Create Record | Run Script | |
---|---|---|
Transaction Control | Per-record commits | Atomic batch commit |
Error Handling | Basic | Customizable |
Data Validation | Field-level | Cross-field logic |
Performance | Slow | Fast |
Debug Visibility | Limited | Customizable |
Recommended Usage Scenarios
- Migrating legacy systems with irregular data formats
- Implementing field value dependencies during import
- Enforcing complex business rules pre-insertion
- Handling GDPR-compliant data anonymization
I hope this sample script proves helpful to you.