Hi I was wondering If anyone got examples of using Cron Schedule functions on Strapi: https://strapi.io/documentation/3.x.x/configurations/configurations.html#functions
like sending email, accessing the strapi config, etc.
'*/1 * * * *': async() => {
console.log("I am running " + new Date(), Object.keys(strapi.config));
await strapi.services.article.publish();
}
In your-project/config/functions/cron.js. you can add as many functions in the above format.
The function name in itself is a cron expression which is parsed by strapi to execute at frequent intervals. There are many online tools that will tell you the cron expression that you want to create.
The above function runs every 1 minute, by which I am publishing a content type by using strapi.services. i.e. in file your-project/api/article/services/Article.js
I have written a service layer method that at the moment is publishing an article.
Similarly, you can send an email from your email content type or any utility file that you have made to trigger an email.
For accessing strapi config use: strapi.config object instead of strapi.services
Some example of CRON jobs for Strapi
add this line server.js
...
port: env.int('PORT', 1337),
cron :{
enabled: true
},
admin:
...
cron.js some examples
module.exports = {
/**
* Simple examples.
*/
'*/5 * * * * *': () => {
console.log("🚀 ~ file: cron.js ~ executing action ~Every 5sec");
},
'*/10 * * * * *': () => {
console.log("🚀 ~ file: cron.js ~ executing action ~Every 10sec");
},
'* */5 * * * *': () => {
console.log("🚀 ~ file: cron.js ~ executing action ~Every 5min");
},
'* * */5 * * *': () => {
console.log("🚀 ~ file: cron.js ~ executing action ~Every 5hour");
},
};
Strapi 3 has cron jobs turned off by default. Make sure you turn them on first :)
You also don't need to do */1 for every minute in a cron job, just *, as * means every, and it only checks once a minute.
My requirement was to fetch data from an external MSSQL DB (master data) hosted under RDS (AWS) and update the strapi product catolog (mongodb) every minute.
I've created a custom "cron" folder under "root" to keep all my custom modules in order keep a clean "cron.js".
Under "cron.js" i've simply imported my custom module to call the external module:
const fwSync = require('../../cron/dataSync');
If you want to call multiple cron jobs
import firstCronJob from '../src/plugins/first-cron-job';
import secondCronJob from '../src/plugins/second-cron-job';
export default ({ env }) => ({
host: env('HOST', '0.0.0.0'),
port: env.int('PORT', 1337),
app: {
keys: env.array('APP_KEYS'),
},
cron: {
enabled: true,
tasks: {
...firstCronJob,
...secondCronJob,
},
},
});
Related
I created a cron job and use Strapi custom service that I wrote. But an error comes as: TypeError: Cannot read property 'services' of undefined at Job.1 * * * * * [as job] .
Here is my cron job code:
module.exports = {
'1 * * * * *': ({ strapi }) => {
strapi.services.account.myService();
},
};
I'm using strapi version 3.6.8.
The answer to this question is simple. You're using the syntax from StrapiV4 in StrapiV3. The correct syntax for cronjob in strapiv3 is as follows:
module.exports = {
/**
* Simple example.
* Every monday at 1am.
*/
'0 0 1 * * 1': () => {
// you can then reference you strapi custom service like so
await strapi.services.account.myServiceMethod();
},
};
References
Cron Jobs in Strapi V4
Cron Job in Strapi V3
I would like to change the implementation shown below to using a command line script in a node.js application. How do I do it?
var cron = require('node-cron');
cron.schedule('* * * * *', () => {
getBananas();
});
Gatsby has documentation on how to setup a preview server here
Problem is it requires a server running 24/7 listening to requests, I would like to achieve the same result but in a serverless setup (AWS Lambda to be more specific) since we would need a preview very rarely.
The context here is using Gatsby with Wordpress as a headless data backend, and I want to implement a custom preview link in Wordpress for previewing posts before publishing them.
So far, there are two main setbacks :
Size, currently the size of node_modules for a Gatsby starter with Wordpress is 570mb
Speed, stateless means every preview request would be running gatsby develop again
I honestly don't know a solution for size here, not sure how to strip down packages.
As for speed, maybe there's a low level Gatsby API function to directly render a page to HTML? For example, a Node.js Lambda code could look like this (buildPageHTML is a hypothetical function I'm trying to find)
import buildPageHTML from "gatsby"
exports.handler = async function(event) {
const postID = event.queryStringParameters.postID
return buildPageHTML(`/preview_post_by_id/${postID}`)
}
Any ideas on how to go on about this?
Running Gatsby in an AWS Lambda
Try this lamba (from this beautiful tutorial) :
import { Context } from 'aws-lambda';
import { link } from 'linkfs';
import mock from 'mock-require';
import fs from 'fs';
import { tmpdir } from 'os';
import { runtimeRequire } from '#/utility/runtimeRequire.utility';
import { deployFiles } from '#/utility/deployFiles.utility';
/* -----------------------------------
*
* Variables
*
* -------------------------------- */
const tmpDir = tmpdir();
/* -----------------------------------
*
* Gatsby
*
* -------------------------------- */
function invokeGatsby(context: Context) {
const gatsby = runtimeRequire('gatsby/dist/commands/build');
gatsby({
directory: __dirname,
verbose: false,
browserslist: ['>0.25%', 'not dead'],
sitePackageJson: runtimeRequire('./package.json'),
})
.then(deployFiles)
.then(context.succeed)
.catch(context.fail);
}
/* -----------------------------------
*
* Output
*
* -------------------------------- */
function rewriteFs() {
const linkedFs = link(fs, [
[`${__dirname}/.cache`, `${tmpDir}/.cache`],
[`${__dirname}/public`, `${tmpDir}/public`],
]);
linkedFs.ReadStream = fs.ReadStream;
linkedFs.WriteStream = fs.WriteStream;
mock('fs', linkedFs);
}
/* -----------------------------------
*
* Handler
*
* -------------------------------- */
exports.handler = (event: any, context: Context) => {
rewriteFs();
invokeGatsby(context);
};
find the source here
I am using a node package(sitemap-generator) to create a sitemap.xml file for my angular website,
At the moment I am running this code manually on my machine then uploading the generated file each time.
Is there any way I can automate this process, maybe by uploading the code and running it periodically and automatically
You can use node-scehdule module to run sitemap generator everyday at a specific time , you can set time according to your requirement
const SitemapGenerator = require('sitemap-generator');
const cron = require('node-schedule');
const generator = SitemapGenerator('https://examaple.com', {
maxDepth: 0,
filepath: '/var/www/example.com/sitemap.xml',
maxEntriesPerFile: 50000,
stripQuerystring: true,
lastMod:true
});
cron.schedule('0 22 * * *', () => {
console.log("will run at 10:00 PM everyday");
generator.start();
});
Context:
I'm trying to build a few slack hooks / notification services for a channel I'm active on, being the cheap-skate finance savvy person that I am, I'd like to make use of a free service as such (trail Heroku accounts, or similar products), thus I'd like to be able to run multiple services on a single instance.
I've created a generic runner, that should be based on a config and be able to pick up some node modules and supply them the config settings.
I'm using the following node_modules:
"auto-loader": "^0.2.0",
"node-cron": "^1.2.0",
"read-yaml": "^1.1.0"
config.yml
foo:
cron: 1 * * * *
url: http://www.foo.com
team:
-
slackId: bar
bnetId: 1
eloId: 1
-
slackId: baz
bnetId: 2
eloId: 2
app.js
const autoLoader = require('auto-loader');
const readYaml = require('read-yaml');
const cron = require('node-cron');
const services = autoLoader.load(__dirname +'/services')
readYaml('config.yml', function(err, conf) {
if (err) throw err;
Object.keys(conf).forEach(function (key) {
console.log('Creating CRON for ' + key);
if(cron.validate(conf[key].cron)) {
console.log(conf[key].cron, '-> is valid cron');
// the cron task below does not seem to fire ever
cron.schedule(conf[key].cron, function(){
services[key](conf[key]);
});
} else {
console.log('Cron invalid for::' + key)
}
});
});
service/foo.js
module.exports = function (config) {
console.log('foo entered!!');
console.log(config)
}
Question:
What am I missing? If I remove the cron schedule, my services get hit, thus my assumptions are as follows...
Either I'm missing something conceptually about how long running process are meant to work in NodeJS (as this is my first), or I'm missing a super (not obvious) to me bug.
How do you create a long running task/process in NodeJS with separate scheduled code sections / tasks?
The code itself works as expected. The issue appears to be with the configuration of the cron.
cron: 1 * * * * will run at 1 minute past the hour.
cron: "*/1 * * * *" # would run it every minute
cron: "*/5 * * * *" # would run it every 5 minutes
cron: "*/10 * * * * *" # would run every 10 seconds