pushpop 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ .env
data/.travis.yml ADDED
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ bundler_args: --without development
3
+
4
+ rvm:
5
+ - 2.1.1
6
+
7
+ script:
8
+ - bundle exec rake spec
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'clockwork'
4
+ gem 'keen'
5
+ gem 'twilio-ruby'
6
+ gem 'mail'
7
+ gem 'foreman'
8
+
9
+ group :development, :test do
10
+ gem 'rake'
11
+ gem 'rspec'
12
+ gem 'webmock'
13
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,72 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ activesupport (4.1.0)
5
+ i18n (~> 0.6, >= 0.6.9)
6
+ json (~> 1.7, >= 1.7.7)
7
+ minitest (~> 5.1)
8
+ thread_safe (~> 0.1)
9
+ tzinfo (~> 1.1)
10
+ addressable (2.3.6)
11
+ builder (3.2.2)
12
+ clockwork (0.7.4)
13
+ activesupport
14
+ tzinfo
15
+ crack (0.4.2)
16
+ safe_yaml (~> 1.0.0)
17
+ diff-lcs (1.2.5)
18
+ dotenv (0.7.0)
19
+ foreman (0.67.0)
20
+ dotenv (~> 0.7.0)
21
+ thor (~> 0.17.0)
22
+ i18n (0.6.9)
23
+ json (1.8.1)
24
+ jwt (0.1.11)
25
+ multi_json (>= 1.5)
26
+ keen (0.8.1)
27
+ addressable (~> 2.3.5)
28
+ multi_json (~> 1.3)
29
+ mail (2.5.4)
30
+ mime-types (~> 1.16)
31
+ treetop (~> 1.4.8)
32
+ mime-types (1.25.1)
33
+ minitest (5.3.3)
34
+ multi_json (1.9.2)
35
+ polyglot (0.3.4)
36
+ rake (10.3.1)
37
+ rspec (2.14.1)
38
+ rspec-core (~> 2.14.0)
39
+ rspec-expectations (~> 2.14.0)
40
+ rspec-mocks (~> 2.14.0)
41
+ rspec-core (2.14.8)
42
+ rspec-expectations (2.14.5)
43
+ diff-lcs (>= 1.1.3, < 2.0)
44
+ rspec-mocks (2.14.6)
45
+ safe_yaml (1.0.2)
46
+ thor (0.17.0)
47
+ thread_safe (0.3.3)
48
+ treetop (1.4.15)
49
+ polyglot
50
+ polyglot (>= 0.3.1)
51
+ twilio-ruby (3.11.5)
52
+ builder (>= 2.1.2)
53
+ jwt (>= 0.1.2)
54
+ multi_json (>= 1.3.0)
55
+ tzinfo (1.1.0)
56
+ thread_safe (~> 0.1)
57
+ webmock (1.17.4)
58
+ addressable (>= 2.2.7)
59
+ crack (>= 0.3.2)
60
+
61
+ PLATFORMS
62
+ ruby
63
+
64
+ DEPENDENCIES
65
+ clockwork
66
+ foreman
67
+ keen
68
+ mail
69
+ rake
70
+ rspec
71
+ twilio-ruby
72
+ webmock
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Author Josh Dzielak
2
+ Copyright (c) 2014 Keen Labs
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Procfile ADDED
@@ -0,0 +1 @@
1
+ worker: bundle exec rake jobs:run
data/README.md ADDED
@@ -0,0 +1,582 @@
1
+ # Pushpop
2
+ [![Build Status](https://travis-ci.org/keenlabs/pushpop.svg)](https://travis-ci.org/keenlabs/pushpop)
3
+
4
+ ### Automatic delivery of regular reports and alerts
5
+
6
+ <hr>
7
+ <img src="http://f.cl.ly/items/1I421w263a10340a0u2q/Screen%20Shot%202014-04-16%20at%204.35.47%20PM.png" width="45%" alt="Pingpong Daily Response Time Report">
8
+ &nbsp;&nbsp;&nbsp;
9
+ <img src="http://f.cl.ly/items/3F3X2s2d2A1I1o0V3p1n/image.png" width="45%" alt="There were 5402 Pageviews today!">
10
+ <hr>
11
+
12
+ ## Overview
13
+
14
+ Pushpop is a simple but powerful Ruby app that sends notifications based on events captured with Keen IO.
15
+
16
+ #### Ways to use Pushpop
17
+
18
+ **Regular reports**
19
+
20
+ + Send a sales report to your inbox every day at noon
21
+ + Send analytics reports to your customers every week
22
+
23
+ **Alerts**
24
+
25
+ + Send an SMS if the performance of your signup funnel dramatically changes
26
+ + Send an email when your site has been busier than usual in the last hour
27
+
28
+ #### An example Pushpop job
29
+
30
+ Here's a simple Pushpop job that uses [Twilio](https://twilio.com/) to send an SMS containing the number of daily pageviews each night at midnight:
31
+
32
+ ``` ruby
33
+ require 'pushpop'
34
+
35
+ job do
36
+
37
+ every 24.hours, at: '00:00'
38
+
39
+ keen do
40
+ event_collection 'pageviews'
41
+ analysis_type 'count'
42
+ timeframe 'last_24_hours'
43
+ end
44
+
45
+ twilio do |response|
46
+ to '+18005555555'
47
+ body "There were #{response} pageviews today!"
48
+ end
49
+
50
+ end
51
+ ```
52
+
53
+ Pushpop syntax is short and sweet, but because anything Ruby can be used it's also quite powerful.
54
+
55
+ ### Where to next?
56
+
57
+ Excited to try out Pushpop with your data? Here's a few options to choose from:
58
+
59
+ #### Quickstart
60
+
61
+ Setup Pushpop locally. It takes 10 minutes to get that first shiny report in your inbox, and even less if you already have a Keen IO, Sendgrid or Twilio account.
62
+
63
+ **[Go to the Quickstart](#quickstart)**
64
+
65
+ #### Deploy a Pushpop Instance
66
+
67
+ Ready to deploy the Pushpop job you wrote locally and start getting regular reports? Detailed instructions for Heroku are provided, as well as the basics for other platforms.
68
+
69
+ **[Go to the Deploy Guide](#deploy-guide)**
70
+
71
+ #### Need help?
72
+
73
+ Don't have a hacker at hand? The friendly folks at Keen IO are happy to help you get a Pushpop instance running.
74
+
75
+ **Email [team@keen.io](mailto:team@keen.io?subject=I want a Pushpop!)** with the subject "I want a Pushpop!"
76
+
77
+ ## Quickstart
78
+
79
+ The goal of the Quickstart is to get a Pushpop instance running locally. This should take less than 10 minutes.
80
+
81
+ #### Prerequisites
82
+
83
+ + A working Ruby installation (1.9+)
84
+ + A [Keen IO](https://keen.io) account and project and associated API keys
85
+ + A [Sendgrid](https://sendgrid.com) and/or [Twilio](https://twilio.com) account and associated API keys
86
+
87
+ #### Steps
88
+
89
+ **Clone this repository**
90
+
91
+ ``` shell
92
+ $ git clone git@github.com:keenlabs/pushpop.git
93
+ ```
94
+
95
+ Enter the pushpop directory and install dependencies.
96
+
97
+ ``` shell
98
+ $ cd pushpop
99
+ $ gem install bundler
100
+ $ bundle install
101
+ ```
102
+
103
+ **Test an example job**
104
+
105
+ There is an example job in [jobs/example_job.rb](jobs/example_job.rb). All it does is print some output to the console. Run this job via a rake task to make sure your configuration is setup properly.
106
+
107
+ ``` shell
108
+ $ foreman run rake jobs:run_once[jobs/example_job.rb]
109
+ ```
110
+
111
+ You should see the following output (followed by a logging statement):
112
+
113
+ ``` html
114
+ Hey Pushpop, let's do a math!
115
+ <pre>The number 30!</pre>
116
+ ```
117
+
118
+ **Specify your API credentials**
119
+
120
+ Now it's time to write a job that connects to APIs and does something real. For that we'll need to specify API keys. We'll use [foreman](https://github.com/ddollar/foreman) to tell Pushpop about these API keys. When you use foreman to run a process, it adds variables from a local `.env` file to the process environment. It's very handy for keeping secure API keys out of your code (`.env` files are gitignored by Pushpop).
121
+
122
+ Create a `.env` file in the project directory and add the API configuration properties and keys that you have. Here's what an example file looks like with settings from all three services:
123
+
124
+ ```
125
+ KEEN_PROJECT_ID=*********
126
+ KEEN_READ_KEY=*********
127
+ SENDGRID_DOMAIN=*********
128
+ SENDGRID_PASSWORD=*********
129
+ SENDGRID_USERNAME=*********
130
+ TWILIO_AUTH_TOKEN=*********
131
+ TWILIO_FROM=*********
132
+ TWILIO_SID=*********
133
+ ```
134
+
135
+ **Write your first job**
136
+
137
+ Let's write a job that performs a count of one of your Keen IO collections and sends an email (or SMS) with the result. We'll set it to run every 24 hours.
138
+
139
+ Create a file in the `jobs` folder called `first_job.rb` and paste in the following example:
140
+
141
+ ``` ruby
142
+ job do
143
+
144
+ # how frequently do we want this job to run?
145
+ every 24.hours
146
+
147
+ # what keen io query should be performed?
148
+ keen do
149
+ event_collection '<my-keen-collection-name>'
150
+ analysis_type 'count'
151
+ timeframe 'last_24_hours'
152
+ end
153
+
154
+ # use this block to send an email
155
+ sendgrid do |_, step_responses|
156
+ to '<my-to-email-address>'
157
+ from '<my-from-email-address>'
158
+ subject "There were #{step_responses['keen']} events in the last 24 hours!"
159
+ body 'Blowing up!'
160
+ end
161
+
162
+ # use this block to send an sms
163
+ twilio do |_, step_responses|
164
+ to '<to-phone-number>'
165
+ body "There were #{step_responses['keen']} events in the last 24 hours!"
166
+ end
167
+ end
168
+ ```
169
+
170
+ Now modify the example to use your specific information. You'll want to specify a `to` and a `from` address if you're using Sendgrid, and a `to` phone number if you're using Twilio. Everything you need to change is marked with `<>`. You'll also want to remove either Sendgrid or Twilio blocks you're not using them.
171
+
172
+ Save the file and test this job using the same `jobs:run_once` rake task that we used before.
173
+
174
+ ``` shell
175
+ $ foreman run rake jobs:run_once[jobs/first_job.rb]
176
+ ```
177
+
178
+ The output of each step will be logged to the console, and if everything worked you'll receive an email or a text message within a few seconds!
179
+
180
+ **Next steps**
181
+
182
+ + Write and test more jobs. See the [Pushpop API Documentation](#pushpop-api-documentation) below for more examples of what you can do.
183
+ + Continue on to the deploy guide to deploy a Pushpop instance and start getting regular reports and alerts.
184
+
185
+ ## Deploy Guide
186
+
187
+ ##### Heroku
188
+
189
+ These instructions are for Heroku, but should be relevant to most environments.
190
+
191
+ **Prerequisites**
192
+
193
+ You'll need a Heroku account, and the [Heroku toolbelt](https://toolbelt.heroku.com/) installed.
194
+
195
+ **Create a new Heroku app**
196
+
197
+ Make sure you're inside the Pushpop directory.
198
+
199
+ ``` shell
200
+ $ heroku create
201
+ ```
202
+
203
+ **Commit changes**
204
+
205
+ If you created a new job from the Quickstart guide, you'll want to commit that code before deploying.
206
+
207
+ ``` shell
208
+ $ git commit -am 'Created my first Pushpop job'
209
+ ```
210
+
211
+ **Set Heroku config variables**
212
+
213
+ The easiest way to do this is with the [heroku-config](https://github.com/ddollar/heroku-config) plugin. This step assumes you have created a `.env` file containing your keys as demonstrated in the Quickstart guide.
214
+
215
+ ``` shell
216
+ $ heroku plugins:install git://github.com/ddollar/heroku-config.git
217
+ $ heroku config:push
218
+ ```
219
+
220
+ **Deploy code to Heroku**
221
+
222
+ Now that your code is commited and config variables pushed we can begin a deploy.
223
+
224
+ ``` shell
225
+ $ git push heroku master
226
+ ```
227
+
228
+ **Tail logs to confirm it's working**
229
+
230
+ To see that jobs are running and that there are no errors, tail the logs on Heroku.
231
+
232
+ ``` shell
233
+ $ heroku logs --tail
234
+ ```
235
+
236
+ Note that if you have jobs that are set to run at specific times of day you might not see output for a while.
237
+
238
+ Also note - by default this will run all jobs in the `jobs` folder. You might want to delete the `example_job.rb` file in
239
+ a separate commit once you've got the hang of things.
240
+
241
+ ##### Other environments
242
+
243
+ Pushpop is run entirely by one long-running Ruby process. Anywhere you can run this process in a monitored fashion you can run a Pushpop instance. Here's the command:
244
+
245
+ ``` shell
246
+ $ foreman run rake jobs:run
247
+ ```
248
+
249
+ If you don't want to use foreman and prefer to set the environment variables yourself then all you need is this:
250
+
251
+ ``` shell
252
+ $ bundle exec rake jobs:run
253
+ ```
254
+
255
+ ## Rake Tasks
256
+
257
+ All `jobs:*` rake tasks optionally take a single filename as a parameter. The file is meant to contain one or more Pushpop jobs. If no filename is specified, all jobs in the jobs folder are considered.
258
+
259
+ Specifying a specific file looks like this:
260
+
261
+ ``` shell
262
+ $ foreman run rake jobs:run[jobs/just_this_job.rb]
263
+ ```
264
+
265
+ Here's a list of the available rake tasks:
266
+
267
+ + `jobs:describe` - Print out the names of jobs in the jobs folder.
268
+ + `jobs:run_once` - Run each job once, right now.
269
+ + `jobs:run` - Run jobs as scheduled in a long-running process. This is the task used when you deploy.
270
+ + `spec` - Run the specs.
271
+
272
+ ## Pushpop API Documentation
273
+
274
+ Steps and jobs are the heart of the Pushpop workflow. Ruby jobs files contain one or more jobs, and each job consists of one or more steps.
275
+
276
+ #### Jobs
277
+
278
+ Jobs have the following attributes:
279
+
280
+ + `name`: (optional) something that describe the job, useful in logs
281
+ + `every_duration`: the frequency at which to run the job
282
+ + `every_options` (optional): options related to when the job runs
283
+ + `steps`: the ordered list of steps to run
284
+
285
+ These attributes are easily specified using the DSL's block syntax. Here's an example:
286
+
287
+ ``` ruby
288
+ job 'print job' do
289
+ every 5.minutes
290
+ step do
291
+ puts "5 minutes later..."
292
+ end
293
+ end
294
+ ```
295
+
296
+ Inside of a `job` configuration block, steps are added by using the `step` method. They can also be
297
+ added by using a method registered by a plugin, like `keen` or `twilio`. For more information, see [Plugin Documentation](#plugin-documentation).
298
+
299
+ The frequency of the job is set via the `every` method. This is basically a passthrough to Clockwork.
300
+ Here are some cool things you can do with regard to scheduling:
301
+
302
+ ``` ruby
303
+ every 5.seconds
304
+ every 24.hours, at: '12:00'
305
+ every 24.hours, at: ['00:00', '12:00']
306
+ every 24.hours, at: '**:05'
307
+ every 24.hours, at: '00:00', tz: 'UTC'
308
+ every 5.seconds, at: '10:**'
309
+ every 1.week, at: 'Monday 12:30'
310
+ ```
311
+
312
+ See the full set of options on the [Clockwork README](https://github.com/tomykaira/clockwork#event-parameters).
313
+
314
+ ##### Job workflow
315
+
316
+ When a job kicks off, steps are run serially in the order they are specified. Each step is invoked with 2
317
+ arguments - the response of the step immediately preceding it, and a map of all responses so far.
318
+ The map is keyed by step name, which defaults to a plugin name if a plugin was used but a step name not specified.
319
+
320
+ Here's an example that shows how the response chain works:
321
+
322
+ ``` ruby
323
+ job do
324
+ every 5.minutes
325
+ step 'one' do
326
+ 1
327
+ end
328
+ step 'two' do |response|
329
+ 5 + response
330
+ end
331
+ step 'add previous steps' do |response, step_responses|
332
+ puts response # prints 5
333
+ puts step_responses['one'] + step_responses['two'] # prints 6
334
+ end
335
+ end
336
+ ```
337
+
338
+ If a `step` returns false, subsequent steps **are not run**. Here's a simple example that illustrates this:
339
+
340
+ ``` ruby
341
+ job 'lame job' do
342
+ every 5.minutes
343
+ step 'one' do
344
+ false
345
+ end
346
+ step 'two' do
347
+ # never called!
348
+ end
349
+ end
350
+ ```
351
+
352
+ This behavior is designed to make *conditional* alerting easy. Here's an example of a job that only sends an alert
353
+ for certain query responses:
354
+
355
+ ``` ruby
356
+ job do
357
+
358
+ every 1.minute
359
+
360
+ keen do
361
+ event_collection 'errors'
362
+ analysis_type 'count'
363
+ timeframe 'last_1_minute'
364
+ end
365
+
366
+ step 'notify only if there are errors' do |response|
367
+ response > 0
368
+ end
369
+
370
+ twilio do |step_responses|
371
+ to '+18005555555'
372
+ body "There were #{step_responses['keen']} errors in the last minute!"
373
+ end
374
+ end
375
+ ```
376
+
377
+ In this example, the `twilio` step will only be ran if the `keen` step returned a count greater than 0.
378
+
379
+ #### Steps
380
+
381
+ Steps have the following attributes:
382
+
383
+ + `name`: (optional) something that describes the step. Useful in logs, and is the key in the `step_responses` hash. Defaults to plugin name if a plugin is used
384
+ + `plugin`: (optional) if the step is backed by a plugin, it's the name of the plugin
385
+ + `block`: A block that runs to configure the step (when a plugin is used) or run it
386
+
387
+ Steps can be pure Ruby code or leverage a plugin DSL. Plugins are just fancy abstractions for creating steps.
388
+
389
+ Steps have built-in support for ERB templating. This is useful for generating more complex emails and reports.
390
+
391
+ Here's an example that uses a template:
392
+
393
+ ``` ruby
394
+ sendgrid do |response, step_responses|
395
+ to 'josh+pushpop@keen.io'
396
+ from 'pushpopapp+123@keen.io'
397
+ subject 'Pingpong Daily Response Time Report'
398
+ body template 'pingpong_report.html.erb', response, step_responses
399
+ preview false
400
+ end
401
+ ```
402
+
403
+ `template` is a function that renders a template in context of the step responses and returns a string.
404
+ The first argument is a template file name, located in the `templates` directory by default.
405
+ The second and third arguments are the `response` and `step_responses` respectively.
406
+ An optional fourth parameter can be used to change the path templates are looked up in.
407
+
408
+ Here's a very simple template:
409
+
410
+ ``` erb
411
+ <h1>Daily Report</h1>
412
+ <p>We got <%= response %> new users today!</p>
413
+ ```
414
+
415
+ ## Recipes
416
+
417
+ The community-driven [pushpop-recipes](https://github.com/keenlabs/pushpop-recipes) repository contains jobs and templates
418
+ for doing common things with Pushpop. Check it out for some inspiration!
419
+
420
+ ## Plugin Documentation
421
+
422
+ Plugins are located at `lib/plugins`. They are loaded automatically.
423
+
424
+ ##### Keen
425
+
426
+ The `keen` plugin gives you a DSL to specify Keen query parameters. When it runs, it
427
+ passes those parameters to the [keen gem](https://github.com/keenlabs/keen-gem), which
428
+ in turn runs the query against the Keen IO API.
429
+
430
+ Here's an example that shows most of the options you can specify:
431
+
432
+ ``` ruby
433
+ job 'daily average response time by check for successful requests in april' do
434
+
435
+ keen do
436
+ event_collection 'checks'
437
+ analysis_type 'average'
438
+ target_property 'request.duration'
439
+ group_by 'check.name'
440
+ interval 'daily'
441
+ timeframe ({ start: '2014-04-01T00:00Z' })
442
+ filters [{ property_name: "response.successful",
443
+ operator: "eq",
444
+ property_value: true }]
445
+ end
446
+
447
+ end
448
+ ```
449
+
450
+ The `keen` plugin requires that the following environment variables are set: `KEEN_PROJECT_ID` and `KEEN_READ_KEY`.
451
+
452
+ A `steps` method is also supported for [funnels](https://keen.io/docs/data-analysis/funnels/),
453
+ as well as `analyses` for doing a [multi-analysis](https://keen.io/docs/data-analysis/multi-analysis/).
454
+
455
+ ##### Sendgrid
456
+
457
+ The `sendgrid` plugin gives you a DSL to specify email parameters like subject and body.
458
+
459
+ Here's an example:
460
+
461
+ ``` ruby
462
+ job 'send an email' do
463
+
464
+ sendgrid do
465
+ to 'josh+pushpop@keen.io'
466
+ from 'pushpopapp+123@keen.io'
467
+ subject 'Is your inbox lonely?'
468
+ body 'This email was intentionally left blank.'
469
+ preview false
470
+ end
471
+
472
+ end
473
+ ```
474
+
475
+ The `sendgrid` plugin requires that the following environment variables are set: `SENDGRID_DOMAIN`, `SENDGRID_USERNAME`, and `SENDGRID_PASSWORD`.
476
+
477
+ The `preview` directive is optional and defaults to false. If you set it to true, the email contents will print out
478
+ to the console, but the email will not be sent.
479
+
480
+ The `body` method can take a string, or it can take the same parameters as `template`,
481
+ in which case it will render a template to create the body. For example:
482
+
483
+ ``` ruby
484
+ body 'pingpong_report.html.erb', response, step_responses
485
+ ```
486
+
487
+ ##### Twilio
488
+
489
+ The `twilio` plugin provides DSL to specify SMS recipient information as well as the text itself.
490
+
491
+ Here's an example:
492
+
493
+ ``` ruby
494
+ job 'send a text' do
495
+
496
+ twilio do
497
+ to '18005555555'
498
+ body 'Breathe in through the nose, out through the mouth.'
499
+ end
500
+
501
+ end
502
+ ```
503
+
504
+ The `twilio` plugin requires that the following environment variables are set: `TWILIO_AUTH_TOKEN`, `TWILIO_SID`, and `TWILIO_FROM`.
505
+
506
+ ## Creating plugins
507
+
508
+ Plugins are just subclasses of `Pushpop::Step`. Plugins should implement a run method, and
509
+ register themselves. Here's a simple plugin that stops job execution if the input into the step is 0:
510
+
511
+ ``` ruby
512
+ module Pushpop
513
+ class BreakIfZero < Step
514
+ PLUGIN_NAME = 'break_if_zero'
515
+ def run(last_response=nil, step_responses=nil)
516
+ last_response == 0
517
+ end
518
+ end
519
+
520
+ Pushpop::Job.register_plugin(BreakIfZero::PLUGIN_NAME, BreakIfZero)
521
+ end
522
+
523
+ # now in your job you can use the break_if_zero step
524
+
525
+ job do
526
+ step do [0, 1].shuffle.first end
527
+ break_if_zero
528
+ step do puts 'made it through!' end
529
+ end
530
+ ```
531
+
532
+ ## Usage as a Ruby gem
533
+
534
+ Pushpop is also a Ruby gem, so you can add it to an existing Ruby project. Here's how to do that:
535
+
536
+ **Install the gem**
537
+
538
+ ``` ruby
539
+ # bundler
540
+ gem 'pushpop'
541
+
542
+ # not bundler
543
+ gem install 'pushpop'
544
+ ```
545
+
546
+ **Require job files and run**
547
+
548
+ Once the gem is available, you should be able to load in Pushpop job files. Once a file loads,
549
+ all of its jobs are ready to be run or scheduled.
550
+
551
+ ``` ruby
552
+ load 'some_job.rb'
553
+
554
+ # run the jobs once
555
+ Pushpop.run
556
+
557
+ # or schedule and run the jobs with clockwork
558
+ Pushpop.schedule
559
+ Clockwork.manager.run
560
+ ```
561
+
562
+ Note that `pushpop` does not declare dependencies other than `clockwork` and `keen`. If you're using
563
+ Pushpop plugins like Sendgrid or Twilio you'll need to install and require those dependencies explicitly.
564
+
565
+ ## Contributing
566
+
567
+ Issues and pull requests are welcome!
568
+
569
+ **Wishlist**
570
+
571
+ + Add plugins for more data collection and notification services
572
+ + Add a web interface that shows the job names, job results, and a countdown to the next run
573
+ + Add a web interface that lets you preview emails in the browser
574
+ + Beautiful email templates with support for typical Keen IO query responses (groups, series, etc)
575
+
576
+ **Testing**
577
+
578
+ Pushpop has a full set of specs (including plugins). Run them like this:
579
+
580
+ ``` shell
581
+ $ bundle exec rake spec
582
+ ```