Проект Python із 30 рядків коду: як налаштувати SMS-сповіщення, коли ваш улюблений Twitcher транслює

Привіт усім :) Сьогодні я розпочинаю нову серію дописів, спеціально орієнтованих на початківців Python. Концепція досить проста: я зроблю цікавий проект із якомога меншою кількістю рядків коду і спробую якомога більше нових інструментів.

Наприклад, сьогодні ми навчимося використовувати Twilio API, Twitch API, і ми побачимо, як розгорнути проект на Heroku. Я покажу вам, як ви можете мати власний SMS-сповіщувач "Twitch Live", у 30 рядків кодів, і за 12 центів на місяць.

Обов’язкова умова : Вам потрібно лише знати, як запустити Python на своїй машині та деякі основні команди в git (коміт і push). Якщо вам потрібна допомога з цим, я можу порадити вам ці 2 статті:

Посібник з встановлення та налаштування Python 3

Остаточний підручник з командування Git для початківців від Адріана Хаддіна.

Що ви дізнаєтесь :

  • API Twitch
  • API Twilio
  • Розгортання на Heroku
  • Налаштування планувальника на Heroku

Що ви будете будувати:

Технічні характеристики прості: ми хочемо отримувати SMS, як тільки певний Twitcher запускає пряму трансляцію. Ми хочемо знати, коли ця людина вийде в ефір і коли вона залишить трансляцію. Ми хочемо, щоб вся ця справа працювала сама собою, цілий день.

Ми розділимо проект на 3 частини. По-перше, ми побачимо, як програмно дізнатись, чи певний Twitcher перебуває в мережі. Тоді ми побачимо, як отримати SMS, коли це станеться. На завершення ми побачимо, як змусити цей фрагмент коду запускатись кожні X хвилин, щоб ми ніколи не пропустили жодного моменту життя нашого улюбленого стримера.

Це Твітчер у прямому ефірі?

Щоб дізнатись, чи працює Twitcher, ми можемо зробити дві речі: ми можемо перейти до URL-адреси Twitcher і спробувати з’ясувати, чи є там значок «Live».

Цей процес включає вишкрібання, і його непросто здійснити в Python менш ніж за 20 рядків коду. Twitch запускає багато коду JS, а простого request.get () буде недостатньо.

Щоб скрепінг працював, у цьому випадку нам потрібно буде зішкребти цю сторінку всередині Chrome, щоб отримати такий самий вміст, як ви бачите на скріншоті. Це можливо, але це займе набагато більше 30 рядків коду. Якщо ви хочете дізнатись більше, не соромтеся перевіряти моє нещодавнє скребування веб-сторінок, не отримуючи заблокованого посібника. (Нещодавно я запустив ScrapingBee, інструмент веб-вишкрібання, звідси мої знання в цій галузі;))

Тож замість того, щоб намагатись зішкребти Twitch, ми використаємо їх API. Для тих, хто не знайомий з цим терміном, API - це програмний інтерфейс, який дозволяє веб-сайтам надавати свої функції та дані кожному, переважно розробникам. У випадку Twitch їх API виставляється через HTTP, відьма означає, що ми можемо мати багато інформації та робити багато речей, просто зробивши простий HTTP-запит.

Отримайте свій ключ API

Для цього потрібно спочатку створити ключ Twitch API. Багато служб забезпечують автентифікацію своїх API, щоб гарантувати, що ніхто не зловживає ними, або обмежити доступ певних функцій до певних людей.

Виконайте ці кроки, щоб отримати ключ API:

  • Створіть обліковий запис Twitch
  • Тепер створіть обліковий запис розробника Twitch -> праворуч "Реєстрація за допомогою Twitch"
  • Перейдіть на свою "інформаційну панель" після входу в систему
  • "Зареєструйте свою заявку"
  • Ім'я -> Що завгодно, URL-адреса переадресації Oauth -> // localhost, Категорія -> Що завгодно

Тепер ви повинні побачити внизу екрана свій ідентифікатор клієнта. Зберігайте це на потім.

Це потокове передавання Twitcher зараз?

З вашим ключем API в руці, тепер ми можемо запитувати API Twitch, щоб отримати потрібну інформацію, тому давайте почнемо кодувати. Наступний фрагмент просто використовує API Twitch з правильними параметрами та друкує відповідь.

# requests is the go to package in python to make http request # //2.python-requests.org/en/master/ import requests # This is one of the route where Twich expose data, # They have many more: //dev.twitch.tv/docs endpoint = "//api.twitch.tv/helix/streams?" # In order to authenticate we need to pass our api key through header headers = {"Client-ID": ""} # The previously set endpoint needs some parameter, here, the Twitcher we want to follow # Disclaimer, I don't even know who this is, but he was the first one on Twich to have a live stream so I could have nice examples params = {"user_login": "Solary"} # It is now time to make the actual request response = request.get(endpoint, params=params, headers=headers) print(response.json())

Результат повинен виглядати так:

{ 'data':[ { 'id':'35289543872', 'user_id':'174955366', 'user_name':'Solary', 'game_id':'21779', 'type':'live', 'title':"Wakz duoQ w/ Tioo - GM 400LP - On récupère le chall après les -250LP d'inactivité !", 'viewer_count':4073, 'started_at':'2019-08-14T07:01:59Z', 'language':'fr', 'thumbnail_url':'//static-cdn.jtvnw.net/previews-ttv/live_user_solary-{width}x{height}.jpg', 'tag_ids':[ '6f655045-9989-4ef7-8f85-1edcec42d648' ] } ], 'pagination':{ 'cursor':'eyJiIjpudWxsLCJhIjp7Ik9mZnNldCI6MX19' } }

Цей формат даних називається JSON і легко читається. dataОб'єкт являє собою масив , який містить всі активні в даний момент потоки. Ключ typeгарантує поточність потоку live. В іншому випадку цей ключ буде порожнім (наприклад, у разі помилки).

So if we want to create a boolean variable in Python that stores whether the current user is streaming, all we have to append to our code is:

json_response = response.json() # We get only streams streams = json_response.get('data', []) # We create a small function, (a lambda), that tests if a stream is live or not is_active = lambda stream: stream.get('type') == 'live' # We filter our array of streams with this function so we only keep streams that are active streams_active = filter(is_active, streams) # any returns True if streams_active has at least one element, else False at_least_one_stream_active = any(streams_active) print(at_least_one_stream_active)

At this point, at_least_one_stream_active is True when your favourite Twitcher is live.

Let's now see how to get notified by SMS.

Send me a text, NOW!

So to send a text to ourselves, we will use the Twilio API. Just go over there and create an account. When asked to confirm your phone number, please use the phone number you want to use in this project. This way you'll be able to use the $15 of free credit Twilio offers to new users. At around 1 cent a text, it should be enough for your bot to run for one year.

If you go on the console, you'll see your Account SID and your Auth Token , save them for later. Also click on the big red button "Get My Trial Number", follow the step, and save this one for later too.

Sending a text with the Twilio Python API is very easy, as they provide a package that does the annoying stuff for you. Install the package with pip install Twilio and just do:

from twilio.rest import Client client = Client(, ) client.messages.create( body="Test MSG",from_=,to=) 

And that is all you need to send yourself a text, amazing right?

Putting everything together

We will now put everything together, and shorten the code a bit so we manage to say under 30 lines of Python code.

import requests from twilio.rest import Client endpoint = "//api.twitch.tv/helix/streams?" headers = {"Client-ID": ""} params = {"user_login": "Solary"} response = request.get(endpoint, params=params, headers=headers) json_response = response.json() streams = json_response.get('data', []) is_active = lambda stream:stream.get('type') == 'live' streams_active = filter(is_active, streams) at_least_one_stream_active = any(streams_active) if at_least_one_stream_active: client = Client(, ) client.messages.create(body='LIVE !!!',from_=,to=)

Avoiding double notifications

This snippet works great, but should that snippet run every minute on a server, as soon as our favorite Twitcher goes live we will receive an SMS every minute.

We need a way to store the fact that we were already notified that our Twitcher is live and that we don't need to be notified anymore.

The good thing with the Twilio API is that it offers a way to retrieve our message history, so we just have to retrieve the last SMS we sent to see if we already sent a text notifying us that the twitcher is live.

Here what we are going do to in pseudocode:

if favorite_twitcher_live and last_sent_sms is not live_notification: send_live_notification() if not favorite_twitcher_live and last_sent_sms is live_notification: send_live_is_over_notification()

This way we will receive a text as soon as the stream starts, as well as when it is over. This way we won't get spammed - perfect right? Let's code it:

# reusing our Twilio client last_messages_sent = client.messages.list(limit=1) last_message_id = last_messages_sent[0].sid last_message_data = client.messages(last_message_id).fetch() last_message_content = last_message_data.body

Let's now put everything together again:

import requests from twilio.rest import Client client = Client(, ) endpoint = "//api.twitch.tv/helix/streams?" headers = {"Client-ID": ""} params = {"user_login": "Solary"} response = request.get(endpoint, params=params, headers=headers) json_response = response.json() streams = json_response.get('data', []) is_active = lambda stream:stream.get('type') == 'live' streams_active = filter(is_active, streams) at_least_one_stream_active = any(streams_active) last_messages_sent = client.messages.list(limit=1) if last_messages_sent: last_message_id = last_messages_sent[0].sid last_message_data = client.messages(last_message_id).fetch() last_message_content = last_message_data.body online_notified = "LIVE" in last_message_content offline_notified = not online_notified else: online_notified, offline_notified = False, False if at_least_one_stream_active and not online_notified: client.messages.create(body='LIVE !!!',from_=,to=) if not at_least_one_stream_active and not offline_notified: client.messages.create(body='OFFLINE !!!',from_=,to=)

And voilà!

You now have a snippet of code, in less than 30 lines of Python, that will send you a text a soon as your favourite Twitcher goes Online / Offline and without spamming you.

We just now need a way to host and run this snippet every X minutes.

The quest for a host

To host and run this snippet we will use Heroku. Heroku is honestly one of the easiest ways to host an app on the web. The downside is that it is really expensive compared to other solutions out there. Fortunately for us, they have a generous free plan that will allow us to do what we want for almost nothing.

If you don't already, you need to create a Heroku account. You also need to download and install the Heroku client.

You now have to move your Python script to its own folder, don't forget to add a requirements.txt file in it. The content of the latter begins:

requests twilio

cd into this folder and just do a `heroku create --app `.

If you go on your app dashboard you'll see your new app.

We now need to initialize a git repo and push the code on Heroku:

git init heroku git:remote -a  git add . git commit -am 'Deploy breakthrough script' git push heroku master

Your app is now on Heroku, but it is not doing anything. Since this little script can't accept HTTP requests, going to .herokuapp.com won't do anything. But that should not be a problem.

To have this script running 24/7 we need to use a simple Heroku add-on call "Heroku Scheduler". To install this add-on, click on the "Configure Add-ons" button on your app dashboard.

Then, on the search bar, look for Heroku Scheduler:

Click on the result, and click on "Provision"

If you go back to your App dashboard, you'll see the add-on:

Click on the "Heroku Scheduler" link to configure a job. Then click on "Create Job". Here select "10 minutes", and for run command select `python .py`. Click on "Save job".

While everything we used so far on Heroku is free, the Heroku Scheduler will run the job on the $25/month instance, but prorated to the second. Since this script approximately takes 3 seconds to run, for this script to run every 10 minutes you should just have to spend 12 cents a month.

Ideas for improvements

I hope you liked this project and that you had fun putting it into place. In less than 30 lines of code, we did a lot, but this whole thing is far from perfect. Here are a few ideas to improve it:

  • Send yourself more information about the current streaming (game played, number of viewers ...)
  • Send yourself the duration of the last stream once the twitcher goes offline
  • Don't send you a text, but rather an email
  • Monitor multiple twitchers at the same time

Do not hesitate to tell me in the comments if you have more ideas.

Conclusion

I hope that you liked this post and that you learned things reading it. I truly believe that this kind of project is one of the best ways to learn new tools and concepts, I recently launched a web scraping API where I learned a lot while making it.

Please tell me in the comments if you liked this format and if you want to do more.

I have many other ideas, and I hope you will like them. Do not hesitate to share what other things you build with this snippet, possibilities are endless.

Happy Coding.

Pierre

Don't want to miss my next post:

You can subscribe here to my newsletter.