├── .travis.yml ├── .gitignore ├── package.json ├── test.js ├── index.js ├── LICENSE ├── README.md └── .jshintrc /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '0.10' 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Projects files 2 | keys.sh 3 | 4 | # OS Artifacts 5 | *.DS_Store 6 | 7 | # Vagrant Artifacts 8 | .vagrant/* 9 | Berksfile.lock 10 | 11 | # NPM Artifacts 12 | node_modules/* 13 | npm-debug.log 14 | libpeerconnection.log 15 | 16 | # Docco artifacts 17 | docs/* 18 | 19 | # IDE Artifacts 20 | .idea/* 21 | *.iml 22 | *.sublime-* 23 | 24 | # Jekyll artifacts 25 | _site/* 26 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "heroku-self-ping", 3 | "version": "1.1.4", 4 | "author": "Matthieu Bacconnier ", 5 | "bin": {}, 6 | "scripts": { 7 | "test": "NODE_ENV=test mocha -R spec test.js" 8 | }, 9 | "main": "./index.js", 10 | "repository": { 11 | "type": "git", 12 | "url": "https://github.com/Neamar/heroku-self-ping" 13 | }, 14 | "keywords": [ 15 | "anyfetch", 16 | "hydrater", 17 | "filecleaner" 18 | ], 19 | "dependencies": { 20 | "is-heroku": "~1.0.1", 21 | "request": "~2.81.0" 22 | }, 23 | "devDependencies": { 24 | "mocha": "~3.1.2" 25 | }, 26 | "licence": "MIT", 27 | "engines": { 28 | "node": ">=0.10" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var assert = require("assert"); 4 | 5 | var herokuSelfPing = require('./index.js'); 6 | 7 | 8 | describe("Heroku self ping", function() { 9 | it("should skip when URL is not defined", function() { 10 | assert.ok(!herokuSelfPing()); 11 | }); 12 | 13 | it("should skip when not on Heroku", function() { 14 | assert.ok(!herokuSelfPing("http://mypp.herokuapp.com")); 15 | }); 16 | 17 | it('should set an interval on Heroku', function() { 18 | // Fake an Heroku env 19 | process.env.HEROKU = true; 20 | // Dirty hack to force a reload of "is-heroku" module, 21 | // else we're stuck with the previously cached value 22 | delete require.cache[require.resolve('is-heroku')]; 23 | 24 | assert.ok(herokuSelfPing("http://mypp.herokuapp.com")); 25 | delete process.env.HEROKU; 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var request = require('request'); 4 | 5 | 6 | module.exports = function herokuSelfPing(url, options) { 7 | if(!options) { 8 | options = {}; 9 | } 10 | 11 | options.interval = options.interval || 20 * 1000 * 60; 12 | options.logger = options.logger || console.log; 13 | options.verbose = options.verbose || false; 14 | 15 | var isHeroku = require("is-heroku"); 16 | 17 | if(!url) { 18 | options.verbose && options.logger("heroku-self-ping: no url provided. Exiting."); 19 | return false; 20 | } 21 | if(!isHeroku) { 22 | options.verbose && options.logger("heroku-self-ping: heroku not detected. Exiting."); 23 | 24 | return false; 25 | } 26 | 27 | 28 | options.verbose && options.logger("heroku-self-ping: Setting up hearbeat to " + url + " every " + options.interval + "ms."); 29 | 30 | return setInterval(function() { 31 | options.logger("heroku-self-ping: Sending hearbeat to " + url); 32 | request(url, function () {}); 33 | }, options.interval); 34 | }; 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Papiel SAS 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Heroku self ping 2 | ================ 3 | 4 | To avoid the one-hour time limit on your dyno, use this npm module: 5 | 6 | ```js 7 | require('heroku-self-ping')("http://your-app-url"); 8 | ``` 9 | 10 | This will register a timer self-pinging your app every 20 minutes. 11 | 12 | This timer will only activate when your app is running on Heroku platform. The script is a no-op on any other environment, including local and CI. 13 | 14 | ## Parameters 15 | * `your-app-url` can be any URL to access your app -- an `herokuapp.com` subdomain or any custom domain defined with your app. 16 | 17 | > Heroku doesn't allow an app to retrieve its current name, which is why you need to manually specify the URL. 18 | 19 | * `options`, optional object with the following keys: 20 | * `interval` number of ms between two heartbeats calls. Default to `20 * 60 * 1000` (20 minutes). 21 | * `logger` function to use for logging. Default to `console.log` 22 | * `verbose` send more information to logger function. Default to `false`. 23 | 24 | ## Return 25 | The function returns an [interval id](https://developer.mozilla.org/en/docs/Web/API/window.setInterval) when running on Heroku and the URL is not falsy, and `false` in other cases. 26 | 27 | ## Usage 28 | We recommend you set a custom env variable, for instance `heroku config:set APP_URL http://yourapp.herokuapp.com` and access it later from `process.env.APP_URL`. 29 | 30 | The lib won't do anything when passed an empty `url`. 31 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "bitwise" : true, 3 | "curly" : true, 4 | "eqeqeq" : true, 5 | "immed" : true, 6 | "latedef" : true, 7 | "newcap" : true, 8 | "noarg" : true, 9 | "noempty" : true, 10 | "nonew" : true, 11 | "plusplus" : true, 12 | "regexp" : true, 13 | "undef" : true, 14 | "strict" : true, 15 | "trailing" : true, 16 | "unused" : true, 17 | "loopfunc" : true, 18 | 19 | "asi" : false, 20 | "boss" : false, 21 | "debug" : false, 22 | "eqnull" : false, 23 | "es5" : false, 24 | "esnext" : false, 25 | "evil" : false, 26 | "expr" : true, 27 | "forin" : false, 28 | "funcscope" : false, 29 | "globalstrict" : false, 30 | "iterator" : false, 31 | "lastsemic" : false, 32 | "laxbreak" : false, 33 | "laxcomma" : false, 34 | "quotmark" : false, 35 | "multistr" : false, 36 | "onecase" : false, 37 | "proto" : false, 38 | "regexdash" : false, 39 | "scripturl" : false, 40 | "smarttabs" : false, 41 | "shadow" : false, 42 | "sub" : false, 43 | "supernew" : false, 44 | "validthis" : false, 45 | 46 | "browser" : false, 47 | "couch" : false, 48 | "devel" : false, 49 | "dojo" : false, 50 | "jquery" : false, 51 | "mootools" : false, 52 | "node" : true, 53 | "nonstandard" : false, 54 | "prototypejs" : false, 55 | "rhino" : false, 56 | "wsh" : false, 57 | 58 | "nomen" : false, 59 | "onevar" : false, 60 | "passfail" : false, 61 | "white" : false, 62 | 63 | "maxerr" : 100, 64 | "predef" : [ 65 | "describe", 66 | "it", 67 | "after", 68 | "before", 69 | "beforeEach" 70 | ], 71 | "indent" : 2, 72 | "maxstatements" : 60, 73 | "maxcomplexity" : 15 74 | } 75 | --------------------------------------------------------------------------------