fastlane-plugin-devresponse 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.
- checksums.yaml +7 -0
- data/LICENSE +26 -0
- data/README.md +40 -0
- data/lib/fastlane/plugin/devresponse.rb +19 -0
- data/lib/fastlane/plugin/devresponse/actions/devresponse.rb +25 -0
- data/lib/fastlane/plugin/devresponse/patches/spaceship/tunes/app_ratings.rb +89 -0
- data/lib/fastlane/plugin/devresponse/patches/spaceship/tunes/tunes_client.rb +51 -0
- data/lib/fastlane/plugin/devresponse/patches/tunes_client.rb +19 -0
- data/lib/fastlane/plugin/devresponse/version.rb +5 -0
- metadata +135 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3004f000da9c80de39739afdd6e05113c18c013f
|
4
|
+
data.tar.gz: 48cb8b1f835ec924f873044173f6bfd520460b0c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a8a15c3ac56b09e8c86fd12ad649b8b6e6ecb604005bb4d249a82f8bc9270e59dc81cc429e95404b71ac0310b76234321b85cb06c50f5b056a9dab410b5161db
|
7
|
+
data.tar.gz: 485d55b5b2da4e76a795e22a5ac59e8ddab53bdd5f2dbcac1047fa35e0435ad1c9a45d790811aa01cfaf50ed8165e60d22fb0768cd3b3825fe3a8336d7f7a037
|
data/LICENSE
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# DON'T BE A DICK PUBLIC LICENSE
|
2
|
+
|
3
|
+
> Version 1.1, December 2016
|
4
|
+
|
5
|
+
> Copyright (C) 2017 Helmut Januschka
|
6
|
+
|
7
|
+
Everyone is permitted to copy and distribute verbatim or modified
|
8
|
+
copies of this license document.
|
9
|
+
|
10
|
+
> DON'T BE A DICK PUBLIC LICENSE
|
11
|
+
> TERMS AND CONDITIONS FOR COPYING, DICCCCCSTRIBUTION AND MODIFICATION
|
12
|
+
|
13
|
+
1. Do whatever you like with the original Cwork, just don't be a dick.
|
14
|
+
|
15
|
+
Being a dick includes - but is not limited to - the following instances:
|
16
|
+
C
|
17
|
+
1a. Outright copyright infringement - Don't just copy this and change the name.
|
18
|
+
1b. Selling the unmodified original with no work done what-so-ever, that's REALLY being a dick.
|
19
|
+
1c. Modifying the original work to contain hidden harmful content. That would make you a PROPER dick.
|
20
|
+
|
21
|
+
2. If you become rich through modifications, related works/services, or supporting the original work,
|
22
|
+
share the love. Only a dick would make loads off this work and not buy the original work's
|
23
|
+
creator(s) a pint.
|
24
|
+
|
25
|
+
3. Code is provided with no warranty. Using somebody else's code and bitching when it goes wrong makes
|
26
|
+
you a DONKEY dick. Fix the problem yourself. A non-dick would submit the fix back.
|
data/README.md
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# devresponse plugin
|
2
|
+
|
3
|
+
[](https://rubygems.org/gems/fastlane-plugin-devresponse)
|
4
|
+
|
5
|
+
Enables you to retreive app-reviews and also answer them
|
6
|
+
|
7
|
+
# Sample
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
lane :reply_all_unanswered do
|
11
|
+
Spaceship::Tunes.login("helmut@januschka.com")
|
12
|
+
app = Spaceship::Application.find("krone.at-fivexfive")
|
13
|
+
|
14
|
+
|
15
|
+
# get all reviews from AT
|
16
|
+
reviews = app.ratings.reviews("AT")
|
17
|
+
|
18
|
+
# iterate over each review - thx the 4+ and apologize all below
|
19
|
+
reviews.each do | review |
|
20
|
+
if review.rating >= 4
|
21
|
+
response_message = "Many Thx for your kind feedback and the awesome rating 🎉"
|
22
|
+
else
|
23
|
+
response_message = "We are really sorry 💔 that you have troubles with the app - feel free to contact us directly at app@domain.com - to get technical assistance!"
|
24
|
+
end
|
25
|
+
# which not yet have gotten a dev response
|
26
|
+
unless review.responded?
|
27
|
+
# respond to this user
|
28
|
+
review.developer_response.create!(response_message)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# here is a sample of editing a existing developer response
|
33
|
+
if reviews.first.responded?
|
34
|
+
reviews.first.developer_response.update!("First you where awesome 👏 but now you are 🚀")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
```
|
39
|
+
|
40
|
+
run with `fastlane reply_all_unanswered`
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'fastlane/plugin/devresponse/version'
|
2
|
+
|
3
|
+
module Fastlane
|
4
|
+
module Devresponse
|
5
|
+
# Return all .rb files inside the "actions" and "helper" directory
|
6
|
+
def self.all_classes
|
7
|
+
Dir[File.expand_path('**/{actions,helper}/*.rb', File.dirname(__FILE__))]
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# By default we want to import all available actions and helpers
|
13
|
+
# A plugin can contain any number of actions and plugins
|
14
|
+
Fastlane::Devresponse.all_classes.each do |current|
|
15
|
+
require current
|
16
|
+
end
|
17
|
+
|
18
|
+
require "fastlane/plugin/devresponse/patches/spaceship/tunes/app_ratings"
|
19
|
+
require "fastlane/plugin/devresponse/patches/spaceship/tunes/tunes_client"
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Fastlane
|
2
|
+
module Actions
|
3
|
+
class DevresponseAction < Action
|
4
|
+
def self.run(params)
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.description
|
8
|
+
"Devresponse patcher"
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.available_options
|
12
|
+
[
|
13
|
+
]
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.authors
|
17
|
+
["hjanuschka"]
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.is_supported?(platform)
|
21
|
+
true
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module Spaceship
|
2
|
+
module Tunes
|
3
|
+
class AppRatings < TunesBase
|
4
|
+
# @return (Array) of Review Objects
|
5
|
+
def reviews(store_front, versionId = '')
|
6
|
+
raw_reviews = client.get_reviews(application.apple_id, application.platform, store_front, versionId)
|
7
|
+
raw_reviews.map do |review|
|
8
|
+
review["value"]["application"] = self.application
|
9
|
+
AppReview.factory(review["value"])
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
class DeveloperResponse < TunesBase
|
14
|
+
attr_reader :id
|
15
|
+
attr_reader :response
|
16
|
+
attr_reader :last_modified
|
17
|
+
attr_reader :hidden
|
18
|
+
attr_reader :state
|
19
|
+
attr_accessor :application
|
20
|
+
attr_accessor :review_id
|
21
|
+
|
22
|
+
attr_mapping({
|
23
|
+
'responseId' => :id,
|
24
|
+
'response' => :response,
|
25
|
+
'lastModified' => :last_modified,
|
26
|
+
'isHidden' => :hidden,
|
27
|
+
'pendingState' => :state
|
28
|
+
})
|
29
|
+
|
30
|
+
def create!(text)
|
31
|
+
client.create_developer_response!(app_id: application.apple_id, platform: application.platform, review_id: review_id, response: text)
|
32
|
+
end
|
33
|
+
|
34
|
+
def update!(text)
|
35
|
+
client.update_developer_response!(app_id: application.apple_id, platform: application.platform, review_id: review_id, response_id: id, response: text)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class AppReview < TunesBase
|
40
|
+
attr_accessor :application
|
41
|
+
attr_reader :rating
|
42
|
+
attr_reader :id
|
43
|
+
attr_reader :title
|
44
|
+
attr_reader :review
|
45
|
+
attr_reader :nickname
|
46
|
+
attr_reader :store_front
|
47
|
+
attr_reader :app_version
|
48
|
+
attr_reader :last_modified
|
49
|
+
attr_reader :helpful_views
|
50
|
+
attr_reader :total_views
|
51
|
+
attr_reader :edited
|
52
|
+
attr_reader :raw_developer_response
|
53
|
+
attr_accessor :developer_response
|
54
|
+
|
55
|
+
attr_mapping({
|
56
|
+
'id' => :id,
|
57
|
+
'rating' => :rating,
|
58
|
+
'title' => :title,
|
59
|
+
'review' => :review,
|
60
|
+
'nickname' => :nickname,
|
61
|
+
'storeFront' => :store_front,
|
62
|
+
'appVersionString' => :app_version,
|
63
|
+
'lastModified' => :last_modified,
|
64
|
+
'helpfulViews' => :helpful_views,
|
65
|
+
'totalViews' => :total_views,
|
66
|
+
'developerResponse' => :raw_developer_response,
|
67
|
+
'edited' => :edited
|
68
|
+
})
|
69
|
+
class << self
|
70
|
+
# Create a new object based on a hash.
|
71
|
+
# This is used to create a new object based on the server response.
|
72
|
+
def factory(attrs)
|
73
|
+
obj = self.new(attrs)
|
74
|
+
response_attrs = {}
|
75
|
+
response_attrs = obj.raw_developer_response if obj.raw_developer_response
|
76
|
+
response_attrs[:application] = obj.application
|
77
|
+
response_attrs[:review_id] = obj.id
|
78
|
+
obj.developer_response = DeveloperResponse.factory(response_attrs)
|
79
|
+
return obj
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def responded?
|
84
|
+
return true if raw_developer_response
|
85
|
+
false
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Spaceship
|
2
|
+
class TunesClient
|
3
|
+
def create_developer_response!(app_id: nil, platform: "ios", review_id: nil, response: nil)
|
4
|
+
raise "app_id is required" unless app_id
|
5
|
+
raise "review_id is required" unless review_id
|
6
|
+
raise "response is required" unless response
|
7
|
+
|
8
|
+
data = {
|
9
|
+
responseText: response,
|
10
|
+
reviewId: review_id
|
11
|
+
}
|
12
|
+
request(:post) do |req|
|
13
|
+
req.url "ra/apps/#{app_id}/platforms/#{platform}/reviews/#{review_id}/responses"
|
14
|
+
req.body = data.to_json
|
15
|
+
req.headers['Content-Type'] = 'application/json'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def update_developer_response!(app_id: nil, platform: "ios", review_id: nil, response_id: nil, response: nil)
|
20
|
+
raise "app_id is required" unless app_id
|
21
|
+
raise "review_id is required" unless review_id
|
22
|
+
raise "response_id is required" unless response_id
|
23
|
+
raise "response is required" unless response
|
24
|
+
|
25
|
+
data = {
|
26
|
+
responseText: response
|
27
|
+
}
|
28
|
+
request(:put) do |req|
|
29
|
+
req.url "ra/apps/#{app_id}/platforms/#{platform}/reviews/#{review_id}/responses/#{response_id}"
|
30
|
+
req.body = data.to_json
|
31
|
+
req.headers['Content-Type'] = 'application/json'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def get_reviews(app_id, platform, storefront, versionId = '')
|
36
|
+
index = 0
|
37
|
+
per_page = 100 # apple default
|
38
|
+
all_reviews = []
|
39
|
+
loop do
|
40
|
+
r = request(:get, "ra/apps/#{app_id}/platforms/#{platform}/reviews?storefront=#{storefront}&versionId=#{versionId}&index=#{index}")
|
41
|
+
all_reviews.concat(parse_response(r, 'data')['reviews'])
|
42
|
+
if all_reviews.count < parse_response(r, 'data')['reviewCount']
|
43
|
+
index += per_page
|
44
|
+
else
|
45
|
+
break
|
46
|
+
end
|
47
|
+
end
|
48
|
+
all_reviews
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'fastlane/plugin/devresponse/version'
|
2
|
+
|
3
|
+
module Fastlane
|
4
|
+
module Devresponse
|
5
|
+
# Return all .rb files inside the "actions" and "helper" directory
|
6
|
+
def self.all_classes
|
7
|
+
Dir[File.expand_path('**/{actions,helper}/*.rb', File.dirname(__FILE__))]
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# By default we want to import all available actions and helpers
|
13
|
+
# A plugin can contain any number of actions and plugins
|
14
|
+
Fastlane::Devresponse.all_classes.each do |current|
|
15
|
+
require current
|
16
|
+
end
|
17
|
+
|
18
|
+
require File.expand_path("**/patches/spaceship/tunes/app_ratings")
|
19
|
+
require File.expand_path("**/patches/spaceship/tunes/tunes_client")
|
metadata
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fastlane-plugin-devresponse
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Helmut Januschka
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-03-31 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: pry
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
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: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
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
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: fastlane
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 2.10.0
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 2.10.0
|
97
|
+
description:
|
98
|
+
email: helmut@januschka.com
|
99
|
+
executables: []
|
100
|
+
extensions: []
|
101
|
+
extra_rdoc_files: []
|
102
|
+
files:
|
103
|
+
- LICENSE
|
104
|
+
- README.md
|
105
|
+
- lib/fastlane/plugin/devresponse.rb
|
106
|
+
- lib/fastlane/plugin/devresponse/actions/devresponse.rb
|
107
|
+
- lib/fastlane/plugin/devresponse/patches/spaceship/tunes/app_ratings.rb
|
108
|
+
- lib/fastlane/plugin/devresponse/patches/spaceship/tunes/tunes_client.rb
|
109
|
+
- lib/fastlane/plugin/devresponse/patches/tunes_client.rb
|
110
|
+
- lib/fastlane/plugin/devresponse/version.rb
|
111
|
+
homepage:
|
112
|
+
licenses:
|
113
|
+
- MIT
|
114
|
+
metadata: {}
|
115
|
+
post_install_message:
|
116
|
+
rdoc_options: []
|
117
|
+
require_paths:
|
118
|
+
- lib
|
119
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
125
|
+
requirements:
|
126
|
+
- - ">="
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: '0'
|
129
|
+
requirements: []
|
130
|
+
rubyforge_project:
|
131
|
+
rubygems_version: 2.6.11
|
132
|
+
signing_key:
|
133
|
+
specification_version: 4
|
134
|
+
summary: Enables Spaceship to deal with developer response
|
135
|
+
test_files: []
|