pushpop 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +0 -5
- data/Gemfile.lock +0 -36
- data/README.md +119 -250
- data/lib/pushpop.rb +4 -5
- data/lib/pushpop/job.rb +15 -4
- data/lib/pushpop/version.rb +1 -1
- data/pushpop.gemspec +3 -4
- data/spec/pushpop/job_spec.rb +13 -6
- data/spec/pushpop/step_spec.rb +3 -3
- data/spec/spec_helper.rb +0 -2
- metadata +6 -29
- data/lib/plugins/keen.rb +0 -78
- data/lib/plugins/sendgrid.rb +0 -94
- data/lib/plugins/twilio.rb +0 -52
- data/spec/plugins/keen_spec.rb +0 -88
- data/spec/plugins/sendgrid_spec.rb +0 -66
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -7,32 +7,13 @@ GEM
|
|
7
7
|
minitest (~> 5.1)
|
8
8
|
thread_safe (~> 0.1)
|
9
9
|
tzinfo (~> 1.1)
|
10
|
-
addressable (2.3.6)
|
11
|
-
builder (3.2.2)
|
12
10
|
clockwork (0.7.4)
|
13
11
|
activesupport
|
14
12
|
tzinfo
|
15
|
-
crack (0.4.2)
|
16
|
-
safe_yaml (~> 1.0.0)
|
17
13
|
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
14
|
i18n (0.6.9)
|
23
15
|
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
16
|
minitest (5.3.3)
|
34
|
-
multi_json (1.9.2)
|
35
|
-
polyglot (0.3.4)
|
36
17
|
rake (10.3.1)
|
37
18
|
rspec (2.14.1)
|
38
19
|
rspec-core (~> 2.14.0)
|
@@ -42,31 +23,14 @@ GEM
|
|
42
23
|
rspec-expectations (2.14.5)
|
43
24
|
diff-lcs (>= 1.1.3, < 2.0)
|
44
25
|
rspec-mocks (2.14.6)
|
45
|
-
safe_yaml (1.0.2)
|
46
|
-
thor (0.17.0)
|
47
26
|
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
27
|
tzinfo (1.1.0)
|
56
28
|
thread_safe (~> 0.1)
|
57
|
-
webmock (1.17.4)
|
58
|
-
addressable (>= 2.2.7)
|
59
|
-
crack (>= 0.3.2)
|
60
29
|
|
61
30
|
PLATFORMS
|
62
31
|
ruby
|
63
32
|
|
64
33
|
DEPENDENCIES
|
65
34
|
clockwork
|
66
|
-
foreman
|
67
|
-
keen
|
68
|
-
mail
|
69
35
|
rake
|
70
36
|
rspec
|
71
|
-
twilio-ruby
|
72
|
-
webmock
|
data/README.md
CHANGED
@@ -1,7 +1,10 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
<p align="center">
|
2
|
+
<img align="center" src="http://f.cl.ly/items/0z182V2i3X0Q0Y3I2A2G/pushpop-logo.png">
|
3
|
+
</p>
|
3
4
|
|
4
|
-
|
5
|
+
[![Build Status](https://travis-ci.org/pushpop-project/pushpop.svg)](https://travis-ci.org/pushpop-project/pushpop)
|
6
|
+
|
7
|
+
### A framework for scheduled integrations
|
5
8
|
|
6
9
|
<hr>
|
7
10
|
<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">
|
@@ -11,101 +14,108 @@
|
|
11
14
|
|
12
15
|
## Overview
|
13
16
|
|
14
|
-
Pushpop is a simple but powerful Ruby
|
17
|
+
Pushpop is a simple but powerful Ruby gem that lets you share data between services at regular intervals.
|
18
|
+
This can be used to do things like regular data collection as well as triggering alerts based on patterns in data.
|
19
|
+
|
20
|
+
Pushpop includes support for sending notifications and reports based on events captured with [Keen IO](https://keen.io).
|
21
|
+
See plugins for more services on the [Pushpop organization](https://github.com/pushpop-project) home page.
|
15
22
|
|
16
23
|
#### Ways to use Pushpop
|
17
24
|
|
18
|
-
|
25
|
+
##### Alerts
|
19
26
|
|
20
|
-
+ Send
|
21
|
-
+ Send
|
27
|
+
+ Send an email when your site has been busier than usual in the last hour
|
28
|
+
+ Send an SMS if the performance of your signup funnel dramatically changes
|
22
29
|
|
23
|
-
|
30
|
+
##### Recurring reports
|
24
31
|
|
25
|
-
+ Send
|
26
|
-
+ Send
|
32
|
+
+ Send a sales report to your inbox every day at noon
|
33
|
+
+ Send analytics reports to your customers every week
|
27
34
|
|
28
35
|
#### An example Pushpop job
|
29
36
|
|
30
|
-
|
37
|
+
This Pushpop job uses the `keen` and `sendgrid` plugins to send a nightly email containing the day's number of pageviews:
|
31
38
|
|
32
39
|
``` ruby
|
33
|
-
require 'pushpop'
|
40
|
+
require 'pushpop-keen'
|
41
|
+
require 'pushpop-sendgrid'
|
34
42
|
|
35
43
|
job do
|
36
44
|
|
37
45
|
every 24.hours, at: '00:00'
|
38
46
|
|
39
47
|
keen do
|
40
|
-
event_collection
|
41
|
-
analysis_type
|
42
|
-
timeframe
|
48
|
+
event_collection 'pageviews'
|
49
|
+
analysis_type 'count'
|
50
|
+
timeframe 'last_24_hours'
|
43
51
|
end
|
44
52
|
|
45
|
-
|
46
|
-
to
|
47
|
-
|
53
|
+
sendgrid do |response, _|
|
54
|
+
to 'josh+pushpop@keen.io'
|
55
|
+
from 'josh+pushpop@keen.io'
|
56
|
+
subject 'Pushpop Daily Pageviews Report'
|
57
|
+
body "There were #{response} pageviews today!"
|
48
58
|
end
|
49
59
|
|
50
60
|
end
|
51
61
|
```
|
52
62
|
|
53
|
-
|
63
|
+
The email is sent by [Sendgrid](https://sendgrid.com), made possible by the [sendgrid](https://github.com/pushpop-project/pushpop-sendgrid) Pushpop plugin.
|
54
64
|
|
55
|
-
|
65
|
+
Pushpop syntax is short and sweet, but because Pushpop is just Ruby it's also quite powerful.
|
56
66
|
|
57
|
-
|
67
|
+
### Get Started
|
58
68
|
|
59
|
-
|
69
|
+
Excited to try out Pushpop with your Keen IO projects? Here's a few options to choose from:
|
60
70
|
|
61
|
-
|
71
|
+
#### The Quickstart
|
72
|
+
|
73
|
+
Setup Pushpop locally and run your first job in minutes.
|
62
74
|
|
63
75
|
**[Go to the Quickstart](#quickstart)**
|
64
76
|
|
65
77
|
#### Deploy a Pushpop Instance
|
66
78
|
|
67
|
-
Ready to deploy
|
79
|
+
Ready to deploy a local Pushpop job? Detailed instructions for Heroku are provided as well as a basic guide for other platforms.
|
68
80
|
|
69
81
|
**[Go to the Deploy Guide](#deploy-guide)**
|
70
82
|
|
71
83
|
#### Need help?
|
72
84
|
|
73
|
-
Don't have a hacker
|
85
|
+
Don't have a hacker on hand? The friendly folks at Keen IO can set a Pushpop up for you.
|
74
86
|
|
75
|
-
**Email [team@keen.io](mailto:team@keen.io?subject=I want a Pushpop!)** with the subject "I want a Pushpop!"
|
87
|
+
**Email [team@keen.io](mailto:team@keen.io?subject=I want a Pushpop!)** with the subject "I want a Pushpop!". Include information about what queries you'd like to run (and when) and how you'd like the results communicated.
|
76
88
|
|
77
89
|
## Quickstart
|
78
90
|
|
79
|
-
The goal of the Quickstart is to get a Pushpop instance running locally. This should take less than 10 minutes.
|
91
|
+
The goal of the Quickstart is to get a Pushpop instance running locally and write your first job. This should take less than 10 minutes.
|
80
92
|
|
81
93
|
#### Prerequisites
|
82
94
|
|
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
|
95
|
+
+ A working [Ruby installation](https://www.ruby-lang.org/en/installation/) (1.9+)
|
86
96
|
|
87
97
|
#### Steps
|
88
98
|
|
89
|
-
|
99
|
+
##### Clone the Pushpop starter project
|
90
100
|
|
91
101
|
``` shell
|
92
|
-
$ git clone git@github.com:
|
102
|
+
$ git clone git@github.com:pushpop-project/pushpop-starter.git
|
93
103
|
```
|
94
104
|
|
95
|
-
Enter the pushpop directory and install dependencies.
|
105
|
+
Enter the `pushpop-starter` directory and install dependencies.
|
96
106
|
|
97
107
|
``` shell
|
98
|
-
$ cd pushpop
|
108
|
+
$ cd pushpop-starter
|
99
109
|
$ gem install bundler
|
100
110
|
$ bundle install
|
101
111
|
```
|
102
112
|
|
103
|
-
|
113
|
+
##### Test the included job
|
104
114
|
|
105
|
-
There is an example job in
|
115
|
+
There is an example job in `jobs/example_job.rb` of the pushpop-starter repository. It simply prints output to the console. Run this job via a rake task to make sure your configuration is setup properly.
|
106
116
|
|
107
117
|
``` shell
|
108
|
-
$
|
118
|
+
$ bundle exec rake jobs:run_once[jobs/example_job.rb]
|
109
119
|
```
|
110
120
|
|
111
121
|
You should see the following output (followed by a logging statement):
|
@@ -115,92 +125,35 @@ Hey Pushpop, let's do a math!
|
|
115
125
|
<pre>The number 30!</pre>
|
116
126
|
```
|
117
127
|
|
118
|
-
|
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.
|
128
|
+
That's it. You're ready to add your own jobs to the jobs folder.
|
171
129
|
|
172
|
-
|
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**
|
130
|
+
##### Next steps
|
181
131
|
|
182
132
|
+ Write and test more jobs. See the [Pushpop API Documentation](#pushpop-api-documentation) below for more examples of what you can do.
|
183
|
-
+
|
133
|
+
+ See [pushpop-recipes](https://github.com/pushpop-project/pushpop-recipes) for reusable code and inspiration.
|
134
|
+
+ Continue on to the [Deploy Guide](#deploy-guide) to deploy the job you just created.
|
184
135
|
|
185
136
|
## Deploy Guide
|
186
137
|
|
187
|
-
|
138
|
+
#### Heroku
|
188
139
|
|
189
140
|
These instructions are for Heroku, but should be relevant to most environments.
|
190
141
|
|
191
|
-
|
142
|
+
##### Prerequisites
|
192
143
|
|
193
|
-
You'll need a Heroku account, and the [Heroku toolbelt](https://toolbelt.heroku.com/) installed.
|
144
|
+
You'll need a [Heroku](https://heroku.com/) account, and the [Heroku toolbelt](https://toolbelt.heroku.com/) installed.
|
194
145
|
|
195
|
-
|
146
|
+
##### Create a new Heroku app
|
196
147
|
|
197
|
-
Make sure you're inside
|
148
|
+
Make sure you're inside a Pushpop project directory (e.g. pushpop-starter), than create a new Heroku app.
|
198
149
|
|
199
150
|
``` shell
|
200
151
|
$ heroku create
|
201
152
|
```
|
202
153
|
|
203
|
-
|
154
|
+
This will create a Heroku app and add a new git remote destination called `heroku` to your git configuration.
|
155
|
+
|
156
|
+
##### Commit changes
|
204
157
|
|
205
158
|
If you created a new job from the Quickstart guide, you'll want to commit that code before deploying.
|
206
159
|
|
@@ -208,24 +161,16 @@ If you created a new job from the Quickstart guide, you'll want to commit that c
|
|
208
161
|
$ git commit -am 'Created my first Pushpop job'
|
209
162
|
```
|
210
163
|
|
211
|
-
|
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**
|
164
|
+
##### Deploy code to Heroku
|
221
165
|
|
222
|
-
Now that your code is commited and config variables pushed we can begin a deploy.
|
166
|
+
Now that your code is commited and config variables pushed we can begin a deploy. We'll also need to scale the number of worker processes to 1.
|
223
167
|
|
224
168
|
``` shell
|
225
169
|
$ git push heroku master
|
170
|
+
$ heroku scale worker=1
|
226
171
|
```
|
227
172
|
|
228
|
-
|
173
|
+
##### Tail logs to confirm it's working
|
229
174
|
|
230
175
|
To see that jobs are running and that there are no errors, tail the logs on Heroku.
|
231
176
|
|
@@ -235,12 +180,11 @@ $ heroku logs --tail
|
|
235
180
|
|
236
181
|
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
182
|
|
238
|
-
|
239
|
-
a separate commit once you've got the hang of things.
|
183
|
+
Another note - by default this will run all jobs in the `jobs` folder. You might want to delete the `example_job.rb` file in a separate commit once you've got the hang of things. You can change this behavior by editing the Procfile.
|
240
184
|
|
241
|
-
|
185
|
+
#### Other environments
|
242
186
|
|
243
|
-
Pushpop is
|
187
|
+
Pushpop is deployed as one long-running Ruby process. Anywhere you can run this process you can run Pushpop. Here's the command:
|
244
188
|
|
245
189
|
``` shell
|
246
190
|
$ foreman run rake jobs:run
|
@@ -252,14 +196,18 @@ If you don't want to use foreman and prefer to set the environment variables you
|
|
252
196
|
$ bundle exec rake jobs:run
|
253
197
|
```
|
254
198
|
|
199
|
+
Note: You probably want to monitor the process via something like [supervisord](http://supervisord.org/).
|
200
|
+
|
255
201
|
## Rake Tasks
|
256
202
|
|
257
|
-
|
203
|
+
Pushpop comes with some rake tasks to make command line interaction and deployment easier.
|
204
|
+
|
205
|
+
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 required.
|
258
206
|
|
259
207
|
Specifying a specific file looks like this:
|
260
208
|
|
261
209
|
``` shell
|
262
|
-
$
|
210
|
+
$ bundle exec rake jobs:run[jobs/just_this_job.rb]
|
263
211
|
```
|
264
212
|
|
265
213
|
Here's a list of the available rake tasks:
|
@@ -271,16 +219,16 @@ Here's a list of the available rake tasks:
|
|
271
219
|
|
272
220
|
## Pushpop API Documentation
|
273
221
|
|
274
|
-
Steps and jobs are the heart of the Pushpop workflow. Ruby
|
222
|
+
Steps and jobs are the heart of the Pushpop workflow. Job files are written in pure Ruby and contain one or more jobs. Each job consists of one or more steps.
|
275
223
|
|
276
224
|
#### Jobs
|
277
225
|
|
278
226
|
Jobs have the following attributes:
|
279
227
|
|
280
228
|
+ `name`: (optional) something that describe the job, useful in logs
|
281
|
-
+ `
|
282
|
-
+ `every_options` (optional): options related to when the job runs
|
283
|
-
+ `steps`:
|
229
|
+
+ `period`: how frequently to run the job, first param to `every`
|
230
|
+
+ `every_options` (optional): options related to when the job runs, second param to `every`
|
231
|
+
+ `steps`: an ordered list of steps to run
|
284
232
|
|
285
233
|
These attributes are easily specified using the DSL's block syntax. Here's an example:
|
286
234
|
|
@@ -293,11 +241,12 @@ job 'print job' do
|
|
293
241
|
end
|
294
242
|
```
|
295
243
|
|
244
|
+
The name of this job is 'print job'. It runs every 5 minutes and it has 1 step.
|
245
|
+
|
296
246
|
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
|
247
|
+
added by using a method registered by a plugin, like `keen` or `twilio`. For more information on plugins see [Plugin Documentation](#plugin-documentation).
|
298
248
|
|
299
|
-
The
|
300
|
-
Here are some cool things you can do with regard to scheduling:
|
249
|
+
The period of the job's execution is set via the `every` method. This is basically a passthrough to the [Clockwork](https://github.com/tomykaira/clockwork) long-running process scheduler. Here are some cool things you can do with regard to setting times and days:
|
301
250
|
|
302
251
|
``` ruby
|
303
252
|
every 5.seconds
|
@@ -380,11 +329,11 @@ In this example, the `twilio` step will only be ran if the `keen` step returned
|
|
380
329
|
|
381
330
|
Steps have the following attributes:
|
382
331
|
|
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
|
332
|
+
+ `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. If you use the same plugin more than twice, you'll need to give steps individual names.
|
384
333
|
+ `plugin`: (optional) if the step is backed by a plugin, it's the name of the plugin
|
385
334
|
+ `block`: A block that runs to configure the step (when a plugin is used) or run it
|
386
335
|
|
387
|
-
Steps can be pure Ruby code or
|
336
|
+
Steps can be pure Ruby code or use a DSL provided by a plugin. Plugins are just fancy abstractions for creating steps.
|
388
337
|
|
389
338
|
Steps have built-in support for ERB templating. This is useful for generating more complex emails and reports.
|
390
339
|
|
@@ -392,20 +341,17 @@ Here's an example that uses a template:
|
|
392
341
|
|
393
342
|
``` ruby
|
394
343
|
sendgrid do |response, step_responses|
|
395
|
-
to
|
396
|
-
from
|
397
|
-
subject
|
344
|
+
to 'josh+pushpop@keen.io'
|
345
|
+
from 'pushpopapp+123@keen.io'
|
346
|
+
subject 'Pingpong Daily Response Time Report'
|
398
347
|
body template 'pingpong_report.html.erb', response, step_responses
|
399
|
-
preview false
|
400
348
|
end
|
401
349
|
```
|
402
350
|
|
403
|
-
`template` is a function that renders a template in context of the
|
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.
|
351
|
+
`template` is a function that renders a template in context of the `response` and `step_responses` and returns a string.
|
352
|
+
The first argument is a template file name, located in the `templates` directory by default. The second and third arguments are the `response` and `step_responses` respectively. An optional fourth parameter can be used to change the path templates are looked up in.
|
407
353
|
|
408
|
-
Here's a very simple template:
|
354
|
+
Here's a very simple template that uses the `response` variable in context:
|
409
355
|
|
410
356
|
``` erb
|
411
357
|
<h1>Daily Report</h1>
|
@@ -414,126 +360,43 @@ Here's a very simple template:
|
|
414
360
|
|
415
361
|
## Recipes
|
416
362
|
|
417
|
-
The community-driven [pushpop-recipes](https://github.com/
|
363
|
+
The community-driven [pushpop-recipes](https://github.com/pushpop-project/pushpop-recipes) repository contains jobs and templates
|
418
364
|
for doing common things with Pushpop. Check it out for some inspiration!
|
419
365
|
|
420
|
-
##
|
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.
|
366
|
+
## Plugins
|
429
367
|
|
430
|
-
|
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`.
|
368
|
+
Plugins are packaged as gems. See the [Pushpop organization](https://github.com/pushpop-project) page for a sampling of popular plugins.
|
505
369
|
|
506
370
|
## Creating plugins
|
507
371
|
|
508
|
-
Plugins are just subclasses of `Pushpop::Step`. Plugins should implement a run method
|
509
|
-
register themselves. Here's a simple plugin that stops job execution if the input into the step is 0:
|
372
|
+
Plugins are just subclasses of `Pushpop::Step`. Plugins should implement a `run` method and register themselves. Here's a simple plugin that stops job execution if the input into the step is 0:
|
510
373
|
|
511
374
|
``` ruby
|
512
375
|
module Pushpop
|
513
|
-
class
|
514
|
-
PLUGIN_NAME = '
|
376
|
+
class StopIfZero < Step
|
377
|
+
PLUGIN_NAME = 'stop_if_zero'
|
515
378
|
def run(last_response=nil, step_responses=nil)
|
516
379
|
last_response == 0
|
517
380
|
end
|
518
381
|
end
|
519
382
|
|
520
|
-
Pushpop::Job.register_plugin(
|
383
|
+
Pushpop::Job.register_plugin(StopIfZero::PLUGIN_NAME, StopIfZero)
|
521
384
|
end
|
522
385
|
|
523
|
-
# now in your job you can use the
|
386
|
+
# now in your job you can use the stop_if_zero step
|
524
387
|
|
525
388
|
job do
|
526
389
|
step do [0, 1].shuffle.first end
|
527
|
-
|
390
|
+
stop_if_zero
|
528
391
|
step do puts 'made it through!' end
|
529
392
|
end
|
530
393
|
```
|
531
394
|
|
532
395
|
## Usage as a Ruby gem
|
533
396
|
|
534
|
-
Pushpop
|
397
|
+
Pushpop can also be embedded in existing Ruby projects as a Ruby gem. Here's some steps on how to do that.
|
535
398
|
|
536
|
-
|
399
|
+
##### Install the gem
|
537
400
|
|
538
401
|
``` ruby
|
539
402
|
# bundler
|
@@ -543,15 +406,14 @@ gem 'pushpop'
|
|
543
406
|
gem install 'pushpop'
|
544
407
|
```
|
545
408
|
|
546
|
-
|
409
|
+
##### Require job files and run
|
547
410
|
|
548
|
-
Once the gem is available
|
549
|
-
all of its jobs are ready to be run or scheduled.
|
411
|
+
Once the gem is available you can load or require Pushpop job files. Once each file loads the jobs it contains are ready to be run or scheduled. Here's that sequence:
|
550
412
|
|
551
413
|
``` ruby
|
552
414
|
load 'some_job.rb'
|
553
415
|
|
554
|
-
# run the jobs once
|
416
|
+
# you could run the jobs once
|
555
417
|
Pushpop.run
|
556
418
|
|
557
419
|
# or schedule and run the jobs with clockwork
|
@@ -559,24 +421,31 @@ Pushpop.schedule
|
|
559
421
|
Clockwork.manager.run
|
560
422
|
```
|
561
423
|
|
562
|
-
|
563
|
-
Pushpop plugins like Sendgrid or Twilio you'll need to
|
424
|
+
The `pushpop` gem does not declare dependencies other than `clockwork` and `keen`. If you're using
|
425
|
+
Pushpop plugins like Sendgrid or Twilio you'll need to bundle and require those dependencies separately.
|
564
426
|
|
565
427
|
## Contributing
|
566
428
|
|
567
|
-
Issues and pull requests are welcome!
|
429
|
+
Issues and pull requests are very welcome!
|
568
430
|
|
569
|
-
|
431
|
+
##### Wishlist
|
570
432
|
|
571
|
-
+ Add plugins for more data collection and notification services
|
572
|
-
+ Add a web interface that shows
|
573
|
-
+ Add a web interface
|
574
|
-
+
|
433
|
+
+ Add plugins for more data collection and email/SMS/notification services
|
434
|
+
+ Add a web interface that shows job names, previous job results, and countdowns to the next run
|
435
|
+
+ Add a web interface for previewing emails in the browser
|
436
|
+
+ Add beautiful email templates with support for typical Keen IO query responses (groups, series, etc)
|
575
437
|
|
576
|
-
|
438
|
+
##### Testing
|
577
439
|
|
578
|
-
Pushpop has a full set of specs (including plugins). Run them like this:
|
440
|
+
Please make sure the specs pass before you submit your pull request. Pushpop has a full set of specs (including plugins). Run them like this:
|
579
441
|
|
580
442
|
``` shell
|
581
443
|
$ bundle exec rake spec
|
582
444
|
```
|
445
|
+
|
446
|
+
## Inspirations
|
447
|
+
|
448
|
+
> "Technology shouldn't require all of our attention, just some of it, and only when necessary."
|
449
|
+
> [calmtechnology.com](http://calmtechnology.com/)
|
450
|
+
|
451
|
+
Dashboards and reports are human presentation vehicles. They require our attention in order to gain meaning. That's great when we're actively seeking answers and want to explore. But as a means to become aware of interesting, timely events it's neither effective nor efficient. A tool like Pushpop works better in those cases. It's a calmer technology.
|
data/lib/pushpop.rb
CHANGED
@@ -4,11 +4,6 @@ require 'pushpop/version'
|
|
4
4
|
require 'pushpop/job'
|
5
5
|
require 'pushpop/step'
|
6
6
|
|
7
|
-
# require all plugins
|
8
|
-
Dir["#{File.expand_path('../plugins/*', __FILE__)}.rb"].each { |file|
|
9
|
-
require file
|
10
|
-
}
|
11
|
-
|
12
7
|
module Pushpop
|
13
8
|
class << self
|
14
9
|
cattr_accessor :logger
|
@@ -33,6 +28,10 @@ module Pushpop
|
|
33
28
|
def schedule
|
34
29
|
self.jobs.map &:schedule
|
35
30
|
end
|
31
|
+
|
32
|
+
def load_plugin(name)
|
33
|
+
load "#{File.expand_path("../plugins/#{name}", __FILE__)}.rb"
|
34
|
+
end
|
36
35
|
end
|
37
36
|
end
|
38
37
|
|
data/lib/pushpop/job.rb
CHANGED
@@ -15,7 +15,7 @@ module Pushpop
|
|
15
15
|
end
|
16
16
|
|
17
17
|
attr_accessor :name
|
18
|
-
attr_accessor :
|
18
|
+
attr_accessor :period
|
19
19
|
attr_accessor :every_options
|
20
20
|
attr_accessor :steps
|
21
21
|
|
@@ -26,8 +26,8 @@ module Pushpop
|
|
26
26
|
self.instance_eval(&block)
|
27
27
|
end
|
28
28
|
|
29
|
-
def every(
|
30
|
-
self.
|
29
|
+
def every(period, options={})
|
30
|
+
self.period = period
|
31
31
|
self.every_options = options
|
32
32
|
end
|
33
33
|
|
@@ -48,7 +48,8 @@ module Pushpop
|
|
48
48
|
end
|
49
49
|
|
50
50
|
def schedule
|
51
|
-
|
51
|
+
raise 'Set job period via "every"' unless self.period
|
52
|
+
Clockwork.manager.every(period, name, every_options) do
|
52
53
|
run
|
53
54
|
end
|
54
55
|
end
|
@@ -79,6 +80,16 @@ module Pushpop
|
|
79
80
|
def method_missing(method, *args, &block)
|
80
81
|
plugin_class = self.class.plugins[method.to_s]
|
81
82
|
|
83
|
+
unless plugin_class
|
84
|
+
begin
|
85
|
+
Pushpop.load_plugin method.to_s
|
86
|
+
plugin_class = self.class.plugins[method.to_s]
|
87
|
+
raise "Plugin not loaded: #{method.to_s}" if plugin_class.nil?
|
88
|
+
rescue LoadError
|
89
|
+
Pushpop.logger.warn("Could not find plugin #{method.to_s}")
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
82
93
|
name = args[0]
|
83
94
|
plugin = method.to_s
|
84
95
|
|
data/lib/pushpop/version.rb
CHANGED
data/pushpop.gemspec
CHANGED
@@ -8,12 +8,11 @@ Gem::Specification.new do |s|
|
|
8
8
|
s.version = Pushpop::VERSION
|
9
9
|
s.authors = ["Josh Dzielak"]
|
10
10
|
s.email = "josh@keen.io"
|
11
|
-
s.homepage = "https://github.com/
|
12
|
-
s.summary = "
|
13
|
-
s.description = "Pushpop is a simple but powerful Ruby app that sends notifications
|
11
|
+
s.homepage = "https://github.com/pushpop-project/pushpop"
|
12
|
+
s.summary = "Share data between services at regular intervals"
|
13
|
+
s.description = "Pushpop is a simple but powerful Ruby app that sends notifications about events captured with Keen IO."
|
14
14
|
|
15
15
|
s.add_dependency "clockwork"
|
16
|
-
s.add_dependency "keen"
|
17
16
|
|
18
17
|
s.files = `git ls-files`.split("\n")
|
19
18
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
data/spec/pushpop/job_spec.rb
CHANGED
@@ -17,7 +17,7 @@ describe Pushpop::Job do
|
|
17
17
|
block_ran = false
|
18
18
|
job = Pushpop::Job.new('foo') do block_ran = true end
|
19
19
|
job.name.should == 'foo'
|
20
|
-
job.
|
20
|
+
job.period.should be_nil
|
21
21
|
job.every_options.should == {}
|
22
22
|
block_ran.should be_true
|
23
23
|
end
|
@@ -29,10 +29,10 @@ describe Pushpop::Job do
|
|
29
29
|
end
|
30
30
|
|
31
31
|
describe '#every' do
|
32
|
-
it 'should set
|
32
|
+
it 'should set period and options' do
|
33
33
|
job = empty_job
|
34
34
|
job.every(10.seconds, at: '01:02')
|
35
|
-
job.
|
35
|
+
job.period.should == 10
|
36
36
|
job.every_options.should == { at: '01:02' }
|
37
37
|
end
|
38
38
|
end
|
@@ -91,9 +91,9 @@ describe Pushpop::Job do
|
|
91
91
|
|
92
92
|
describe '#schedule' do
|
93
93
|
it 'should add the job to clockwork' do
|
94
|
-
|
94
|
+
period = 1.seconds
|
95
95
|
simple_job = Pushpop::Job.new('foo') do
|
96
|
-
every
|
96
|
+
every period
|
97
97
|
step 'track_times_run' do
|
98
98
|
@times_run ||= 0
|
99
99
|
@times_run += 1
|
@@ -104,9 +104,16 @@ describe Pushpop::Job do
|
|
104
104
|
|
105
105
|
Clockwork.manager.tick(Time.now)
|
106
106
|
simple_job.run.first.should == 2
|
107
|
-
Clockwork.manager.tick(Time.now +
|
107
|
+
Clockwork.manager.tick(Time.now + period)
|
108
108
|
simple_job.run.first.should == 4
|
109
109
|
end
|
110
|
+
|
111
|
+
it 'should fail if the period was not specified' do
|
112
|
+
simple_job = Pushpop::Job.new('foo') do end
|
113
|
+
expect {
|
114
|
+
simple_job.schedule
|
115
|
+
}.to raise_error
|
116
|
+
end
|
110
117
|
end
|
111
118
|
|
112
119
|
describe '#method_missing' do
|
data/spec/pushpop/step_spec.rb
CHANGED
@@ -24,9 +24,9 @@ describe Pushpop::Step do
|
|
24
24
|
|
25
25
|
it 'should set name to plugin name if not given' do
|
26
26
|
empty_proc = Proc.new {}
|
27
|
-
step = Pushpop::Step.new(nil, '
|
28
|
-
step.name.should == '
|
29
|
-
step.plugin.should == '
|
27
|
+
step = Pushpop::Step.new(nil, 'whee', &empty_proc)
|
28
|
+
step.name.should == 'whee'
|
29
|
+
step.plugin.should == 'whee'
|
30
30
|
step.block.should == empty_proc
|
31
31
|
end
|
32
32
|
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pushpop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-06-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: clockwork
|
@@ -27,24 +27,8 @@ dependencies:
|
|
27
27
|
- - ! '>='
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: '0'
|
30
|
-
|
31
|
-
|
32
|
-
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
|
-
requirements:
|
35
|
-
- - ! '>='
|
36
|
-
- !ruby/object:Gem::Version
|
37
|
-
version: '0'
|
38
|
-
type: :runtime
|
39
|
-
prerelease: false
|
40
|
-
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
|
-
requirements:
|
43
|
-
- - ! '>='
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
version: '0'
|
46
|
-
description: Pushpop is a simple but powerful Ruby app that sends notifications based
|
47
|
-
on events captured with Keen IO.
|
30
|
+
description: Pushpop is a simple but powerful Ruby app that sends notifications about
|
31
|
+
events captured with Keen IO.
|
48
32
|
email: josh@keen.io
|
49
33
|
executables: []
|
50
34
|
extensions: []
|
@@ -59,17 +43,12 @@ files:
|
|
59
43
|
- README.md
|
60
44
|
- Rakefile
|
61
45
|
- jobs/example_job.rb
|
62
|
-
- lib/plugins/keen.rb
|
63
|
-
- lib/plugins/sendgrid.rb
|
64
|
-
- lib/plugins/twilio.rb
|
65
46
|
- lib/pushpop.rb
|
66
47
|
- lib/pushpop/job.rb
|
67
48
|
- lib/pushpop/step.rb
|
68
49
|
- lib/pushpop/version.rb
|
69
50
|
- pushpop.gemspec
|
70
51
|
- spec/jobs/simple_job.rb
|
71
|
-
- spec/plugins/keen_spec.rb
|
72
|
-
- spec/plugins/sendgrid_spec.rb
|
73
52
|
- spec/pushpop/job_spec.rb
|
74
53
|
- spec/pushpop/step_spec.rb
|
75
54
|
- spec/pushpop_spec.rb
|
@@ -77,7 +56,7 @@ files:
|
|
77
56
|
- spec/spec_helper.rb
|
78
57
|
- spec/templates/spec.html.erb
|
79
58
|
- templates/first_template.html.erb
|
80
|
-
homepage: https://github.com/
|
59
|
+
homepage: https://github.com/pushpop-project/pushpop
|
81
60
|
licenses: []
|
82
61
|
post_install_message:
|
83
62
|
rdoc_options: []
|
@@ -100,11 +79,9 @@ rubyforge_project:
|
|
100
79
|
rubygems_version: 1.8.23
|
101
80
|
signing_key:
|
102
81
|
specification_version: 3
|
103
|
-
summary:
|
82
|
+
summary: Share data between services at regular intervals
|
104
83
|
test_files:
|
105
84
|
- spec/jobs/simple_job.rb
|
106
|
-
- spec/plugins/keen_spec.rb
|
107
|
-
- spec/plugins/sendgrid_spec.rb
|
108
85
|
- spec/pushpop/job_spec.rb
|
109
86
|
- spec/pushpop/step_spec.rb
|
110
87
|
- spec/pushpop_spec.rb
|
data/lib/plugins/keen.rb
DELETED
@@ -1,78 +0,0 @@
|
|
1
|
-
require 'keen'
|
2
|
-
|
3
|
-
module Pushpop
|
4
|
-
|
5
|
-
class Keen < Step
|
6
|
-
|
7
|
-
PLUGIN_NAME = 'keen'
|
8
|
-
|
9
|
-
attr_accessor :_event_collection
|
10
|
-
attr_accessor :_analysis_type
|
11
|
-
attr_accessor :_timeframe
|
12
|
-
attr_accessor :_target_property
|
13
|
-
attr_accessor :_group_by
|
14
|
-
attr_accessor :_interval
|
15
|
-
attr_accessor :_filters
|
16
|
-
attr_accessor :_steps
|
17
|
-
attr_accessor :_analyses
|
18
|
-
|
19
|
-
def run(last_response=nil, step_responses=nil)
|
20
|
-
self.configure(last_response, step_responses)
|
21
|
-
::Keen.send(self._analysis_type, self._event_collection, self.to_analysis_options)
|
22
|
-
end
|
23
|
-
|
24
|
-
def configure(last_response=nil, step_responses=nil)
|
25
|
-
self.instance_exec(last_response, step_responses, &block)
|
26
|
-
end
|
27
|
-
|
28
|
-
def to_analysis_options
|
29
|
-
{ timeframe: self._timeframe,
|
30
|
-
target_property: self._target_property,
|
31
|
-
group_by: self._group_by,
|
32
|
-
interval: self._interval,
|
33
|
-
filters: self._filters,
|
34
|
-
analyses: self._analyses,
|
35
|
-
steps: self._steps
|
36
|
-
}.delete_if { |_, v| v.nil? }
|
37
|
-
end
|
38
|
-
|
39
|
-
def event_collection(event_collection)
|
40
|
-
self._event_collection = event_collection
|
41
|
-
end
|
42
|
-
|
43
|
-
def analysis_type(analysis_type)
|
44
|
-
self._analysis_type = analysis_type
|
45
|
-
end
|
46
|
-
|
47
|
-
def timeframe(timeframe)
|
48
|
-
self._timeframe = timeframe
|
49
|
-
end
|
50
|
-
|
51
|
-
def target_property(target_property)
|
52
|
-
self._target_property = target_property
|
53
|
-
end
|
54
|
-
|
55
|
-
def group_by(group_by)
|
56
|
-
self._group_by = group_by
|
57
|
-
end
|
58
|
-
|
59
|
-
def interval(interval)
|
60
|
-
self._interval = interval
|
61
|
-
end
|
62
|
-
|
63
|
-
def filters(filters)
|
64
|
-
self._filters = filters
|
65
|
-
end
|
66
|
-
|
67
|
-
def steps(steps)
|
68
|
-
self._steps = steps
|
69
|
-
end
|
70
|
-
|
71
|
-
def analyses(analyses)
|
72
|
-
self._analyses = analyses
|
73
|
-
end
|
74
|
-
|
75
|
-
end
|
76
|
-
|
77
|
-
Pushpop::Job.register_plugin(Keen::PLUGIN_NAME, Keen)
|
78
|
-
end
|
data/lib/plugins/sendgrid.rb
DELETED
@@ -1,94 +0,0 @@
|
|
1
|
-
require 'mail'
|
2
|
-
|
3
|
-
Mail.defaults do
|
4
|
-
delivery_method :smtp, { address: 'smtp.sendgrid.net',
|
5
|
-
port: 587,
|
6
|
-
domain: ENV['SENDGRID_DOMAIN'],
|
7
|
-
user_name: ENV['SENDGRID_USERNAME'],
|
8
|
-
password: ENV['SENDGRID_PASSWORD'],
|
9
|
-
authentication: 'plain',
|
10
|
-
enable_starttls_auto: true }
|
11
|
-
end
|
12
|
-
|
13
|
-
module Pushpop
|
14
|
-
|
15
|
-
class Sendgrid < Step
|
16
|
-
|
17
|
-
PLUGIN_NAME = 'sendgrid'
|
18
|
-
|
19
|
-
attr_accessor :_from
|
20
|
-
attr_accessor :_to
|
21
|
-
attr_accessor :_subject
|
22
|
-
attr_accessor :_body
|
23
|
-
attr_accessor :_preview
|
24
|
-
|
25
|
-
def run(last_response=nil, step_responses=nil)
|
26
|
-
|
27
|
-
self.configure(last_response, step_responses)
|
28
|
-
|
29
|
-
# print the message if its just a preview
|
30
|
-
return print_preview if self._preview
|
31
|
-
|
32
|
-
_to = self._to
|
33
|
-
_from = self._from
|
34
|
-
_subject = self._subject
|
35
|
-
_body = self._body
|
36
|
-
|
37
|
-
Mail.deliver do
|
38
|
-
to _to
|
39
|
-
from _from
|
40
|
-
subject _subject
|
41
|
-
text_part do
|
42
|
-
body _body
|
43
|
-
end
|
44
|
-
html_part do
|
45
|
-
content_type 'text/html; charset=UTF-8'
|
46
|
-
body _body
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def configure(last_response=nil, step_responses=nil)
|
52
|
-
self.instance_exec(last_response, step_responses, &block)
|
53
|
-
end
|
54
|
-
|
55
|
-
def from(from)
|
56
|
-
self._from = from
|
57
|
-
end
|
58
|
-
|
59
|
-
def to(to)
|
60
|
-
self._to = to
|
61
|
-
end
|
62
|
-
|
63
|
-
def subject(subject)
|
64
|
-
self._subject = subject
|
65
|
-
end
|
66
|
-
|
67
|
-
def preview(preview)
|
68
|
-
self._preview = preview
|
69
|
-
end
|
70
|
-
|
71
|
-
def body(*args)
|
72
|
-
if args.length == 1
|
73
|
-
self._body = args.first
|
74
|
-
else
|
75
|
-
self._body = template *args
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
private
|
80
|
-
|
81
|
-
def print_preview
|
82
|
-
puts <<MESSAGE
|
83
|
-
To: #{self._to}
|
84
|
-
From: #{self._from}
|
85
|
-
Subject: #{self._subject}
|
86
|
-
|
87
|
-
#{self._body}
|
88
|
-
MESSAGE
|
89
|
-
end
|
90
|
-
|
91
|
-
end
|
92
|
-
|
93
|
-
Pushpop::Job.register_plugin(Sendgrid::PLUGIN_NAME, Sendgrid)
|
94
|
-
end
|
data/lib/plugins/twilio.rb
DELETED
@@ -1,52 +0,0 @@
|
|
1
|
-
require 'twilio-ruby'
|
2
|
-
|
3
|
-
TWILIO_SID = ENV['TWILIO_SID']
|
4
|
-
TWILIO_AUTH_TOKEN = ENV['TWILIO_AUTH_TOKEN']
|
5
|
-
TWILIO_FROM = ENV['TWILIO_FROM']
|
6
|
-
|
7
|
-
module Pushpop
|
8
|
-
|
9
|
-
class Twilio < Step
|
10
|
-
|
11
|
-
PLUGIN_NAME = 'twilio'
|
12
|
-
|
13
|
-
attr_accessor :_from
|
14
|
-
attr_accessor :_to
|
15
|
-
attr_accessor :_body
|
16
|
-
|
17
|
-
def run(last_response=nil, step_responses=nil)
|
18
|
-
|
19
|
-
self.configure(last_response, step_responses)
|
20
|
-
|
21
|
-
_to = self._to
|
22
|
-
_from = self._from || TWILIO_FROM
|
23
|
-
_body = self._body
|
24
|
-
|
25
|
-
client = ::Twilio::REST::Client.new(TWILIO_SID, TWILIO_AUTH_TOKEN)
|
26
|
-
|
27
|
-
client.account.messages.create(
|
28
|
-
from: _from,
|
29
|
-
to: _to,
|
30
|
-
body: _body )
|
31
|
-
end
|
32
|
-
|
33
|
-
def configure(last_response=nil, step_responses=nil)
|
34
|
-
self.instance_exec(last_response, step_responses, &block)
|
35
|
-
end
|
36
|
-
|
37
|
-
def from(from)
|
38
|
-
self._from = from
|
39
|
-
end
|
40
|
-
|
41
|
-
def to(to)
|
42
|
-
self._to = to
|
43
|
-
end
|
44
|
-
|
45
|
-
def body(body)
|
46
|
-
self._body = body
|
47
|
-
end
|
48
|
-
|
49
|
-
end
|
50
|
-
|
51
|
-
Pushpop::Job.register_plugin(Twilio::PLUGIN_NAME, Twilio)
|
52
|
-
end
|
data/spec/plugins/keen_spec.rb
DELETED
@@ -1,88 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Pushpop::Keen do
|
4
|
-
|
5
|
-
describe '#configure' do
|
6
|
-
|
7
|
-
it 'should set various params' do
|
8
|
-
|
9
|
-
step = Pushpop::Keen.new do
|
10
|
-
event_collection 'pageviews'
|
11
|
-
analysis_type 'count'
|
12
|
-
timeframe 'last_3_days'
|
13
|
-
target_property 'trinkets'
|
14
|
-
group_by 'referer'
|
15
|
-
interval 'hourly'
|
16
|
-
filters [{ property_value: 'referer',
|
17
|
-
operator: 'ne',
|
18
|
-
property_value: 'yahoo.com' }]
|
19
|
-
steps [{ event_collection: 'pageviews',
|
20
|
-
actor_property: 'user.id' }]
|
21
|
-
analyses [{ analysis_type: 'count' }]
|
22
|
-
end
|
23
|
-
|
24
|
-
step.configure
|
25
|
-
|
26
|
-
step._event_collection.should == 'pageviews'
|
27
|
-
step._analysis_type.should == 'count'
|
28
|
-
step._timeframe.should == 'last_3_days'
|
29
|
-
step._group_by.should == 'referer'
|
30
|
-
step._interval.should == 'hourly'
|
31
|
-
step._steps.should == [{
|
32
|
-
event_collection: 'pageviews',
|
33
|
-
actor_property: 'user.id'
|
34
|
-
}]
|
35
|
-
step._analyses.should == [{ analysis_type: 'count' }]
|
36
|
-
end
|
37
|
-
|
38
|
-
end
|
39
|
-
|
40
|
-
describe '#run' do
|
41
|
-
it 'should run the query based on the analysis type' do
|
42
|
-
Keen.stub(:count).with('pageviews', {
|
43
|
-
timeframe: 'last_3_days'
|
44
|
-
}).and_return(365)
|
45
|
-
|
46
|
-
step = Pushpop::Keen.new('one') do
|
47
|
-
event_collection 'pageviews'
|
48
|
-
analysis_type 'count'
|
49
|
-
timeframe 'last_3_days'
|
50
|
-
end
|
51
|
-
response = step.run
|
52
|
-
response.should == 365
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
describe '#to_analysis_options' do
|
57
|
-
it 'should include various options' do
|
58
|
-
step = Pushpop::Keen.new('one') do end
|
59
|
-
step._timeframe = 'last_4_days'
|
60
|
-
step._group_by = 'referer'
|
61
|
-
step._target_property = 'trinkets'
|
62
|
-
step._interval = 'hourly'
|
63
|
-
step._filters = [{ property_value: 'referer',
|
64
|
-
operator: 'ne',
|
65
|
-
property_value: 'yahoo.com' }]
|
66
|
-
step._steps = [{ event_collection: 'pageviews',
|
67
|
-
actor_property: 'user.id' }]
|
68
|
-
step._analyses = [{ analysis_type: 'count' }]
|
69
|
-
step.to_analysis_options.should == {
|
70
|
-
timeframe: 'last_4_days',
|
71
|
-
target_property: 'trinkets',
|
72
|
-
group_by: 'referer',
|
73
|
-
interval: 'hourly',
|
74
|
-
filters: [{ property_value: 'referer',
|
75
|
-
operator: 'ne',
|
76
|
-
property_value: 'yahoo.com' }],
|
77
|
-
steps: [{ event_collection: 'pageviews',
|
78
|
-
actor_property: 'user.id' }],
|
79
|
-
analyses: [{ analysis_type: 'count' }]
|
80
|
-
}
|
81
|
-
end
|
82
|
-
|
83
|
-
it 'should not include nils' do
|
84
|
-
step = Pushpop::Keen.new('one') do end
|
85
|
-
step.to_analysis_options.should == {}
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
@@ -1,66 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
SPEC_TEMPLATES_DIRECTORY ||= File.expand_path('../../templates', __FILE__)
|
4
|
-
|
5
|
-
describe Pushpop::Sendgrid do
|
6
|
-
|
7
|
-
describe '#configure' do
|
8
|
-
|
9
|
-
it 'should set various params' do
|
10
|
-
|
11
|
-
step = Pushpop::Sendgrid.new do
|
12
|
-
to 'josh@keen.io'
|
13
|
-
from 'depths@hell.com'
|
14
|
-
subject 'time is up'
|
15
|
-
body 'use code 3:16 for high leniency'
|
16
|
-
preview true
|
17
|
-
end
|
18
|
-
|
19
|
-
step.configure
|
20
|
-
|
21
|
-
step._to.should == 'josh@keen.io'
|
22
|
-
step._from.should == 'depths@hell.com'
|
23
|
-
step._subject.should == 'time is up'
|
24
|
-
step._body.should == 'use code 3:16 for high leniency'
|
25
|
-
step._preview.should be_true
|
26
|
-
|
27
|
-
end
|
28
|
-
|
29
|
-
end
|
30
|
-
|
31
|
-
describe '#run' do
|
32
|
-
|
33
|
-
it 'should send some email' do
|
34
|
-
|
35
|
-
Mail.stub(:deliver)
|
36
|
-
|
37
|
-
step = Pushpop::Sendgrid.new do |response|
|
38
|
-
to 'josh@keen.io'
|
39
|
-
from 'alerts+pushpop@keen.io'
|
40
|
-
subject "There were #{response} Pageviews Today!"
|
41
|
-
body 'hey wats up'
|
42
|
-
end
|
43
|
-
|
44
|
-
step.run(365)
|
45
|
-
|
46
|
-
end
|
47
|
-
|
48
|
-
end
|
49
|
-
|
50
|
-
describe '#body' do
|
51
|
-
|
52
|
-
it 'should use a string if given 1 arg' do
|
53
|
-
step = Pushpop::Sendgrid.new
|
54
|
-
step.body 'hello world'
|
55
|
-
step._body.should == 'hello world'
|
56
|
-
end
|
57
|
-
|
58
|
-
it 'should use a template if more than 1 arg is passed' do
|
59
|
-
step = Pushpop::Sendgrid.new
|
60
|
-
step.body('spec.html.erb', 500, {}, SPEC_TEMPLATES_DIRECTORY)
|
61
|
-
step._body.strip.should == '<pre>500</pre>'
|
62
|
-
end
|
63
|
-
|
64
|
-
end
|
65
|
-
|
66
|
-
end
|