Skip to content

Instantly share code, notes, and snippets.

@Monichre
Forked from grncdr/data.csv
Created May 8, 2020 04:18
Show Gist options
  • Save Monichre/b7d546ff38c7e84b218ae026c917dc41 to your computer and use it in GitHub Desktop.
Save Monichre/b7d546ff38c7e84b218ae026c917dc41 to your computer and use it in GitHub Desktop.
Demo of importing a CSV file into a Contentful space
first name last name age
Stephen Sugden 31
Tom Reznik 29
Justin Thomas 30
#!/usr/bin/env babel-node --stage=0
import fs from 'fs';
import contentful from 'contentful-management';
import Parser from 'csv-parse';
import prat from 'prat';
const client = contentful.createClient({
/**
* Your Management API token. Get one quickly at
* contentful.com/developers/documentation/content-management-api
* then set it as an environment variable like
*
* export CONTENTFUL_CMA_TOKEN="abcdef123457890"
*/
accessToken: process.env.CONTENTFUL_CMA_TOKEN,
});
/**
* The Content Type ID that matches the rows from the CSV you want to import
*/
const contentTypeId = '5aL1iEoPWE44KAcwUOw8M6';
async function main () {
const space = await client.getSpace('n65xuot4ik7f');
const parser = new Parser({columns: true});
const rows = fs.createReadStream('./data.csv').pipe(parser);
const entries = await prat.ify(rows)
.map((row) => rowToEntry(space, row))
.reduce([], (entries, entry) => entries.concat(entry));
console.log('entries', entries)
}
/**
* Finds an entry and updates it, or creates a new entry if no existing entry is found.
*
* The update logic simply overwrites the existing fields, a deep merge would
* be a better strategy if the entries also have fields that are edited by humans.
*/
async function rowToEntry (space, row) {
const id = `${row['first name']}.${row['last name']}`;
const sys = { id };
const fields = rowToFields(row);
try {
const entry = await space.getEntry(id)
entry.fields = fields;
console.log('Update', id);
return await space.updateEntry(entry);
} catch (_) {
console.log('Create', id);
return await space.createEntry(contentTypeId, { sys, fields });
}
}
/**
* This helper maps a CSV row to the contentful fields structure.
* Currently it's hard-coded to use en-US, but expanding this script to support
* multiple locales (maybe by importing different files) would be trivial.
*/
function rowToFields (row) {
return {
firstName: { 'en-US': row['first name'] },
lastName: { 'en-US': row['last name'] },
age: { 'en-US': parseInt(row['age'], 10) }
};
}
main().catch((err) => {
console.error(err.stack);
process.exit(1);
});
{
"name": "example-contentful-csv-import",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Tests? maybe next time ;)\" && exit 1",
"import": "babel-node --stage=0 index.js"
},
"author": "Stephen Sugden",
"license": "MIT",
"dependencies": {
"babel": "^5.5.8",
"contentful-management": "^0.1.1",
"csv": "^0.4.5",
"prat": "^1.1.0"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment