slack_itc_autoingestion 0.0.1
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.
- checksums.yaml +7 -0
- data/.gitignore +23 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +45 -0
- data/Rakefile +1 -0
- data/app/assets/images/slack_itc_autoingestion/itunesconnect_app_icon.png +0 -0
- data/app/controllers/slack_itc_autoingestion/slack_controller.rb +42 -0
- data/config/routes.rb +5 -0
- data/lib/slack_itc_autoingestion.rb +8 -0
- data/lib/slack_itc_autoingestion/configuration.rb +33 -0
- data/lib/slack_itc_autoingestion/engine.rb +7 -0
- data/lib/slack_itc_autoingestion/itunes_connect.rb +27 -0
- data/lib/slack_itc_autoingestion/slack.rb +106 -0
- data/lib/slack_itc_autoingestion/version.rb +3 -0
- data/slack_itc_autoingestion.gemspec +22 -0
- metadata +101 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 67307df97f28843533b4dd502232ce75c288760d
|
4
|
+
data.tar.gz: 771170ca7d8134b66256a8a07fa5259687838f4f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ac8fd20378bec4e6e4d91879887cb371bc48486c76e14aba79a8e82b03e3045557108ea875918949ccd532c55938293591752558507c0860c677284337377db7
|
7
|
+
data.tar.gz: e401796631aee308b7f28d3be8c7c3ee9f34b4eb996e364e24662fc5061b8a3dfdb8dc07e3fc27d1d0946e0212444ed4f0ddc4e538c2a9683b1482345a3e0c1d
|
data/.gitignore
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
23
|
+
*.DS_Store
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Ian Hirschfeld
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# Slack iTunes Connect Autoingestion
|
2
|
+
|
3
|
+
This gem will add a Slack outgoing webhook endpoint for pulling iTunes Connect report data and then posting it to your Slack channels.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
```ruby
|
9
|
+
gem 'slack_itc_autoingestion'
|
10
|
+
```
|
11
|
+
|
12
|
+
And then run:
|
13
|
+
```shell
|
14
|
+
$ bundle install
|
15
|
+
```
|
16
|
+
|
17
|
+
## Configuration
|
18
|
+
By default the config looks for options set in your environment variables. Override any the defaults in `config/initializers/slack_itc_autoingestion.rb`:
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
SlackItcAutoingestion.configure do |config|
|
22
|
+
config.itc_username = ENV['ITUNES_CONNECT_USERNAME']
|
23
|
+
config.itc_password = ENV['ITUNES_CONNECT_PASSWORD']
|
24
|
+
config.itc_vendor_id = ENV['ITUNES_CONNECT_VENDOR_ID']
|
25
|
+
config.slack_token = ENV['SLACK_TOKEN']
|
26
|
+
config.slack_webhook_url = ENV['SLACK_WEBHOOK_URL']
|
27
|
+
config.slack_command = '/itc'
|
28
|
+
end
|
29
|
+
```
|
30
|
+
|
31
|
+
## Usage
|
32
|
+
In any public Slack channel you can type:
|
33
|
+
`/itc [report_date] [report_date] [date_type] [report_type]`
|
34
|
+
|
35
|
+
`report_date` is date in the format `YYYYMMDD`. Defaults to yesterday.
|
36
|
+
`date_type` is 'Daily' or 'Weekly'. Defaults to 'Daily'.
|
37
|
+
`report_type` is 'Summary' or 'Opt-In'. Defaults to 'Summary'.
|
38
|
+
|
39
|
+
## Contributing
|
40
|
+
|
41
|
+
1. Fork it ( https://github.com/[my-github-username]/slack_itc_autoingestion/fork )
|
42
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
43
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
44
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
45
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
@@ -0,0 +1,42 @@
|
|
1
|
+
class SlackItcAutoingestion::SlackController < ApplicationController
|
2
|
+
|
3
|
+
protect_from_forgery with: :null_session
|
4
|
+
|
5
|
+
def receiver
|
6
|
+
slack = SlackItcAutoingestion::Slack.new params
|
7
|
+
|
8
|
+
if slack.valid?
|
9
|
+
autoingestion = SlackItcAutoingestion::ItunesConnect.new(
|
10
|
+
SlackItcAutoingestion.configuration.itc_username,
|
11
|
+
SlackItcAutoingestion.configuration.itc_password,
|
12
|
+
SlackItcAutoingestion.configuration.itc_vendor_id
|
13
|
+
)
|
14
|
+
|
15
|
+
uri = URI.parse SlackItcAutoingestion.configuration.slack_webhook_url
|
16
|
+
http = Net::HTTP.new uri.host, uri.port
|
17
|
+
http.use_ssl = true
|
18
|
+
request = Net::HTTP::Post.new uri.request_uri
|
19
|
+
|
20
|
+
body = {
|
21
|
+
username: 'Itunes Connect Autoingestion',
|
22
|
+
icon_url: view_context.image_url('slack_itc_autoingestion/itunesconnect_app_icon.png')
|
23
|
+
}
|
24
|
+
|
25
|
+
begin
|
26
|
+
slack.report = autoingestion.fetch_and_parse slack.report_params
|
27
|
+
body[:text] = slack.text
|
28
|
+
body[:attachments] = slack.attachments
|
29
|
+
rescue => e
|
30
|
+
body[:text] = e.message
|
31
|
+
end
|
32
|
+
|
33
|
+
request.body = body.to_json
|
34
|
+
response = http.request request
|
35
|
+
|
36
|
+
render json: {}, status: :ok
|
37
|
+
else
|
38
|
+
render json: {error: {message: slack.error_message}}, status: :bad_request
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
data/config/routes.rb
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
require 'slack_itc_autoingestion/version'
|
2
|
+
require 'slack_itc_autoingestion/configuration'
|
3
|
+
require 'slack_itc_autoingestion/engine'
|
4
|
+
require 'slack_itc_autoingestion/itunes_connect'
|
5
|
+
require 'slack_itc_autoingestion/slack'
|
6
|
+
|
7
|
+
module SlackItcAutoingestion
|
8
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module SlackItcAutoingestion
|
2
|
+
class Configuration
|
3
|
+
|
4
|
+
attr_accessor :itc_username
|
5
|
+
attr_accessor :itc_password
|
6
|
+
attr_accessor :itc_vendor_id
|
7
|
+
attr_accessor :slack_token
|
8
|
+
attr_accessor :slack_webhook_url
|
9
|
+
attr_accessor :slack_command
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@itc_username = ENV['ITUNES_CONNECT_USERNAME']
|
13
|
+
@itc_password = ENV['ITUNES_CONNECT_PASSWORD']
|
14
|
+
@itc_vendor_id = ENV['ITUNES_CONNECT_VENDOR_ID']
|
15
|
+
@slack_token = ENV['SLACK_TOKEN']
|
16
|
+
@slack_webhook_url = ENV['SLACK_WEBHOOK_URL']
|
17
|
+
@slack_command = '/itc'
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
class << self
|
23
|
+
attr_accessor :configuration
|
24
|
+
|
25
|
+
def configuration
|
26
|
+
@configuration ||= Configuration.new
|
27
|
+
end
|
28
|
+
|
29
|
+
def configure
|
30
|
+
yield configuration
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'itunes_ingestion'
|
2
|
+
|
3
|
+
module SlackItcAutoingestion
|
4
|
+
class ItunesConnect
|
5
|
+
|
6
|
+
attr_reader :report
|
7
|
+
|
8
|
+
def initialize(username, password, vid)
|
9
|
+
@fetcher = ITunesIngestion::Fetcher.new username, password, vid
|
10
|
+
end
|
11
|
+
|
12
|
+
def fetch_and_parse(options = {})
|
13
|
+
fetch options
|
14
|
+
parse @report_data
|
15
|
+
end
|
16
|
+
|
17
|
+
def fetch(options = {})
|
18
|
+
@report_options = options
|
19
|
+
@report_data = @fetcher.fetch options
|
20
|
+
end
|
21
|
+
|
22
|
+
def parse(data)
|
23
|
+
@report = ITunesIngestion::SalesReportParser.parse data
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
module SlackItcAutoingestion
|
2
|
+
class Slack
|
3
|
+
|
4
|
+
DATE_FORMAT = '%a, %b %-m, %Y'
|
5
|
+
ATTACTMENT_COLOR = '#0594f9'
|
6
|
+
|
7
|
+
attr_accessor :report
|
8
|
+
attr_reader :report_params
|
9
|
+
|
10
|
+
def initialize(params = {})
|
11
|
+
@command = params[:command]
|
12
|
+
@token = params[:token]
|
13
|
+
@report_params = parse_text params[:text]
|
14
|
+
end
|
15
|
+
|
16
|
+
def parse_text(text)
|
17
|
+
data = {}
|
18
|
+
args = text.split(' ')
|
19
|
+
data[:report_date] = args[0] if args[0]
|
20
|
+
data[:date_type] = args[1].capitalize if args[1]
|
21
|
+
data[:report_type] = args[2].titleize.gsub(' ', '-') if args[2]
|
22
|
+
data
|
23
|
+
end
|
24
|
+
|
25
|
+
def error_message
|
26
|
+
if !valid_command?
|
27
|
+
"Invalid Slack command received. Got '#{@command}' and expected '#{SlackItcAutoingestion.configuration.slack_command}'."
|
28
|
+
elsif !valid_token?
|
29
|
+
"Invalid Slack token received."
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def valid?
|
34
|
+
valid_command? && valid_token?
|
35
|
+
end
|
36
|
+
|
37
|
+
def valid_command?
|
38
|
+
@command == SlackItcAutoingestion.configuration.slack_command
|
39
|
+
end
|
40
|
+
|
41
|
+
def valid_token?
|
42
|
+
@token == SlackItcAutoingestion.configuration.slack_token
|
43
|
+
end
|
44
|
+
|
45
|
+
def text
|
46
|
+
"Units sold #{date_text}."
|
47
|
+
end
|
48
|
+
|
49
|
+
def attachments
|
50
|
+
slack_attachments = []
|
51
|
+
grouped_skus = @report.group_by { |i| i[:sku] }
|
52
|
+
products = grouped_skus.select { |_, skus| skus[0][:parent_id].empty? }
|
53
|
+
iaps = grouped_skus.select { |_, skus| skus[0][:parent_id].present? }
|
54
|
+
|
55
|
+
products.each do |sku_id, skus|
|
56
|
+
units = skus.reduce(0) {|sum, sku| sum + sku[:units] }
|
57
|
+
sku_iaps = iaps.select { |_, iap| iap[0][:parent_id] == sku_id }
|
58
|
+
|
59
|
+
slack_attachments.push({
|
60
|
+
fallback: fallback(units),
|
61
|
+
title: skus[0][:title],
|
62
|
+
text: "#{units} units sold.",
|
63
|
+
fields: fields(sku_iaps),
|
64
|
+
color: ATTACTMENT_COLOR
|
65
|
+
})
|
66
|
+
end
|
67
|
+
|
68
|
+
slack_attachments
|
69
|
+
end
|
70
|
+
|
71
|
+
def fallback(units)
|
72
|
+
"#{units} units sold #{date_text}."
|
73
|
+
end
|
74
|
+
|
75
|
+
def fields(iaps)
|
76
|
+
slack_fields = []
|
77
|
+
|
78
|
+
iaps.each do |_, skus|
|
79
|
+
slack_fields.push({
|
80
|
+
title: skus[0][:title],
|
81
|
+
value: skus.reduce(0) {|sum, sku| sum + sku[:units] },
|
82
|
+
short: true
|
83
|
+
})
|
84
|
+
end
|
85
|
+
|
86
|
+
slack_fields
|
87
|
+
end
|
88
|
+
|
89
|
+
def date_text
|
90
|
+
item = @report.first
|
91
|
+
begin_date = item[:begin_date]
|
92
|
+
end_date = item[:end_date]
|
93
|
+
|
94
|
+
if begin_date == end_date
|
95
|
+
"on #{formatted_date(begin_date)}"
|
96
|
+
else
|
97
|
+
"between #{formatted_date(begin_date)}-#{formatted_date(end_date)}"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def formatted_date(date)
|
102
|
+
date.strftime DATE_FORMAT
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'slack_itc_autoingestion/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'slack_itc_autoingestion'
|
8
|
+
spec.version = SlackItcAutoingestion::VERSION
|
9
|
+
spec.authors = ['Ian Hirschfeld']
|
10
|
+
spec.email = ['ihirschfeld@thesoapcollective.com']
|
11
|
+
spec.summary = %q{iTunes Connect autoingestion webhook for Slack.}
|
12
|
+
spec.description = %q{Post iTunes Connect report data to your Slack channels.}
|
13
|
+
spec.homepage = 'https://github.com/thesoapcollective/slack_itc_autoingestion'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.require_paths = ['lib']
|
18
|
+
|
19
|
+
spec.add_runtime_dependency 'itunes_ingestion', '~> 0'
|
20
|
+
spec.add_development_dependency 'bundler', '~> 1.6'
|
21
|
+
spec.add_development_dependency 'rake', '~> 0'
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: slack_itc_autoingestion
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ian Hirschfeld
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-03-25 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: itunes_ingestion
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.6'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.6'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: Post iTunes Connect report data to your Slack channels.
|
56
|
+
email:
|
57
|
+
- ihirschfeld@thesoapcollective.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- ".gitignore"
|
63
|
+
- Gemfile
|
64
|
+
- LICENSE.txt
|
65
|
+
- README.md
|
66
|
+
- Rakefile
|
67
|
+
- app/assets/images/slack_itc_autoingestion/itunesconnect_app_icon.png
|
68
|
+
- app/controllers/slack_itc_autoingestion/slack_controller.rb
|
69
|
+
- config/routes.rb
|
70
|
+
- lib/slack_itc_autoingestion.rb
|
71
|
+
- lib/slack_itc_autoingestion/configuration.rb
|
72
|
+
- lib/slack_itc_autoingestion/engine.rb
|
73
|
+
- lib/slack_itc_autoingestion/itunes_connect.rb
|
74
|
+
- lib/slack_itc_autoingestion/slack.rb
|
75
|
+
- lib/slack_itc_autoingestion/version.rb
|
76
|
+
- slack_itc_autoingestion.gemspec
|
77
|
+
homepage: https://github.com/thesoapcollective/slack_itc_autoingestion
|
78
|
+
licenses:
|
79
|
+
- MIT
|
80
|
+
metadata: {}
|
81
|
+
post_install_message:
|
82
|
+
rdoc_options: []
|
83
|
+
require_paths:
|
84
|
+
- lib
|
85
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
requirements: []
|
96
|
+
rubyforge_project:
|
97
|
+
rubygems_version: 2.2.2
|
98
|
+
signing_key:
|
99
|
+
specification_version: 4
|
100
|
+
summary: iTunes Connect autoingestion webhook for Slack.
|
101
|
+
test_files: []
|