Skip to content

Commit

Permalink
Add slack_bot. (#1468)
Browse files Browse the repository at this point in the history
  • Loading branch information
dvc94ch authored Jan 30, 2025
1 parent 707fe55 commit 7b2afd4
Show file tree
Hide file tree
Showing 6 changed files with 252 additions and 10 deletions.
72 changes: 72 additions & 0 deletions .github/workflows/merge-docker-slack-bot.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: Build Docker slack bot
on:
push:
paths:
- '.github/workflows/merge-docker-slack-bot.yaml'
- 'analog-gmp/**'
- 'config/subxt/**'
- 'primitives/**'
- 'tc-subxt/**'
- 'tc-cli/**'
- 'Cargo.toml'
- 'Cargo.lock'
- 'rust-toolchain.toml'
branches:
- 'development'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
DOCKER_REPO: analoglabs/slack-bot
jobs:
set-tags:
name: Get & set tags
runs-on: ubuntu-latest
outputs:
commit_hash: ${{ steps.get-sha.outputs.sha }}
commit_hash8: ${{ steps.get-sha.outputs.sha8 }}
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Get SHA
id: get-sha
run: |
sha=$(git log -1 --format='%H')
echo "sha=$sha" >> $GITHUB_OUTPUT
echo "sha8=$(git log -1 --format='%H' | cut -c1-8)" >> $GITHUB_OUTPUT
echo "SHA commit:" $sha
build-binary:
name: Build Docker image
needs: ["set-tags"]
runs-on: ["self-hosted", "container"]
steps:
- name: Fetch latest code
uses: actions/checkout@v3
with:
submodules: recursive
- name: Setup Cargo
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: stable
target: x86_64-unknown-linux-musl,wasm32-unknown-unknown
components: rust-src
- name: Install musl deps
run: sudo apt-get update && sudo apt-get install -y musl-tools
- name: Rust cache
uses: Swatinem/rust-cache@v2
- name: Build slack-bot
run: cargo build --profile testnet -p tc-cli --target x86_64-unknown-linux-musl --features testnet,develop
- name: Copy bin
run: cp -r target/x86_64-unknown-linux-musl/testnet/slack_bot slack-bot-bin
- name: Build and push
uses: ./.github/actions/buildah-action
with:
image_name: ${{ env.DOCKER_REPO }}
containerfile: ./config/docker/Dockerfile.slack-bot-release
context: .
volume: ${{ github.workspace }}/target:/build/target
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
registry: docker.io
push: 'true'
tags: ${{ needs.set-tags.outputs.commit_hash8 }},latest
82 changes: 78 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions config/docker/Dockerfile.slack-bot-release
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM ubuntu:22.04
WORKDIR /app

COPY slack-bot-bin slack-bot

ENTRYPOINT ["/app/slack-bot"]
2 changes: 1 addition & 1 deletion config/docker/Dockerfile.tc-cli-release
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ RUN apt update && apt install -y wget
RUN wget -O /app/foundry.tar.gz https://github.com/foundry-rs/foundry/releases/download/nightly/foundry_nightly_linux_amd64.tar.gz
RUN tar -xvzf /app/foundry.tar.gz -C /usr/local/bin

ENTRYPOINT ["/app/tc-cli"]
ENTRYPOINT ["/app/tc-cli"]
11 changes: 6 additions & 5 deletions tc-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ repository.workspace = true

[dependencies]
anyhow.workspace = true
axum = "0.8.1"
clap.workspace = true
csv = "1.3.0"
csv_to_table = "0.6.0"
dotenv = "0.15.0"
futures.workspace = true
gmp.workspace = true
Expand All @@ -20,21 +22,20 @@ log.workspace = true
num-bigint = "0.4.6"
num-rational = "0.4.2"
num-traits = "0.2.19"
polkadot-sdk = { workspace = true, features = ["sp-runtime"]}
reqwest = { version = "0.12.7", default-features = false, features = ["json", "rustls-tls-native-roots"] }
rustls = { version = "0.23", features = ["ring"], default-features = false }
scale-codec.workspace = true
serde = { workspace = true, features = ["derive"] }
serde_yaml = "0.9.34"
slack-morphism = { version = "2.8.0", features = ["axum", "hyper"] }
surf = { version = "2.3.2", default-features = false, features = [ "h1-client-rustls" ] }
tabled = "0.16.0"
tc-subxt.workspace = true
scale-codec.workspace = true
polkadot-sdk = { workspace = true, features = ["sp-runtime"]}
time-primitives = { workspace = true, default-features = true }
tokio = { workspace = true, features = [ "macros", "rt-multi-thread", "signal" ]}
tracing.workspace = true
tracing-subscriber = "0.3.18"
csv_to_table = "0.6.0"
slack-morphism = { version = "2.8.0", features = ["hyper"] }
rustls = { version = "0.23", features = ["ring"], default-features = false }

[features]
testnet = [
Expand Down
89 changes: 89 additions & 0 deletions tc-cli/src/bin/slack_bot.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
use anyhow::Result;
use axum::Extension;
use slack_morphism::prelude::*;
use std::sync::Arc;
use tokio::net::TcpListener;

#[tokio::main]
async fn main() -> Result<()> {
let subscriber = tracing_subscriber::fmt()
.with_env_filter("axum_events_api_server=debug,slack_morphism=debug")
.finish();
tracing::subscriber::set_global_default(subscriber)?;
rustls::crypto::ring::default_provider()
.install_default()
.expect("Failed to install rustls crypto provider");
server().await?;
Ok(())
}

fn error_handler(
err: Box<dyn std::error::Error + Send + Sync>,
_client: Arc<SlackHyperClient>,
_states: SlackClientEventsUserState,
) -> HttpStatusCode {
tracing::error!("{:#?}", err);

// Defines what we return Slack server
HttpStatusCode::BAD_REQUEST
}

async fn oauth_install_function(
resp: SlackOAuthV2AccessTokenResponse,
_client: Arc<SlackHyperClient>,
_states: SlackClientEventsUserState,
) {
tracing::info!("{:#?}", resp);
}

async fn command_event(
Extension(_environment): Extension<Arc<SlackHyperListenerEnvironment>>,
Extension(event): Extension<SlackCommandEvent>,
) -> axum::Json<SlackCommandEventResponse> {
tracing::info!("Received command event: {:?}", event);
axum::Json(SlackCommandEventResponse::new(
SlackMessageContent::new().with_text("Working on it".into()),
))
}

async fn server() -> Result<()> {
let client: Arc<SlackHyperClient> =
Arc::new(SlackClient::new(SlackClientHyperConnector::new()?));

let addr = std::net::SocketAddr::from(([127, 0, 0, 1], 8080));
tracing::info!("Loading server: {}", addr);

let oauth_listener_config = SlackOAuthListenerConfig::new(
std::env::var("SLACK_CLIENT_ID")?.into(),
std::env::var("SLACK_CLIENT_SECRET")?.into(),
std::env::var("SLACK_BOT_SCOPE")?,
std::env::var("SLACK_REDIRECT_HOST")?,
);

let listener_environment: Arc<SlackHyperListenerEnvironment> = Arc::new(
SlackClientEventsListenerEnvironment::new(client.clone()).with_error_handler(error_handler),
);
let signing_secret: SlackSigningSecret = std::env::var("SLACK_SIGNING_SECRET")?.into();

let listener: SlackEventsAxumListener<SlackHyperHttpsConnector> =
SlackEventsAxumListener::new(listener_environment.clone());

// build our application route with OAuth nested router and Push/Command/Interaction events
let app = axum::routing::Router::new()
.nest(
"/auth",
listener.oauth_router("/auth", &oauth_listener_config, oauth_install_function),
)
.route(
"/command",
axum::routing::post(command_event).layer(
listener
.events_layer(&signing_secret)
.with_event_extractor(SlackEventsExtractors::command_event()),
),
);

axum::serve(TcpListener::bind(&addr).await.unwrap(), app).await.unwrap();

Ok(())
}

0 comments on commit 7b2afd4

Please sign in to comment.