fastlane-plugin-devresponse 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![fastlane Plugin Badge](https://rawcdn.githack.com/fastlane/fastlane/master/fastlane/assets/plugin-badge.svg)](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: []
|