ZReviewTender is a tool for fetching app reviews from the App Store and Google Play Console using the brand new official Stability API, and seamlessly integrating them into your workflow.
- Supports fetching App Store reviews for iOS apps and Mac OS apps
- Supports fetching Google Play Console reviews for Android apps
- Resends the newest reviews to a specified Slack channel
- Supports auto-translating review content to your language using Google Translate
- Supports auto-logging reviews to Google Sheets or Asana task
- Offers flexible extensions so you can develop your own processor (a.k.a. plugin) to suit your workflow
- Provides a lightweight implementation that only logs the latest review timestamp, rather than saving all reviews in local storage
- Supports filtering, allowing you to add custom filter conditions to filter out the reviews you don't need
- Based on official APIs (AndroidpublisherV3 and the brand new AppStoreConnect API), eliminating the need for workarounds or dealing with session expired problems
- Quickly deployable with the Github Repo Template/Github Action
- 100% Ruby@RubyGem
ZReviewTender | Appreviewbot.com | Reviewbot.io | Aappbot.co | Appfollow.io | Appfigures.com | |
---|---|---|---|---|---|---|
Pricing for 2 Apps (Android & iOS) | Forever Free No limit | $11.99/month | $5/month | $39/month | $0 | $7.99/month |
Service Type | PaaS | SaaS | SaaS | SaaS | SaaS | SaaS |
Stability & Immediacy | High | High | untested | untested | Low | untested |
Countries/Languages Limit | No limit | No limit | 5 | No limit | No limit | No limit |
Reviews Monitoring (resend to Slack) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
Reviews Auto-Translation | ✅ Powered by GoogleTranslate | ✅ | ❌ (not available for basic plan) | ✅ (300 Reviews/month) | ❌ (not available for free plan) | ✅ |
Reviews Monitoring Customized Filter | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
Customized Integration | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
Reply to reviews | ❌ | ✅ | ❌ | ❌ (not available for small plan) | ❌ (not available for free plan) | ✅ |
Reviews Analytics or Reporting | ❌ | ❌ | ❌ (not available for basic plan) | ✅ | ✅ | ✅ |
Deploy with Gitub Repo Template 🚀🚀🚀
- no need host/server ✅
- no need environment requirement ✅
- no engineering background knowledge ✅
- only need configuration ✅
- total free ✅
Github Action Proivde 2,000+ mins/month for free. ZReviewTender will cost ~= 30s per time, default run every 6 hours will cost 4 times/day * 30s/per time * 30days = 60 mins/month
- make sure has Docker on your system.
- git clone this repo
git clone https://github.com/ZhgChgLi/ZReviewTender
cd /ZReviewTender
- build docker image
docker build -t zreviewtender:latest --build-arg CRON_SETTING="*/30 * * * *" --build-arg ZREVIEWTENDER_COMMAND="-r" .
- CRON_SETTING = crontab schedule setting
- ZREVIEWTENDER_COMMAND = ZReviewTender Command (Refer to the configuration block down below.)
- Refer to the configuration block down below and finish the configuration.
- run docker
docker run -v ./:/usr/src/app zreviewtender
- have fun!
- make sure you have Ruby in your environment (I use
2.6.5p114
) - make sure you have Bundle in your environment (I use
2.3.13
) - type
gem install ZReviewTender
in terminal
- MacOS comes with a System Ruby pre-installed, but we are NOT Recommend to use that, using rvm/rbenv's Ruby instead.
- install rbenv or rvm to manage Ruby environment
- install Ruby through rbenv/rym (you can install ruby version
2.6.X
) - change the systme ruby to rbenv/rvm's Ruby
- type
which ruby
in terminal to make sure current Ruby is NOT/usr/bin/ruby
- type
gem install ZReviewTender
in terminal
- Clone this repo
- Setup ruby environment
- run
bundle install
- execute with
bundle exec bin/ZReviewTender
ZReviewTender uses yaml file to config Apple/Google Review Bot Setting.
[Recommended] use ZReviewTender -i
generator apple.yml & android.yml config yml files.
- Reference the apple.example.yml example config yaml file.
(Please rename
apple.example.yml
toapple.yml
if you've downloaded from reference.) - fill configuration in yaml file:
Go to App Store Connect -> Keys -> App Store Connect API
appStoreConnectIssueID:
appStoreConnectP8PrivateKeyID & appStoreConnectP8PrivateKeyFilePath:
Create a new API Key:
- Name:
ZReviewTender
- Access:
App Manager
- appStoreConnectP8PrivateKeyID:
Key ID
- appStoreConnectP8PrivateKeyFilePath:
/AuthKey_XXXXXXXXXX.p8
, Download API Key and placed it to /config/ folder (releated path with config yml file)
appID:
appID: App Store Connect -> App Store -> General -> App Information -> Apple ID
- after filled out configuration in yaml file, rename
apple.example.yml
toapple.yml
Use Authenticating as a service accountAuthenticating as a service account for Google Releated Service
- follow the steps of Creating a service account in offcial documentation, to create a service account of GCP and download the GCP JSON Private Key.
- make sure the service account have the right access you need (e.g. Google Translate/Google Ancdroid Publisher API/Google Sheet...)
- Download the android.example.yml config yaml file. (Please rename
android.example.yml
toandroid.yml
if you've downloaded from reference.) - fill configuration in yaml file:
packageName:
packageName: find Android App packageName in Google Play Console -> Dashboard -> App
playConsoleDeveloperAccountID & playConsoleAppID:
find in Google Play Console -> Dashboard -> App -> Page URL:
keyFilePath:
Follow the GCP Started Document to created a Google Cloud Project Service Account and linked it to your Google Play Console, enable Google Play Android Developer API in Google Play Console -> Setup -> API Access.
- make sure the service account have the right access
keyFilePath: /gcp_key.json
the key path of GCP JSON Private Key, placed it to /config/ folder (releated path with config yml file).
- class:
FilterProcessor
, no need to chane, it's point to lib/Processors/FilterProcessor
.rb - enable: true/false enable this Processor or Not
- keywordsInclude: ["KEYWORD1","KEYWORD2"…] filter out the Review that contains those keywords
- ratingsInclude: [1,2…] 1~5 filter out the Review that contains rating
- territoriesInclude: ["zh-hant","TWN"…] filter out the Review that from those territories (Territor(TWN/JPN...) for Apple / Language(zh-hant,en...) For Android)
- class:
GoogleTranslateProcessor
, no need to chane, it's point to lib/Processors/GoogleTranslateProcessor
.rb - enable: true/false enable this Processor or Not
- googleTranslateAPIKeyFilePath:
/gcp_key.json
Google Translate GCP Service Account JSON Private Key File Path*.json
,placed it to /config/ folder (releated path with config yml file) - make sure the service account have the right access(Google Translate API)
- googleTranslateTargetLang:
zh-TW
Target translated language - googleTranslateTerritoriesExclude: ["zh-hant","TWN"…] (Territor(TWN/JPN...) for Apple or Language(zh-hant,en...) For Android review that didn't need to translate.
- class:
SlackProcessor
, no need to chane, it's point to lib/Processors/SlackProcessor
.rb - enable: true/false enable this Processor or Not
- slackTimeZoneOffset:
+08:00
timezone of display review created time - slackAttachmentGroupByNumber:
1
specify how many Reviews will group by in same Slack Message (in Attacment) - slackBotToken:
xoxb-xxxx-xxxx-xxxx
Slack Bot Token - slackBotTargetChannel:
CXXXXXX
Channel ID (Not Channel Name), and you need to add Slack Bot to this Channel - slackInCommingWebHookURL:
https://hooks.slack.com/services/XXXXX
the old send message to slack way, will deprecated.
Please note, this is a legacy custom integration - an outdated way for teams to integrate with Slack. These integrations lack newer features and they will be deprecated and possibly removed in the future. We do not recommend their use. Instead, we suggest that you check out their replacement: Slack apps.
ZReviewTender will use slackBotToken by default.
- class:
GoogleSheetProcessor
, no need to chane, it's point to lib/Processors/GoogleSheetProcessor
.rb - enable: true/false enable this Processor or Not
- googleSheetAPIKeyFilePath:
/gcp_key.json
Google Sheet GCP Service Account JSON Private Key File Path*.json
,placed it to /config/ folder (releated path with config yml file) - make sure the service account have the right access(Google Translate API)
- googleSheetTimeZoneOffset:
+08:00
timezone of display review created time - googleSheetInsertStyle.type: "append" # Google Sheet Insert type, append or insert
- googleSheetInsertStyle.at: 0 # required if type is insert, where index should insert at
- googleSheetInsertStyle.sheetID: null # required if type is insert, the sheet ID, you can get it on google sheet url: e.g. https://docs.google.com/spreadsheets/d/googleSpreadsheetID/edit#gid=sheetID
- googleSheetInsertStyle.sheetName: "Sheet1" # required if type is append, a.k.a google sheet tab name
- values: [] # Columns Data you can uses magic variable below to compose string.
%TITLE% for review's title
%BODY% for review's content
%RATING% for review's rating 1~5
%PLATFORM% for review's platform Apple or Android
%ID% for review's ID
%USERNAME% for review's reviewer username
%URL% for link to review
%TERRITORY% for review's territory (language for android e.g. zh-Hant, en)
%APPVERSION% for review's reviewer app version
%CREATEDDATE% for review's created date
- keywordsInclude: ["KEYWORD1","KEYWORD2"…] filter out the Review that contains those keywords you want's log to google sheet
- ratingsInclude: [1,2…] 1~5 filter out the Review that contains rating you want's log to google sheet
- territoriesInclude: ["zh-hant","TWN"…] filter out the Review that from those territories you want's log to google sheet (Territor(TWN/JPN...) for Apple / Language(zh-hant,en...) For Android)
*make sure you have add service account to your google sheet collaborate with edit permission.
- Clone this repo project (due to ZReviewTedner is a completely Gem, you can't modify it dynamically)
- Reference Processor.rb, make a copy and devlop the feature you want
initialize
config
: config yml parameterconfigFilePath
: config yml file pathbaseExecutePath
the path that user execute ZReviewTender
processReviews(reviews, platform)
- Input Function
- you will receive latest reviews list, you can decide what you want to do, e.g. transform or filter...
- Review Struct: lib/Models/Review.rb
- Remember return the result reviews, for next Processor uses
- Add your Processor & Processor Parameter needed to config.yml,
processors:
section - Test & Run!
- Done!
*processors are data flow chain and sort sensitive.
- set
enable
tofalse
or just remove that Processor Setting Block in config yml
if you're not install with Gems, you should use bundle exec ruby bin/ZReviewTender
to excute.
Generate config yml file
ZReviewTender -i
will generate apple.yml and android.yml in config/ folder.
Check Both Apple & Android App's latest Reviews
ZReviewTender -r
will uses apple.yml
and android.yml
in config
folder.
Check Both Apple & Android App's latest Reviews, specify Config YAML file path
ZReviewTender --run=CONFIG_FOLDER
Check Apple App's latest Reviews
ZReviewTender -a
will uses apple.yml
in config
folder.
Check Apple App's latest Reviews, specify Config YAML file path
ZReviewTender --apple=PATH_TO_APPLE_CONFIG_YAML_FILE
Check Android App's latest Reviews
ZReviewTender -g
will uses android.yml
in config
folder.
Check Android App's latest Reviews, specify Config YAML file path
ZReviewTender --googleAndroid=PATH_TO_ANDROID_CONFIG_YAML_FILE
Clean last check timestamp log(back to init state)
ZReviewTender -d
Show current ZReviewTender version
ZReviewTender -v
Upgrade ZReviewTender to latest release version(only RubyGem)
ZReviewTender -n
you will received an init success message in your Slack Channel!
ZReviewTender will also created latestCheckTimestamp/Apple, latestCheckTimestamp/Android to log ZReviewTender latest checked Review Timestamp and created execute.log for log excute error.
- You could use crontab or any schedule service to execute ZReviewTender periodicity
- e.g. in crontab:
15 */6 * * * ZReviewTender -r
- please note that, google api only allow retrieve the reviews that users have created or modified within the last week, so could not set the time period more than one week.
ZReviewTender App Reviews Automatic Bot
name: ZReviewTender
on:
workflow_dispatch:
schedule:
- cron: "15 */6 * * *" #check new review every 6 hour.
jobs:
ZReviewTender:
runs-on: ubuntu-latest
steps:
- name: ZReviewTender Automatic Bot
uses: ZhgChgLi/ZReviewTender@main
with:
command: '-r'
you can change command to others ZReviewTender's command.
This repository is for research purposes only, the use of this code is your responsibility.
- Code authors take NO responsibility and/or liability for how you choose to use any of the source code available here.
- By using any of the files available in this repository, you understand that you are AGREEING TO USE AT YOUR OWN RISK.
- ALL files available here are for EDUCATION and/or RESEARCH purposes ONLY.
Pinkoi.com is Asia's leading online marketplace for original design goods, digital creations, and workshop experiences.
- ZMarkupParser is a pure-Swift library that helps you to convert HTML strings to NSAttributedString with customized style and tags.
- ZPlayerCacher is a lightweight implementation of the AVAssetResourceLoaderDelegate protocol that enables AVPlayerItem to support caching streaming files.
- ZNSTextAttachment enables NSTextAttachment to download images from remote URLs, support both UITextView and UILabel.
- ZReviewTender is a tool for fetching app reviews from the App Store and Google Play Console and integrating them into your workflow.
- ZMediumToMarkdown is a powerful tool that allows you to effortlessly download and convert your Medium posts to Markdown format.
If you find this library helpful, please consider starring the repo or recommending it to your friends.
Feel free to open an issue or submit a fix/contribution via pull request. :)