In this example, we will explain how to Import CSV data into your project.
Here's a sample of the CSV table we will use in this project
id | title | text |
c0f99460-68f0-47a7-b26d-88230987a885 | Just an example | "<h1>HTML Ipsum Presents</h1><p><strong>Pellentesque habitant morbi tristique</strong> senectus et netus.</p><pre><code>npm install react</code></pre>" |
af7c1fe6-d669-414e-b066-e9733f0de7a8 | Another example | "<h1>Another HTML Ipsum Presents</h1><p><strong>Lorem ipsum dolor sit</strong> amet, consectetur adipiscing elit.</p>" |
This is the final code of this example: https://github.com/caisy-io/data-import-example
Install @caisy/sdk
and get your personal access token ready
const sdk = initSdk({
token: "<YOUR_PERONSAL_ACCESS_TOKEN>",
endpoint: "https://cloud.caisy.io/caisy/graphql"
});
Check the docs for Internal API and Personal Access Token
The next step is to get blueprint details so we can extract the fields and create content
const getBlueprintDetails = async () => {
// Blueprint can be fetched by its ID using GetBlueprintById
const blueprintResponse = await sdk.GetBlueprintByName({
input: { blueprintName: "Article", projectId: "<CAISY_PROJECT_ID>" },
});
return blueprintResponse?.GetBlueprintByName?.blueprint;
};
You can get Blueprint Name
from API field in Blueprint settings menu
You can get BLUEPRINT ID
from any created content with the same blueprint
const fieldNamesToImport = ["title", "text"];
const validateBlueprintAndFields = async (blueprint) => {
if (!blueprint) {
throw new Error(
"Blueprint not found. Please ensure a blueprint named 'Article' exists with the fields 'title' and 'text'."
);
}
// blueprint.groups?.[0]?.fields return blueprint fields as Array
const fields = blueprint.groups?.[0]?.fields?.filter(
(field) => field?.name && fieldNamesToImport.includes(field.name)
);
if (!fields || fields.length !== fieldNamesToImport.length) {
throw new Error(
"The blueprint lacks the requisite fields. Ensure the existence of a 'BlogPost' blueprint with 'title' and 'text' fields."
);
}
return fields;
};
Once the blueprint and its fields are validated, the next phase involves parsing and preparing the CSV data file:
In the following snippet, we will use csvtojson package but if you intend to build a UI extension for non-technical users you can use react-csv-importer
const readAndParseData = async () => {
const importData = await csvtojson().fromFile("<PATH_TO_YOUR_FILE>");
return importData.map((item) => ({
...item,
text: item.text && parseHTMLToJSON(item.text)
}));
};
At this step, we transform the CSV data into Caisy Document fields format, in the snippet we add type casting so it helps with typescript auto-completion
const dataRowsToCaisyDocument = ({
importDataParsed,
blueprint,
blueprintFields,
}) => {
return {
input: {
projectId: projectId,
// Iterate over CSV data to create Caisy document inputs
documentInputs: importDataParsed.map((rowData) => {
return {
documentId: rowData.id,
title: rowData.title,
statusId: 2,
blueprintId: blueprint?.blueprintId,
// Map CSV columns to corresponding blueprint fields
fields: Object.keys(rowData)
.map((key) => {
const value = rowData[key];
const matchingField = blueprintFields.find(
(field) => field?.name === key
);
return {
blueprintFieldId: matchingField?.blueprintFieldId,
data: value,
} as DocumentFieldInput;
})
.filter((field) => !!field?.blueprintFieldId),
} as DocumentWithFieldsInput;
}),
},
};
};
Putting all documents at once
The final step involves the actual uploading of data to the Caisy project:
(async () => {
const importDataParsed = await readAndParseData();
const blueprint = await getBlueprintDetails();
const fields = await validateBlueprintAndFields(blueprint);
// Construct input data for PutManyDocuments method
const documentsInput = dataRowToCaisyDocument({importDataParsed, blueprint, blueprintFields: fields});
// Execute the sdk.PutManyDocuments method
const upsertResult = await sdk.PutManyDocuments(documentsInput);
// Handle successful imports
if (upsertResult?.PutManyDocuments?.successfulDocumentIds?.length) {
console.info(
`Successfully imported ${upsertResult.PutManyDocuments.successfulDocumentIds.length} documents.`
);
}
// Handle errors
if (upsertResult?.PutManyDocuments?.errors?.length) {
console.error(
"Errors occurred during the import process: ",
upsertResult.PutManyDocuments.errors
);
}
})();
Putting Documents individually
In the above example, we have shown How to create all documents at once because it's the most performant method if you want to create documents one by one you could use sdk.CreateDocument
then getting the documentId
from CreateDoucment response:
const documentId = createDocument?.CreateDocument?.document?.documentId;
Then iterating over Blueprint fields to update the fields
for (let field of bluePrintFields) {
await sdk.UpdateDocumentField({
input: {
projectId: "<CAISY_PROJECT_ID>",
documentId: documentId,
blueprintFieldId: field?.blueprintFieldId,
data: "Hello World",
},
});
}
By following the steps outlined above, you can now leverage the internal API of Caisy to upload data efficiently. 😉