Skip to content

Instantly share code, notes, and snippets.

@dvinciguerra
Last active September 26, 2023 21:44
Show Gist options
  • Save dvinciguerra/cc28c4574b97157485f7e509366f2288 to your computer and use it in GitHub Desktop.
Save dvinciguerra/cc28c4574b97157485f7e509366f2288 to your computer and use it in GitHub Desktop.
Twitch cli to check if channel is online without accessing browser or receive a push notification
# frozen_string_literal: true
require 'faraday'
require 'json'
require 'logger'
require 'oga'
require 'pastel'
module Twitch
module PageLoader
private
def page
@page ||= Faraday.get(@url)
end
end
module PageParser
private
def dom
@dom ||= Oga.parse_html(page.body || '') if page.success?
end
end
class Channel
include PageLoader
include PageParser
attr_reader :url, :name
def initialize(name)
@name = name
@url = "https://www.twitch.tv/#{name}"
end
def self.open(name)
new(name)
end
def self.from_url(url)
new(url.split('/').last)
end
def live?
payload.dig(0, :publication, :isLiveBroadcast) || false
end
def payload
@payload ||=
begin
raw = dom.css('script[type="application/ld+json"]').first&.text || '{}'
JSON.parse(raw, symbolize_names: true)
end
end
end
end
# USAGE:
channels = %w[
alanzoka alexisdino mrfalll calango galaxyyk
]
def status_description_for(channel)
p = Pastel.new
time = p.inverse("[#{Time.now}]")
title = "#{channel.name} ( #{channel.url} )"
status = channel.live? ? p.green('live') : p.red('offline')
"#{time} Channel #{title} is #{status}!"
end
channels.each do |channel_name|
channel = Twitch::Channel.open(channel_name)
puts status_description_for(channel)
end
# SPEC
exit unless ENV['SPECS'] == 'true'
require 'rspec/autorun'
RSpec.describe Twitch::Channel do
describe '.from_url' do
subject(:instance) { described_class.from_url('https://www.twitch.tv/alanzoka') }
it 'returns a channel object' do
expect(instance).to be_a(described_class)
end
end
describe '.open' do
subject(:instance) { described_class.open('alanzoka') }
it 'returns a channel object' do
expect(instance).to be_a(described_class)
end
it 'sets the channel name' do
expect(instance.name).to eq('alanzoka')
end
it 'sets the channel url' do
expect(instance.url).to eq('https://www.twitch.tv/alanzoka')
end
it 'sets the channel payload' do
expect(instance.payload).to include(kind_of Hash)
end
end
describe '#live?' do
context 'when the channel is live' do
it 'returns true' do
expect(described_class.open('alanzoka').live?).to eq(true)
end
end
context 'when the channel is offline' do
it 'returns false' do
expect(described_class.open('carolschmitt').live?).to eq(false)
end
end
context 'when the channel not exists' do
it 'returns false' do
expect(described_class.open('xundachannelmagicunicorn').live?).to eq(false)
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment