Last active
September 26, 2023 21:44
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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