micalevisk / twitchtv-channel-notifier

Use GitHub workflow scheduler to notify via Telegram bot when some channel on https://twitch.tv went live. Working demo: https://t.me/codigofaladolive
3 stars 1 forks source link

Migrate to Twitch Webhooks API #3

Open micalevisk opened 4 years ago

micalevisk commented 4 years ago

To replace the current long polling technique just subscribe to the topic stream changed and notify when data.length > 0 (from notify request payload) and the date saved on some sort of storage file is not the same as data.started_at (since there is no way to filter only stream goes online event)

This will increase notification reliability, introduces realtime capabilities and decrease the usage of GitHub Actions quota

But GH Actions as storage can no longer be used due to webhook callback constraint (Vercel Now, Netlify, MongoDB Stitch, Supabase Function & storage. And keeping state between serveless function invocations will be a problem. To solve this we can use the free tier of Upstash (Redis-as-a-service), or a Database-as-a-service like: mLab, FaunaDB cloud, Railway, PlanetScale, or even the free tier of Qovery to host the entire Nodejs app + using Redis as the main database.

Maybe we can use External events: repository_dispatch (via GitHub API) to trigger the workflow run that will use an artifact to keep the state. See Async workflows with repository dispatch - GitHub Satellite 2020

GH Actions could be used to renew the webhook subscriptions since "All subscriptions have an expiration time, which cannot exceed 10 days."

Besides that, we'll can implement a notification for multiple Twitch channels and update the message sent by the bot as well :smiley:

Note that we're looking for a more dependecy-free and slim solution here to reduce the serverless cold start latency -- https://moiva.io to rescue!


The happy path workflow will be somewhat like this:

  • Client: our temporary HTTP client just send a subscription request (besides the fact that subscriptions should be renew due to its expiration time)
  • Helix API: https://api.twitch.tv/helix endpoint
  • Twitch: the twitch webhook server
  • Server: our serverless function that will be used as webhook (hub.callback X value in 1, following this spec)

sequence diagram


TODO to close this issue


Example of incoming request from Twitch (step 5):

req url = '/'
req method = 'POST'
req headers = {
  host: 'c56b8fe5.ngrok.io',
  'user-agent': 'Go-http-client/1.1',
  connection: 'close',
  'content-length': '559',
  'content-type': 'application/json; charset=utf-8',
  link: '<https://api.twitch.tv/helix/webhooks/hub>; rel="hub", <https://api.twitch.tv/helix/streams?user_id=433615460>; rel="self"',
  'twitch-notification-id': '88429811-567d-4cfa-85a3-b37b88abe65f',
  'twitch-notification-retry': '0',
  'twitch-notification-timestamp': '2020-05-02T20:03:23Z',
  'x-hub-signature': 'sha256=XYZABC',
  'accept-encoding': 'gzip',
  'x-forwarded-for': '34.218.218.240'
}

{
  data: [
    {
      game_id: '509670',
      id: '1438466417',
      language: 'pt',
      started_at: '2020-05-02T20:00:06Z',
      tag_ids: [Array],
      thumbnail_url: 'https://static-cdn.jtvnw.net/previews-ttv/live_user_codigofalado-{width}x{height}.jpg',
      title: '[BR] Criando um Timer com Vue.js + Novos MEMEs no Canal',
      type: 'live',
      user_id: '433615460',
      user_name: 'CodigoFalado',
      viewer_count: 57
    }
  ]
}
micalevisk commented 4 years ago

For now I'm testing the feasibility of this. Soon I'll be prototyping the new design.