Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Slack通知を実装 #287

Merged
merged 5 commits into from
May 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions crates/sos24-infrastructure/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ aws-sdk-s3.workspace = true
chrono.workspace = true
futures-util.workspace = true
mongodb.workspace = true
reqwest.workspace = true
rs-firebase-admin-sdk.workspace = true
sendgrid.workspace = true
serde.workspace = true
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use sendgrid::v3::{Content, Email, Message, Personalization};
use sos24_use_case::shared::adapter::email::{self, EmailSender, SendEmailCommand};

use super::SendGrid;
use crate::shared::sendgrid::SendGrid;

pub struct SendGridEmailSender {
sender: SendGrid,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use sos24_domain::{
repository::file_data::{FileDataRepository, FileDataRepositoryError},
};

use crate::postgresql::Postgresql;
use crate::shared::postgresql::Postgresql;

#[derive(FromRow)]
pub struct FileDataRow {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use sos24_domain::{
repository::file_object::{FileObjectRepository, FileObjectRepositoryError},
};

use super::S3;
use crate::shared::s3::S3;

pub struct S3FileObjectRepository {
s3: S3,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use sos24_domain::{
repository::firebase_user::{FirebaseUserRepository, FirebaseUserRepositoryError},
};

use super::FirebaseAuth;
use crate::shared::firebase::FirebaseAuth;

pub struct FirebaseUserRepositoryImpl {
auth: FirebaseAuth,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use sos24_domain::{
repository::form::{FormRepository, FormRepositoryError},
};

use super::MongoDb;
use crate::shared::mongodb::MongoDb;

#[derive(Debug, Serialize, Deserialize)]
pub struct FormDoc {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use sos24_domain::{
repository::form_answer::{FormAnswerRepository, FormAnswerRepositoryError},
};

use super::MongoDb;
use crate::shared::mongodb::MongoDb;

#[derive(Debug, Serialize, Deserialize)]
pub struct FormAnswerDoc {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use sos24_domain::{
repository::invitation::{InvitationRepository, InvitationRepositoryError},
};

use super::Postgresql;
use crate::shared::postgresql::Postgresql;

#[derive(FromRow)]
pub struct InvitationRow {
Expand Down
58 changes: 35 additions & 23 deletions crates/sos24-infrastructure/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,32 @@
use firebase::firebase_user::FirebaseUserRepositoryImpl;
use firebase::FirebaseAuth;
use mongodb::form::MongoFormRepository;
use mongodb::form_answer::MongoFormAnswerRepository;
use mongodb::MongoDb;
use postgresql::file_data::PgFileDataRepository;
use postgresql::invitation::PgInvitationRepository;
use postgresql::project::PgProjectRepository;
use postgresql::user::PgUserRepository;
use s3::file_object::S3FileObjectRepository;
use s3::S3;
use sendgrid::email::SendGridEmailSender;
use sendgrid::SendGrid;
use email::SendGridEmailSender;
use file_data::PgFileDataRepository;
use file_object::S3FileObjectRepository;
use firebase_user::FirebaseUserRepositoryImpl;
use form::MongoFormRepository;
use form_answer::MongoFormAnswerRepository;
use invitation::PgInvitationRepository;
use news::PgNewsRepository;
use notification::SlackNotifier;
use project::PgProjectRepository;
use shared::{
firebase::FirebaseAuth, mongodb::MongoDb, postgresql::Postgresql, s3::S3, sendgrid::SendGrid,
};
use sos24_domain::repository::Repositories;
use sos24_use_case::shared::adapter::Adapters;

use crate::postgresql::news::PgNewsRepository;
use crate::postgresql::Postgresql;

pub mod firebase;
pub mod mongodb;
pub mod postgresql;
pub mod s3;
pub mod sendgrid;
use user::PgUserRepository;

pub mod email;
pub mod file_data;
pub mod file_object;
pub mod firebase_user;
pub mod form;
pub mod form_answer;
pub mod invitation;
pub mod news;
pub mod notification;
pub mod project;
pub mod shared;
pub mod user;

pub struct DefaultRepositories {
firebase_user_repository: FirebaseUserRepositoryImpl,
Expand Down Expand Up @@ -101,20 +106,27 @@ impl Repositories for DefaultRepositories {

pub struct DefaultAdapters {
email_sender: SendGridEmailSender,
notifier: SlackNotifier,
}

impl DefaultAdapters {
pub fn new(send_grid: SendGrid) -> Self {
pub fn new(send_grid: SendGrid, slack_webhook_url: Option<String>) -> Self {
Self {
email_sender: SendGridEmailSender::new(send_grid),
notifier: SlackNotifier::new(slack_webhook_url),
}
}
}

impl Adapters for DefaultAdapters {
type EmailSenderImpl = SendGridEmailSender;
type NotifierImpl = SlackNotifier;

fn email_sender(&self) -> &Self::EmailSenderImpl {
&self.email_sender
}

fn notifier(&self) -> &Self::NotifierImpl {
&self.notifier
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use sos24_domain::entity::news::{News, NewsBody, NewsId, NewsTitle};
use sos24_domain::entity::project::{ProjectAttributes, ProjectCategories};
use sos24_domain::repository::news::{NewsRepository, NewsRepositoryError};

use crate::postgresql::Postgresql;
use crate::shared::postgresql::Postgresql;

#[derive(FromRow)]
pub struct NewsRow {
Expand Down
47 changes: 47 additions & 0 deletions crates/sos24-infrastructure/src/notification.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use std::time::Duration;

use anyhow::Context;
use reqwest::ClientBuilder;
use serde_json::json;
use sos24_use_case::shared::adapter::notification::Notifier;

pub struct SlackNotifier {
webhook_url: Option<String>,
}

impl SlackNotifier {
pub fn new(webhook_url: Option<String>) -> Self {
let webhook_url = match webhook_url {
Some(url) => {
// 有効なURLかどうかをチェックする
let _ = reqwest::Url::parse(&url).expect("Invalid URL");
Some(url)
}
None => None,
};

Self { webhook_url }
}
}

impl Notifier for SlackNotifier {
async fn notify(&self, message: String) -> anyhow::Result<()> {
tracing::info!("Slack通知を送信します");

let Some(ref webhook_url) = self.webhook_url else {
tracing::warn!("SlackのWebhook URLが設定されていないため、通知を送信しませんでした");
return Ok(());
};

let client = ClientBuilder::new()
.timeout(Duration::from_secs(60))
.build()
.context("Failed to create HTTP client")?;

let body = json!({"text": message});
client.post(webhook_url).json(&body).send().await?;

tracing::info!("Slack通知を送信しました");
Ok(())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ use sos24_domain::{
repository::project::{ProjectRepository, ProjectRepositoryError, ProjectWithOwners},
};

use super::{user::UserRoleRow, Postgresql};
use crate::shared::postgresql::Postgresql;

use super::user::UserRoleRow;

#[derive(FromRow)]
pub struct ProjectWithOwnersRow {
Expand Down
5 changes: 5 additions & 0 deletions crates/sos24-infrastructure/src/shared.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pub mod firebase;
pub mod mongodb;
pub mod postgresql;
pub mod s3;
pub mod sendgrid;
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ use std::ops::Deref;

use rs_firebase_admin_sdk::{App, CustomServiceAccount, LiveAuthAdmin};

pub mod firebase_user;

pub struct FirebaseAuth(LiveAuthAdmin);

impl FirebaseAuth {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@ use std::ops::Deref;

use mongodb::{options::ClientOptions, Client};

pub mod form;
pub mod form_answer;

#[derive(Clone)]
pub struct MongoDb(mongodb::Database);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,6 @@ use std::ops::Deref;
use sqlx::postgres::PgPoolOptions;
use sqlx::PgPool;

pub mod file_data;
pub mod invitation;
pub mod news;
pub mod project;
pub mod user;

#[derive(Clone)]
pub struct Postgresql(pub(crate) PgPool);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ use aws_sdk_s3::{
Client,
};

pub mod file_object;

#[derive(Clone)]
pub struct S3(Client);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ use std::ops::Deref;

use sendgrid::v3::Sender;

pub mod email;

pub struct SendGrid(Sender);

impl SendGrid {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use sos24_domain::{
repository::user::{UserRepository, UserRepositoryError},
};

use super::Postgresql;
use crate::shared::postgresql::Postgresql;

#[derive(FromRow)]
pub struct UserRow {
Expand Down
4 changes: 4 additions & 0 deletions crates/sos24-presentation/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,7 @@ pub fn email_reply_to_address() -> String {
pub fn app_url() -> String {
env::var("APP_URL").expect("Env `APP_URL` must be set")
}

pub fn slack_webhook_url() -> Option<String> {
env::var("SLACK_WEBHOOK_URL").ok()
}
26 changes: 19 additions & 7 deletions crates/sos24-presentation/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub struct Modules {
invitation_use_case: InvitationUseCase<module::Repositories>,
news_use_case: NewsUseCase<module::Repositories, module::Adapters>,
file_use_case: FileUseCase<module::Repositories>,
project_use_case: ProjectUseCase<module::Repositories>,
project_use_case: ProjectUseCase<module::Repositories, module::Adapters>,
user_use_case: UserUseCase<module::Repositories>,
}

Expand Down Expand Up @@ -58,7 +58,7 @@ impl Modules {
&self.file_use_case
}

pub fn project_use_case(&self) -> &ProjectUseCase<module::Repositories> {
pub fn project_use_case(&self) -> &ProjectUseCase<module::Repositories, module::Adapters> {
&self.project_use_case
}

Expand All @@ -69,12 +69,13 @@ impl Modules {

#[cfg(not(test))]
pub async fn new(config: Config) -> anyhow::Result<Modules> {
use crate::env;
use sos24_infrastructure::{
use sos24_infrastructure::shared::{
firebase::FirebaseAuth, mongodb::MongoDb, postgresql::Postgresql, s3::S3,
sendgrid::SendGrid,
};

use crate::env;

let db = Postgresql::new(&env::postgres_db_url()).await?;
let mongo_db = MongoDb::new(&env::mongodb_db_url(), &env::mongodb_db_name()).await?;
let auth = FirebaseAuth::new(&env::firebase_service_account_key()).await?;
Expand All @@ -93,7 +94,10 @@ pub async fn new(config: Config) -> anyhow::Result<Modules> {
));

let send_grid = SendGrid::new(&env::send_grid_api_key());
let adapters = Arc::new(sos24_infrastructure::DefaultAdapters::new(send_grid));
let adapters = Arc::new(sos24_infrastructure::DefaultAdapters::new(
send_grid,
env::slack_webhook_url(),
));

let application_period = ProjectApplicationPeriod::new(
config.project_application_start_at.clone(),
Expand All @@ -110,7 +114,11 @@ pub async fn new(config: Config) -> anyhow::Result<Modules> {
),
news_use_case: NewsUseCase::new(Arc::clone(&repositories), Arc::clone(&adapters)),
file_use_case: FileUseCase::new(Arc::clone(&repositories)),
project_use_case: ProjectUseCase::new(Arc::clone(&repositories), application_period),
project_use_case: ProjectUseCase::new(
Arc::clone(&repositories),
Arc::clone(&adapters),
application_period,
),
user_use_case: UserUseCase::new(Arc::clone(&repositories)),
})
}
Expand All @@ -135,7 +143,11 @@ pub async fn new_test(
),
news_use_case: NewsUseCase::new(Arc::clone(&repositories), Arc::clone(&adapters)),
file_use_case: FileUseCase::new(Arc::clone(&repositories)),
project_use_case: ProjectUseCase::new(Arc::clone(&repositories), application_period),
project_use_case: ProjectUseCase::new(
Arc::clone(&repositories),
Arc::clone(&adapters),
application_period,
),
user_use_case: UserUseCase::new(Arc::clone(&repositories)),
})
}
Loading