Setup CI/CD
This commit is contained in:
7
.github/dependabot.yml
vendored
Normal file
7
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
version: 2
|
||||
updates:
|
||||
# Maintain dependencies for GitHub Actions
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
50
.github/workflows/build-and-deploy.yml
vendored
Normal file
50
.github/workflows/build-and-deploy.yml
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
name: Build docker image
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
|
||||
jobs:
|
||||
Build-Docker-Image:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- id: repository_name
|
||||
uses: ASzc/change-string-case-action@v6
|
||||
with:
|
||||
string: ${{ github.repository }}
|
||||
|
||||
-
|
||||
name: Login to ghcr.io
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
-
|
||||
name: Build and push
|
||||
id: docker_build
|
||||
uses: docker/build-push-action@v6
|
||||
env:
|
||||
IMAGE: ${{ steps.repository_name.outputs.lowercase }}
|
||||
with:
|
||||
push: true
|
||||
platforms: linux/amd64
|
||||
tags: ghcr.io/${{ env.IMAGE }}:latest
|
||||
context: .
|
||||
file: ./docker/Dockerfile
|
||||
|
||||
-
|
||||
name: Invoke deployment hook
|
||||
uses: joelwmale/webhook-action@master
|
||||
with:
|
||||
url: ${{ secrets.WEBHOOK_URL }}
|
||||
23
docker/Dockerfile
Normal file
23
docker/Dockerfile
Normal file
@@ -0,0 +1,23 @@
|
||||
FROM rust:bullseye AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN cargo build --release --bin telegram-twitch-notifier
|
||||
|
||||
|
||||
FROM debian:bullseye-slim
|
||||
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y openssl ca-certificates curl jq \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN update-ca-certificates
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY --from=builder /app/target/release/telegram-twitch-notifier /usr/local/bin
|
||||
|
||||
CMD ["/usr/local/bin/telegram-twitch-notifier"]
|
||||
@@ -1,12 +1,12 @@
|
||||
pub mod bot;
|
||||
pub mod config;
|
||||
pub mod subscription_manager;
|
||||
pub mod telegram_bot;
|
||||
pub mod twitch_webhook;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use bot::start_bot;
|
||||
use subscription_manager::SubscriptionManager;
|
||||
use telegram_bot::start_telegram_bot;
|
||||
use twitch_webhook::start_twitch_webhook;
|
||||
|
||||
#[tokio::main]
|
||||
@@ -15,8 +15,10 @@ async fn main() {
|
||||
|
||||
subscription_manager.init().await;
|
||||
|
||||
tokio::time::sleep(tokio::time::Duration::from_secs(10)).await;
|
||||
|
||||
let (_, webhook_result) = tokio::join!(
|
||||
start_bot(subscription_manager.clone()),
|
||||
start_telegram_bot(subscription_manager.clone()),
|
||||
start_twitch_webhook(subscription_manager)
|
||||
);
|
||||
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
use std::{error::Error, sync::Arc};
|
||||
|
||||
use teloxide::{
|
||||
Bot,
|
||||
adaptors::throttle::Limits,
|
||||
dispatching::{HandlerExt, dialogue::GetChatId},
|
||||
Bot as OriginBot,
|
||||
adaptors::{CacheMe, Throttle, throttle::Limits},
|
||||
dispatching::{HandlerExt, UpdateFilterExt as _, dialogue::GetChatId},
|
||||
dptree::{self, Handler},
|
||||
macros::BotCommands,
|
||||
prelude::{Dispatcher, LoggingErrorHandler, Requester, RequesterExt},
|
||||
types::{BotCommand, Message},
|
||||
types::{BotCommand, Message, Update},
|
||||
update_listeners::webhooks,
|
||||
};
|
||||
|
||||
use crate::{config::CONFIG, subscription_manager::SubscriptionManager};
|
||||
|
||||
pub type Bot = CacheMe<Throttle<OriginBot>>;
|
||||
|
||||
pub type BotHandlerInternal = Result<(), Box<dyn Error + Send + Sync>>;
|
||||
type BotHandler = Handler<
|
||||
'static,
|
||||
@@ -32,11 +34,11 @@ enum Command {
|
||||
}
|
||||
|
||||
pub async fn help_message_handler(bot: Bot, message: Message) -> BotHandlerInternal {
|
||||
const HELP_MESSAGE: &str = r#"""
|
||||
const HELP_MESSAGE: &str = r#"
|
||||
Welcome!
|
||||
|
||||
This bot allow you to subscribe to receive start stream notifications.
|
||||
"""#;
|
||||
"#;
|
||||
|
||||
match bot
|
||||
.send_message(message.chat_id().unwrap(), HELP_MESSAGE)
|
||||
@@ -86,11 +88,10 @@ pub async fn unsubscribe_handler(
|
||||
}
|
||||
|
||||
pub async fn get_handler() -> BotHandler {
|
||||
dptree::entry().branch(dptree::entry().filter_command::<Command>().endpoint(
|
||||
|bot: Bot,
|
||||
message: Message,
|
||||
command: Command,
|
||||
subscription_manager: Arc<SubscriptionManager>| async move {
|
||||
dptree::entry().branch(
|
||||
Update::filter_message()
|
||||
.filter_command::<Command>()
|
||||
.endpoint(|bot, message, command, subscription_manager| async move {
|
||||
match command {
|
||||
Command::Start | Command::Help => help_message_handler(bot, message).await,
|
||||
Command::Subscribe(username) => {
|
||||
@@ -100,8 +101,8 @@ pub async fn get_handler() -> BotHandler {
|
||||
unsubscribe_handler(bot, message, subscription_manager, username).await
|
||||
}
|
||||
}
|
||||
},
|
||||
))
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
pub async fn get_commands() -> Vec<BotCommand> {
|
||||
@@ -125,8 +126,8 @@ pub async fn get_commands() -> Vec<BotCommand> {
|
||||
]
|
||||
}
|
||||
|
||||
pub async fn start_bot(subscription_manager: Arc<SubscriptionManager>) {
|
||||
let bot = Bot::new(CONFIG.bot_token.clone())
|
||||
pub async fn start_telegram_bot(subscription_manager: Arc<SubscriptionManager>) {
|
||||
let bot = OriginBot::new(CONFIG.bot_token.clone())
|
||||
.throttle(Limits::default())
|
||||
.cache_me();
|
||||
|
||||
@@ -141,7 +142,10 @@ pub async fn start_bot(subscription_manager: Arc<SubscriptionManager>) {
|
||||
|
||||
let addr = ([0, 0, 0, 0], CONFIG.telegram_webhook_port).into();
|
||||
let url = CONFIG.telegram_webhook_url.parse().unwrap();
|
||||
let update_listener = webhooks::axum(bot, webhooks::Options::new(addr, url))
|
||||
let update_listener = webhooks::axum(
|
||||
bot,
|
||||
webhooks::Options::new(addr, url).path("/telegram/".to_string()),
|
||||
)
|
||||
.await
|
||||
.expect("Couldn't setup webhook");
|
||||
|
||||
@@ -194,13 +194,20 @@ impl TwitchWebhookServer {
|
||||
.await;
|
||||
}
|
||||
|
||||
pub async fn subscribe(&self, streamer: String) {
|
||||
let _ = eventsub_register(
|
||||
pub async fn subscribe(&self, streamer: String) -> bool {
|
||||
match eventsub_register(
|
||||
self.app_access_token.clone(),
|
||||
streamer,
|
||||
streamer.clone(),
|
||||
format!("{}/twitch/eventsub/", CONFIG.twitch_webhook_url),
|
||||
)
|
||||
.await;
|
||||
.await
|
||||
{
|
||||
Ok(_) => true,
|
||||
Err(err) => {
|
||||
eprintln!("Error subscribing to {}: {}", streamer, err);
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn check_subscriptions(&self) {
|
||||
@@ -218,12 +225,13 @@ impl TwitchWebhookServer {
|
||||
let is_subscribed = self.subscribed_to.read().await.contains(&streamer);
|
||||
|
||||
if !is_subscribed {
|
||||
self.subscribe(streamer.clone()).await;
|
||||
if self.subscribe(streamer.clone()).await {
|
||||
self.subscribed_to.write().await.push(streamer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tokio::time::sleep(tokio::time::Duration::from_secs(60)).await;
|
||||
tokio::time::sleep(tokio::time::Duration::from_secs(5)).await;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user