{"_id":"59365227e16643001bac504d","category":{"_id":"59365227e16643001bac5034","version":"59365226e16643001bac5030","project":"543026235eceb608003fde5f","__v":0,"sync":{"url":"","isSync":false},"reference":false,"createdAt":"2016-09-19T11:41:31.988Z","from_sync":false,"order":3,"slug":"test","title":"Advanced"},"project":"543026235eceb608003fde5f","user":"5736eb0b1a48812200566f0d","parentDoc":null,"version":{"_id":"59365226e16643001bac5030","project":"543026235eceb608003fde5f","__v":1,"createdAt":"2017-06-06T06:56:38.999Z","releaseDate":"2017-06-06T06:56:38.999Z","categories":["59365227e16643001bac5031","59365227e16643001bac5032","59365227e16643001bac5033","59365227e16643001bac5034"],"is_deprecated":false,"is_hidden":false,"is_beta":true,"is_stable":true,"codename":"","version_clean":"1.0.0","version":"1.0.0"},"__v":0,"updates":[],"next":{"pages":[],"description":""},"createdAt":"2017-06-05T12:55:07.330Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":1,"body":"## Scheduling\n\n*[Documentation in progress]*\n\n\n##### Default Adapter\nGhost ships a default adapter for scheduling, which will schedule your posts or newsletters within the process.\nThis adapter is configured by default, so if you start your server the scheduling feature is ready to use.\n\nA disadvantage of the default adapter can be *for you*:\n- if you have a cache in front of your blog, the default adapter is not able to clear a cache entry\n- if your blog is off, scheduling is as well. That's why you maybe want to write custom adapters to communicate with external schedulers\n\n##### Custom adapters\nYou can write your own adapters. \nFor example if you want to use the [Heroku Scheduler](https://elements.heroku.com/addons/scheduler) or your own external logic.\n\n**1. Writing your adapter**\n\n`my-adapter.js`\n\n\n```\nvar util = require('util');\n\n// If this require does not work, then your content folder structure is different\n// So change the require path so that your adapter can import the scheduling base.\nvar SchedulingBase = require('../../core/server/adapters/scheduling/SchedulingBase');\n\nfunction MyAdapter(options) {\n    SchedulingBase.call(this, options);\n}\n\nutil.inherits(MyAdapter, SchedulingBase);\n\n// required functions you need to implement\nMyAdapter.prototype.schedule = function(object) {\n    // when the job should be executed (time is a UTC timestamp)\n    var time = object.time;\n    \n    // the url you need to execute when the time is reached\n    var url = object.url;\n    \n    // the HTTP method you need to use\n    var httpMethod = object.extra.httpMethod;\n};\n\nMyAdapter.prototype.reschedule = function(object) {\n    // see MyAdapter.prototype.schedule\n    \n    // the time when the url was scheduled before (oldTime is a UTC timestamp)\n    var oldTime = object.extra.oldTime;\n};\n\nMyAdapter.prototype.unschedule = function(object) {\n    // see MyAdapter.prototype.schedule\n};\n\n//this function is called on server bootstrap\nMyAdapter.prototype.run = function() {};\n\nmodule.exports = MyAdapter;\n```\n\n**2. Adding your adapter**  \n- copy your adapter to `content/scheduling/`.\n\n**3. Extend your `config`**\n\n```\n\"scheduling\": {\n  \"active\": 'my-adapter'\n}\n```\n    \nIn this example we run Ghost in production, replace production if you run Ghost for example in development mode.\n\n\n##### Publish posts in the past\n\nBy default Ghost disallows publishing posts in the past or in the future to avoid problems/bugs. But in case your scheduling service was down, you can use the `force` flag to publish posts in the past.\n\n```\nif (moment(time).isBefore(moment())) {\n    request[httpMethod](url)\n        .send({ force: true })\n        .end(...)\n}\n```\n\nIf the `httpMethod` is a `GET`, you need to use `query` parameters.","excerpt":"","slug":"using-a-custom-scheduling-module","type":"basic","title":"Using a custom scheduling module"}

Using a custom scheduling module


## Scheduling *[Documentation in progress]* ##### Default Adapter Ghost ships a default adapter for scheduling, which will schedule your posts or newsletters within the process. This adapter is configured by default, so if you start your server the scheduling feature is ready to use. A disadvantage of the default adapter can be *for you*: - if you have a cache in front of your blog, the default adapter is not able to clear a cache entry - if your blog is off, scheduling is as well. That's why you maybe want to write custom adapters to communicate with external schedulers ##### Custom adapters You can write your own adapters. For example if you want to use the [Heroku Scheduler](https://elements.heroku.com/addons/scheduler) or your own external logic. **1. Writing your adapter** `my-adapter.js` ``` var util = require('util'); // If this require does not work, then your content folder structure is different // So change the require path so that your adapter can import the scheduling base. var SchedulingBase = require('../../core/server/adapters/scheduling/SchedulingBase'); function MyAdapter(options) { SchedulingBase.call(this, options); } util.inherits(MyAdapter, SchedulingBase); // required functions you need to implement MyAdapter.prototype.schedule = function(object) { // when the job should be executed (time is a UTC timestamp) var time = object.time; // the url you need to execute when the time is reached var url = object.url; // the HTTP method you need to use var httpMethod = object.extra.httpMethod; }; MyAdapter.prototype.reschedule = function(object) { // see MyAdapter.prototype.schedule // the time when the url was scheduled before (oldTime is a UTC timestamp) var oldTime = object.extra.oldTime; }; MyAdapter.prototype.unschedule = function(object) { // see MyAdapter.prototype.schedule }; //this function is called on server bootstrap MyAdapter.prototype.run = function() {}; module.exports = MyAdapter; ``` **2. Adding your adapter** - copy your adapter to `content/scheduling/`. **3. Extend your `config`** ``` "scheduling": { "active": 'my-adapter' } ``` In this example we run Ghost in production, replace production if you run Ghost for example in development mode. ##### Publish posts in the past By default Ghost disallows publishing posts in the past or in the future to avoid problems/bugs. But in case your scheduling service was down, you can use the `force` flag to publish posts in the past. ``` if (moment(time).isBefore(moment())) { request[httpMethod](url) .send({ force: true }) .end(...) } ``` If the `httpMethod` is a `GET`, you need to use `query` parameters.