Coder Social home page Coder Social logo

rogerluan / app-store-connect-notifier Goto Github PK

View Code? Open in Web Editor NEW
97.0 4.0 23.0 854 KB

Node.js app that sends App Store Connect notifications to Slack.

License: BSD 2-Clause "Simplified" License

Ruby 20.26% JavaScript 78.21% Dockerfile 1.41% Procfile 0.11%
hacktoberfest hacktoberfest2020 slack fastlane ruby-script nodejs bot

app-store-connect-notifier's Introduction

App Store Connect Notifier

Get those App Store Connect notifications delivered directly to Slack.

Latest Release Build Status Issues Follow on Twitter

View Demo · Report Bug · Request Feature


Intro

App Store Connect Notifier is a node.js app that fetches your app and build info directly from App Store Connect and posts changes in Slack as a bot. Since App Store Connect doesn't provide event webhooks (yet), these scripts use polling with the help of fastlane's Spaceship.

Preview

App Status

Build Status

Be notified when your builds are ready to be submitted!

Set Up

There are 2 versions of this service: a self-hosted version and a SaaS version — Statused.

While the self-hosted version is free, it requires you to host and maintain its server yourself. The SaaS version is a paid service, but it's fully managed and has a lot more features, such as support for Android apps, and a web dashboard to manage multiple apps, workflows, Slack channels, notification preferences, and more.

You can read more about the SaaS announcement here: #270

SaaS

You can use the SaaS version of this app, which evolved from this project, but eventually became a much more complete version of this simple tool. You can find out about it here:

Statused Social Banner

Forget about "When did release v2.1.3 go live again?" and "Is the app ready to be tested yet?"

Statused monitors App Store Connect and Google Play Store and sends you notifications about the status of your app release progress directly on Slack.

Learn more: statused.com

Self-hosted

If you prefer to host it yourself, you can follow the instructions below.

Prerequisites

You will need a Slack Bot to post updates on your behalf to your Slack workspace. If you still don't have one, check out this article on how to create a bot for your workspace.

Method 1: Heroku

Deploy

Method 2: Hosting Manually

Environment Variables

Be sure to set these to the appropriate values:

# Your App Store Connect username. Required when SPACESHIP_CONNECT_API_KEY is not used.
export ITC_USERNAME="[email protected]"

# Your App Store Connect password. Required if you're in a non-interactive environment. In interactive environments, it will ask for the password when executing and save it in Keychain.
export ITC_PASSWORD="your-app-store-connect-account-password"

# The [App Store Connect API key](https://developer.apple.com/documentation/appstoreconnectapi/creating_api_keys_for_app_store_connect_api). Use this when on a non-interactive environment and you have 2FA set up. When using this, neither ITC_USERNAME or ITC_PASSWORD are used.
export SPACESHIP_CONNECT_API_KEY='-----BEGIN PRIVATE KEY-----
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxx
-----END PRIVATE KEY-----'

# The App Store Connect API Issuer ID. Required when SPACESHIP_CONNECT_API_KEY is used
export SPACESHIP_CONNECT_API_ISSUER_ID='xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxx'

# The App Store Connect API Key ID. Required when SPACESHIP_CONNECT_API_KEY is used
export SPACESHIP_CONNECT_API_KEY_ID='xxxxxxxxxx'

# Optional: If you're in multiple teams, enter the IDs of your App Store Connect team here (comma separated).
export ITC_TEAM_IDS=132123123,456456456

# Comma-separated list of bundle identifiers of the apps you want these scripts to monitor. If this is not set, it will monitor all apps of your team.
export BUNDLE_IDENTIFIERS="com.apple.swift"

# Specify the channel you'd like the bot to post App Store Connect status updates. Don't forget to add the bot to this channel in Slack so it can post there. Required when BOT_SLACK_WEBHOOK_URL is not set.
export SLACK_CHANNEL_NAME="#ios-app-updates"

# Optional: Specify the channel you'd like the bot to post its uptime updates. Don't forget to add the bot to this channel in Slack so it can post there. If not provided, it won't post status updates. Not used when BOT_STATUS_SLACK_WEBHOOK_URL is set
export BOT_STATUS_SLACK_CHANNEL_NAME="#ios-bot-status-updates"

# The API token for your bot, provided by Slack. Required when BOT_SLACK_WEBHOOK_URL is not set.
export BOT_API_TOKEN="xoxb-123123123123-ASDASDASDASD-FGHFGHFGHFGH"

# The incoming webhook URL provided by Slack for your channel. When using this, SLACK_CHANNEL_NAME and BOT_API_TOKEN are not used.
export BOT_SLACK_WEBHOOK_URL="https://hooks.slack.com/services/XXXXXXXX/XXXXXXXX/XxxxXXXXXxxxxxxxxxxxx"

# Optional: Specify the incoming webhook URL for the channel you'd like the bot to post its uptime updates. When using this, BOT_STATUS_SLACK_CHANNEL_NAME is not used.
export BOT_STATUS_SLACK_WEBHOOK_URL="https://hooks.slack.com/services/XXXXXXXX/XXXXXXXX/XxxxXXXXXxxxxxxxxxxxx"

# How often the script should check for updates (in seconds). Required.
export POLL_TIME_IN_SECONDS=120

# How many builds do you want to track simultaneously? Defaults to 1, as you usually just want to track the latest build. Set to 0 if you're not interested in receiving status updates on the builds.
export NUMBER_OF_BUILDS=1

Method 3: Docker

Use environment variables similarly to Method 2

docker run \
  -e SPACESHIP_CONNECT_API_KEY="$(cat api_key.p8)" \
  -e SPACESHIP_CONNECT_API_ISSUER_ID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxx" \
  -e SPACESHIP_CONNECT_API_KEY_ID="xxxxxxxxxx" \
  -e BOT_SLACK_WEBHOOK_URL="https://hooks.slack.com/services/XXXXXXXX/XXXXXXXX/XxxxXXXXXxxxxxxxxxxxx" \
  rogerluan/app-store-connect-notifier:latest

Method 4: Docker Compose

Use environment variables similarly to Method 2

services:
  app-store-connect-notifier:
    container_name: app-store-connect-notifier
    hostname: app-store-connect-notifier
    image: rogerluan/app-store-connect-notifier
    environment:
      SPACESHIP_CONNECT_API_KEY: |
        -----BEGIN PRIVATE KEY-----
        xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        xxxxxxxxxxxxxx
        -----END PRIVATE KEY-----
      SPACESHIP_CONNECT_API_ISSUER_ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxx
      SPACESHIP_CONNECT_API_KEY_ID: xxxxxxxxxx
      BOT_SLACK_WEBHOOK_URL: https://hooks.slack.com/services/XXXXXXXX/XXXXXXXX/XxxxXXXXXxxxxxxxxxxxx
Install
bundle install
npm install
Store your App Store Connect password

You can use fastlane's CredentialsManager to store your password. Enter this command and it will prompt you for your password:

bundle exec fastlane fastlane-credentials add --username [email protected]
Using App Store Connect API

For more information on how to use SPACESHIP_CONNECT_API_KEY, SPACESHIP_CONNECT_API_ISSUER_ID and SPACESHIP_CONNECT_API_KEY_ID to skip 2FA authentication, check out Apple Documentation and Using App Store Connect API on fastlane.

Running
npm start

Or you can use the forever tool to keep it up indefinitely:

forever start src/poll-itc.js

Project Structure

fetch_app_status.rb

Ruby script that uses Spaceship to connect to App Store Connect. It then stdouts a JSON blob with your app info.

poll-itc.js

Node script to invoke the ruby script at certain intervals. It uses a key/value store to keep track of app status changes, and then invokes post-update.js once the status changes.

post-update.js

Node script that uses Slack's node.js SDK to send a message as a bot. It also calculates the number of hours since submission.

Troubleshooting

Why does my app hosted on Heroku reboots all the time?

Heroku does something called Dyno cycling at least once a day, and you can't prevent that from happening, unfortunately. Rebooting is fine, actually, except that you will lose all your database of app statuses that you collected since the last reboot. This means that we can't add nice features such as tracking the delta time between status changes (reliably) without persisting the information using an external service.

Vision

The long-term goal of this project is to retire itself once App Store Connect finally starts supporting webhooks.

Once the App Store Connect APIs support webhooks, if a 3rd party app is still needed to receive those webhooks and post to Slack (i.e. if Apple doesn't provide one), then this project will be updated to provide those features as well.

Credits

This app is heavily based on @erikvillegas's itunes-connect-slack. Most of the credit goes to him for figuring out the integration between ruby and javascript.

License

This project is open source and covered by a standard 2-clause BSD license. That means you have to mention Roger Oba as the original author of this code and reproduce the LICENSE text inside your app, repository, project or research paper.

app-store-connect-notifier's People

Contributors

caseycs avatar dependabot[bot] avatar johnf avatar probot-auto-merge[bot] avatar rogerluan avatar tahirmt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

app-store-connect-notifier's Issues

Replace iTunes Connect Credentials with App Store Connect API Token

With the introduction of the new App Store Connect APIs in June 2020 (beta), Apple now offers an official set of APIs for us to use. Once fastlane fully supports those, we should migrate from user & pass credentials to API Token credentials. This also resolves the problem of 2FA sessions.

Attachment Colors of Slack Messages Are Wrong

The colors of the attachments of the slack message broke in the latest App Store Connect API changes, because the statuses changed. Now they all display gray colors instead of red/yellow/green/etc

Error when fetching app latest version from App Store Connect

Description

This error is popping since September 3rd 2020:

/Users/rogerluan/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fastlane-2.159.0/spaceship/lib/spaceship/client.rb:719:in `parse_response': {"data"=>nil, "messages"=>{"warn"=>nil, "error"=>["Not Found"], "info"=>nil}, "statusCode"=>"ERROR"} (Spaceship::UnexpectedResponse)
	from /Users/rogerluan/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fastlane-2.159.0/spaceship/lib/spaceship/tunes/tunes_client.rb:456:in `app_version_data'
	from /Users/rogerluan/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fastlane-2.159.0/spaceship/lib/spaceship/tunes/tunes_client.rb:447:in `app_version'
	from /Users/rogerluan/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fastlane-2.159.0/spaceship/lib/spaceship/tunes/app_version.rb:291:in `find'
	from /Users/rogerluan/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fastlane-2.159.0/spaceship/lib/spaceship/tunes/application.rb:126:in `live_version'
	from /Users/rogerluan/.rbenv/versions/2.6.5/lib/ruby/gems/2.6.0/gems/fastlane-2.159.0/spaceship/lib/spaceship/tunes/application.rb:137:in `latest_version'

Preventing the app from running completely.

Use app store connect p8 key

spaceship supports the usage of the App Store connect api key instead of password for usage without a password. This will help with 2fa accounts.

Phased Rollout Notifications

Background

Apple has a phased rollout capability where it will automatically roll an app out to an increasing percentage of its audience whom use automatic app updates. The %'s are static and chosen by Apple, as a developer we can push it to 100% of users at any time during the rollout and we can also pause the rollout at anytime which stops any more users from getting the automatic update.

Request

When Apple changes the % of whom get the rollout, a notification should be sent like:
"App Name has rolled out to 5% of users"
"App Name has finished rollout and is available to 100% of users"

When a developer pushed a release to 100%, a notification should be sent like:
"App Name has been pushed to 100% of users"

When a developer paused a release, a notification should be sent like:
"The rollout of App Name has been paused at 5% of users"

When a developer resumes a release after being paused, a notification should be sent like:
"The rollout of App Name has been resumed. Currently at 5% of users"

Source

https://twitter.com/JamesSherlouk/status/1305287338826911745

Deploy to Heroku push Failed

Hello,

Tried deploying to Heroku and everything builds successful but the push step fails. pasted the error below

-----> Building on the Heroku-20 stack
-----> Using buildpacks:
       1. heroku/nodejs
       2. heroku/ruby
-----> Node.js app detected
       
-----> Creating runtime environment
       
       NPM_CONFIG_LOGLEVEL=error
       NODE_VERBOSE=false
       NODE_ENV=production
       NODE_MODULES_CACHE=true
       
-----> Installing binaries
       engines.node (package.json):  unspecified
       engines.npm (package.json):   unspecified (use default)
       
       Resolving node version 14.x...
       Downloading and installing node 14.18.1...
       Using default npm version: 6.14.15
       
-----> Installing dependencies
       Installing node modules
       added 117 packages in 2.357s
       
-----> Build
       
-----> Caching build
       - node_modules
       
-----> Pruning devDependencies
       removed 92 packages and audited 25 packages in 0.786s
       
       2 packages are looking for funding
         run `npm fund` for details
       
       found 0 vulnerabilities
       
       
-----> Build succeeded!
-----> Ruby app detected
-----> Installing bundler 2.2.21
-----> Removing BUNDLED WITH version in the Gemfile.lock
-----> Compiling Ruby
       Command: 'set -o pipefail; curl -L --fail --retry 5 --retry-delay 1 --connect-timeout 3 --max-time 30 https://s3-external-1.amazonaws.com/heroku-buildpack-ruby/heroku-20/ruby-2.6.5.tgz -s -o - | tar zxf - ' failed on attempt 1 of 3.
       Command: 'set -o pipefail; curl -L --fail --retry 5 --retry-delay 1 --connect-timeout 3 --max-time 30 https://s3-external-1.amazonaws.com/heroku-buildpack-ruby/heroku-20/ruby-2.6.5.tgz -s -o - | tar zxf - ' failed on attempt 2 of 3.
 !
 !     The Ruby version you are trying to install does not exist on this stack.
 !     
 !     You are trying to install ruby-2.6.5 on heroku-20.
 !     
 !     Ruby ruby-2.6.5 is present on the following stacks:
 !     
 !     - heroku-18
 !     
 !     Heroku recommends you use the latest supported Ruby version listed here:
 !     https://devcenter.heroku.com/articles/ruby-support#supported-runtimes
 !     
 !     For more information on syntax for declaring a Ruby version see:
 !     https://devcenter.heroku.com/articles/ruby-versions
 !
 !     Push rejected, failed to compile Ruby app.
 !     Push failed```

spaceship A required agreement is missing or has expired

Hi! Tried:

sudo bundle install
npm install

All is correct. But on starting the app with npm start:

Fetching latest app status...
There was a problem fetching the status of the app!
/Users/aturan23/apps/app-store-connect-notifier/.vendor/ruby/3.0.0/gems/fastlane-2.199.0/spaceship/lib/spaceship/connect_api/api_client.rb:226:in `handle_error': A required agreement is missing or has expired. - This request requires an in-effect agreement that has not been signed or has expired. (Spaceship::ProgramLicenseAgreementUpdated)
	from /Users/aturan23/apps/app-store-connect-notifier/.vendor/ruby/3.0.0/gems/fastlane-2.199.0/spaceship/lib/spaceship/client.rb:922:in `block in send_request'
	from /Users/aturan23/apps/app-store-connect-notifier/.vendor/ruby/3.0.0/gems/fastlane-2.199.0/spaceship/lib/spaceship/client.rb:677:in `with_retry'
	from /Users/aturan23/apps/app-store-connect-notifier/.vendor/ruby/3.0.0/gems/fastlane-2.199.0/spaceship/lib/spaceship/client.rb:918:in `send_request'
	from /Users/aturan23/apps/app-store-connect-notifier/.vendor/ruby/3.0.0/gems/fastlane-2.199.0/spaceship/lib/spaceship/client.rb:762:in `request'
	from /Users/aturan23/apps/app-store-connect-notifier/.vendor/ruby/3.0.0/gems/fastlane-2.199.0/spaceship/lib/spaceship/connect_api/api_client.rb:106:in `block in get'
	from /Users/aturan23/apps/app-store-connect-notifier/.vendor/ruby/3.0.0/gems/fastlane-2.199.0/spaceship/lib/spaceship/connect_api/api_client.rb:162:in `with_asc_retry'
	from /Users/aturan23/apps/app-store-connect-notifier/.vendor/ruby/3.0.0/gems/fastlane-2.199.0/spaceship/lib/spaceship/connect_api/api_client.rb:105:in `get'
	from /Users/aturan23/apps/app-store-connect-notifier/.vendor/ruby/3.0.0/gems/fastlane-2.199.0/spaceship/lib/spaceship/connect_api/testflight/testflight.rb:22:in `get_apps'
	from /Users/aturan23/.rvm/rubies/ruby-3.0.0/lib/ruby/3.0.0/forwardable.rb:238:in `get_apps'
	from /Users/aturan23/apps/app-store-connect-notifier/.vendor/ruby/3.0.0/gems/fastlane-2.199.0/spaceship/lib/spaceship/connect_api/models/app.rb:74:in `all'
	from /Users/aturan23/apps/app-store-connect-notifier/.vendor/ruby/3.0.0/gems/fastlane-2.199.0/spaceship/lib/spaceship/connect_api/models/app.rb:80:in `find'
	from src/fetch_app_status.rb:91:in `block in get_app_version_from'
	from src/fetch_app_status.rb:90:in `each'
	from src/fetch_app_status.rb:90:in `get_app_version_from'
	from src/fetch_app_status.rb:119:in `block in <main>'
	from src/fetch_app_status.rb:117:in `each'
	from src/fetch_app_status.rb:117:in `<main>'

Week ago all worked fine. But now not

Play Store Support

@rogerluan Would you have any interest in extending this at all to perform similar actions for the Google play store?
Asking before I do a PR, otherwise I'll fork and create a sibling project that just does the google bits

Is Optional Bundle Identifier?

In fetch_app_status.rb using environment for bundle_identifier

bundle_id = ENV["BUNDLE_IDENTIFIER"]

but , in README.md has no content.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.