fastlane-plugin-devresponse 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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.
@@ -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")
@@ -0,0 +1,5 @@
1
+ module Fastlane
2
+ module Devresponse
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
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: []