{"id":13624751,"url":"https://github.com/rspective/contentful-emails","last_synced_at":"2026-03-01T18:02:32.951Z","repository":{"id":69054922,"uuid":"74612899","full_name":"rspective/contentful-emails","owner":"rspective","description":"A tool for automating content creation for email campaigns, built with Contentful.","archived":false,"fork":false,"pushed_at":"2018-05-19T17:31:27.000Z","size":363,"stargazers_count":54,"open_issues_count":0,"forks_count":2,"subscribers_count":18,"default_branch":"master","last_synced_at":"2025-04-12T03:30:01.675Z","etag":null,"topics":["contentful","email","email-template","gulp","javascript","swig"],"latest_commit_sha":null,"homepage":"https://www.voucherify.io/blog/coding-free-iterating-on-email-content","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rspective.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-11-23T20:48:53.000Z","updated_at":"2025-02-12T19:48:58.000Z","dependencies_parsed_at":null,"dependency_job_id":"fa949e74-2f6e-47cd-b456-92a3e4c13a06","html_url":"https://github.com/rspective/contentful-emails","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rspective/contentful-emails","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rspective%2Fcontentful-emails","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rspective%2Fcontentful-emails/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rspective%2Fcontentful-emails/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rspective%2Fcontentful-emails/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rspective","download_url":"https://codeload.github.com/rspective/contentful-emails/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rspective%2Fcontentful-emails/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29977966,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-01T16:35:47.903Z","status":"ssl_error","status_checked_at":"2026-03-01T16:35:44.899Z","response_time":124,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["contentful","email","email-template","gulp","javascript","swig"],"created_at":"2024-08-01T21:01:45.915Z","updated_at":"2026-03-01T18:02:32.935Z","avatar_url":"https://github.com/rspective.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# Coding-free iterating on email \n\n## License\n\n[MIT](/LICENSE.md)\n\n## Business aspects\n\nBusiness ascepts have been presented in deatils [here](https://www.voucherify.io/blog/2016/12/14/coding-free-iterating-on-email-content).\n\nIn short: it's a sample application using [Contentful](https://www.contentful.com/) SaaS to fastly build a coding-free tool for emails' content management.\n\n**NOTICE**: We are using this in production on daily basis and it works just perfect. It's giving us a possibility to work on Ops emails with almost no need for commiting/deploying, we only do that when there is a breaking change in the layout or new features are going to be released ;)\n\n## Technical aspects\n\n### Configuration\n\nTo setup your integration with Contentful you will have to modify `config/base.js` file. You should change two places:\n\n- Contentful Service (`contentful/draft` and `contentful/published` keys); you should obtains the keys in your Contentful settings.\n- Authorization configuration (`autorization/contentful` key), the value should be sent in Authorization header with Contentful Webhook request, it's configured in Contentful along with the webhook.\n\n**NOTICE**: The config pattern in the app allows you to have multiple configuration files - environment or locale based - but at the beggining you can use it in a simple way:\n\n```js\nvar config = require(\"./../config\").current;\n```\n\n### General Desing\n\n#### Contentful restrictions\n\nThere is a hardcoded value of content type's name that shuld be called `email` so that you have to name you content type in Contentful this way or change it in the code, it's up to you.\n\n#### Email Container Engine\n\nTo use the email container in your system you should do the following:\n\n```js\nvar EmailContainer  = require(\"./../services/email-container\");\nvar emailContainer  = new EmailContainer({ container: \"backup\" });\n```\n\nThe types of container are as follows:\n\n- `backup`, data will be read from previously generated backup file stored as: `contentful-emails-backup.json`\n- `cache`, data will be read from Memory Cached version. Cache is initialized on application start and refreshed when Contentful webhook reach the api endpoint.\n- `contentful`, here you can additonally pass `type` attribute (`published` or `draft`) depends from which source you want to render. In this case data will be read directly from Contentful.\n\nThen to render the file:\n\n```js\nemailContainer.render(util.format(\"welcome\", customer.language), payload)\n    .then((emailEntry) =\u003e {\n        // emailEntry: { body: ... , subject: ..., etc. }\n    });\n```\n\nTo configure mapping between Contentful and available properties please look into `/service/email-container/index.js` file and check the `render` method.\n\n#### Layouts\n\nWe decided to use [Swig](https://github.com/paularmstrong/swig) templating engine, because we had many good experiences with it in the past. For email rendering we use files stored in `front-end/views/emails` folder and you should store there all email related content to easily extend your layouts in the future.\n\nThe variables available during rendering can be configured in the `util/html.js`. As you can notice we have already preapred some basic useful variables and methods.\n\n#### Parser\n\nThe parser class you can find here: `/services/email-container/parser`. It's a place where you can define spacial placehoders and thier transformations so that Content Manager can display dynamic data (undestand as payload used for rendering) inside the content, e.g.:\n\n```\nHi [[customer-name]]\n```\n\nThe list of needed placeholder should be discussed between developers and Content Managers. \n\n#### Cache \u0026 Webhook\n\nThe application provides simple Memory Cache mechanism. When application is started then published data is read from Contentful and stored in the memory. Whenever there is a publish/unpublish done in Contenful the Cache will be updated accordingly by configured webhook or after application is restarted.\n\n### Tasks\n\nIn the project for running maintanance tasks we use [Gulp](http://gulpjs.com/).\n\n#### Backup Contentful\n\nRunning the below command will endup downloading the published versions from Contentful and storing them in the file system: `files/contentful-emails-backup.json`. This file is used by `backup` email container to render the tempaltes.\n\n```js\ngulp contentful-backup\n```\n\n### Run the app\n\nTo run the app simple run the following command: \n\n```js\nnpm install\nnode server.js\n```\n\nThe simply open in your browser: `http://localhost:3000` and then you can see content of your containers:\n\n![Application Overview](/ApplicationOverview.png \"Application Overview\")\n\n## Basic usage\n\n**Developer**: \n\n- setup environment\n- create and maintain layouts\n- prepare new placeholders and partials views\n\n**Content Manager**: \n\n- define entries in Contentful\n- define placeholders for developer (e.g. \"we need a button that allows to confirm registration\")\n- fix typos\n- preapre the content (check always in draft mode how email looks like)\n- publish ready emails so they are avaiaible in production right away\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frspective%2Fcontentful-emails","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frspective%2Fcontentful-emails","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frspective%2Fcontentful-emails/lists"}