-
-
Save henryvoorburg/6b184f64b5683135e7038bf6e546ec56 to your computer and use it in GitHub Desktop.
Demo of importing a CSV file into a Contentful space
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
first name | last name | age | |
---|---|---|---|
Stephen | Sugden | 31 | |
Tom | Reznik | 29 | |
Justin | Thomas | 30 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"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