Feature/slack_notify#134 (#139)
* add slack notify * cargo fmt --all * slack-hook version up * change bot name
This commit is contained in:
2
.env.example
Normal file
2
.env.example
Normal file
@@ -0,0 +1,2 @@
|
||||
WEBHOOK_URL=
|
||||
CHANNEL=#
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -3,4 +3,5 @@
|
||||
*.test
|
||||
/.vscode/
|
||||
.DS_Store
|
||||
test_*
|
||||
test_*
|
||||
.env
|
||||
1122
Cargo.lock
generated
1122
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -24,6 +24,8 @@ linked-hash-map = "0.5.3"
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
num_cpus = "1.13.0"
|
||||
mopa = "0.2.2"
|
||||
slack-hook = "0.8"
|
||||
dotenv = "0.15.0"
|
||||
|
||||
[target.x86_64-pc-windows-gnu]
|
||||
linker = "x86_64-w64-mingw32-gcc"
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
use crate::detections::configs;
|
||||
use crate::detections::print;
|
||||
use crate::detections::print::AlertMessage;
|
||||
use crate::notify::slack::SlackNotify;
|
||||
use chrono::{DateTime, Local, TimeZone, Utc};
|
||||
use serde::Serialize;
|
||||
use std::error::Error;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
use std::io::BufWriter;
|
||||
use std::process;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
@@ -18,34 +20,56 @@ pub struct CsvFormat<'a> {
|
||||
}
|
||||
|
||||
pub fn after_fact() {
|
||||
let mut target: Box<dyn io::Write> = if let Some(csv_path) = configs::CONFIG
|
||||
.read()
|
||||
.unwrap()
|
||||
.args
|
||||
.value_of("csv-timeline")
|
||||
{
|
||||
match File::create(csv_path) {
|
||||
Ok(file) => Box::new(file),
|
||||
Err(err) => {
|
||||
let stdout = std::io::stdout();
|
||||
let mut stdout = stdout.lock();
|
||||
AlertMessage::alert(&mut stdout, format!("Failed to open file. {}", err)).ok();
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Box::new(io::stdout())
|
||||
};
|
||||
|
||||
if let Err(err) = emit_csv(&mut target) {
|
||||
let fn_emit_csv_err = |err: Box<dyn Error>| {
|
||||
let stdout = std::io::stdout();
|
||||
let mut stdout = stdout.lock();
|
||||
AlertMessage::alert(&mut stdout, format!("Failed to write CSV. {}", err)).ok();
|
||||
process::exit(1);
|
||||
};
|
||||
|
||||
// slack通知する場合はemit_csvした後に
|
||||
if configs::CONFIG.read().unwrap().args.is_present("slack") {
|
||||
let mut buf = vec![];
|
||||
let mut writer = BufWriter::new(buf);
|
||||
if let Err(err) = emit_csv(&mut writer) {
|
||||
fn_emit_csv_err(err);
|
||||
} else {
|
||||
buf = writer.into_inner().unwrap();
|
||||
let s = std::str::from_utf8(&buf).unwrap();
|
||||
if SlackNotify::notify(s.to_string()).is_err() {
|
||||
eprintln!("slack notification failed!!");
|
||||
}
|
||||
println!("{}", s.to_string());
|
||||
}
|
||||
} else {
|
||||
let mut target: Box<dyn io::Write> = if let Some(csv_path) = configs::CONFIG
|
||||
.read()
|
||||
.unwrap()
|
||||
.args
|
||||
.value_of("csv-timeline")
|
||||
{
|
||||
// ファイル出力する場合
|
||||
match File::create(csv_path) {
|
||||
Ok(file) => Box::new(file),
|
||||
Err(err) => {
|
||||
let stdout = std::io::stdout();
|
||||
let mut stdout = stdout.lock();
|
||||
AlertMessage::alert(&mut stdout, format!("Failed to open file. {}", err)).ok();
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 標準出力に出力する場合
|
||||
Box::new(io::stdout())
|
||||
};
|
||||
|
||||
if let Err(err) = emit_csv(&mut target) {
|
||||
fn_emit_csv_err(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn emit_csv(writer: &mut Box<dyn io::Write>) -> Result<(), Box<dyn Error>> {
|
||||
fn emit_csv<W: std::io::Write>(writer: &mut W) -> Result<(), Box<dyn Error>> {
|
||||
let mut wtr = csv::WriterBuilder::new().from_writer(writer);
|
||||
let messages = print::MESSAGES.lock().unwrap();
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@ fn build_app<'a>() -> ArgMatches<'a> {
|
||||
.arg(Arg::from_usage("-d --directory=[DIRECTORY] 'event log files directory'"))
|
||||
.arg(Arg::from_usage("-s --statistics 'event statistics'"))
|
||||
.arg(Arg::from_usage("-t --threadnum=[NUM] 'thread number'"))
|
||||
.arg(Arg::from_usage("--slack 'slack notification'"))
|
||||
.arg(Arg::from_usage("--credits 'Zachary Mathis, Akira Nishikawa'"))
|
||||
.get_matches()
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
pub mod afterfact;
|
||||
pub mod detections;
|
||||
pub mod notify;
|
||||
pub mod omikuji;
|
||||
pub mod timeline;
|
||||
pub mod yaml;
|
||||
|
||||
1
src/notify/mod.rs
Normal file
1
src/notify/mod.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub mod slack;
|
||||
57
src/notify/slack.rs
Normal file
57
src/notify/slack.rs
Normal file
@@ -0,0 +1,57 @@
|
||||
extern crate slack_hook;
|
||||
use dotenv::dotenv;
|
||||
use slack_hook::{PayloadBuilder, Slack};
|
||||
use std::env;
|
||||
|
||||
pub struct SlackNotify {}
|
||||
|
||||
impl SlackNotify {
|
||||
// Check if Slack is configured.
|
||||
pub fn check_setting() -> bool {
|
||||
dotenv().ok();
|
||||
if env::var("CHANNEL").is_err() {
|
||||
eprintln!("Channel not found");
|
||||
return false;
|
||||
}
|
||||
|
||||
if env::var("WEBHOOK_URL").is_err() {
|
||||
eprintln!("WEBHOOK_URL not found");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// send message to slack.
|
||||
pub fn notify(msg: String) -> Result<(), String> {
|
||||
dotenv().ok();
|
||||
if !SlackNotify::check_setting() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let channel = env::var("CHANNEL").expect("CHANNEL is not found");
|
||||
let webhook_url = env::var("WEBHOOK_URL").expect("WEBHOOK_URL is not found");
|
||||
let ret = SlackNotify::_send_to_slack(msg, &channel, &webhook_url);
|
||||
if ret.is_ok() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err("Slack Notification Failed.".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
fn _send_to_slack(
|
||||
msg: String,
|
||||
channel: &str,
|
||||
webhook_url: &str,
|
||||
) -> Result<(), slack_hook::Error> {
|
||||
let slack = Slack::new(webhook_url).unwrap();
|
||||
let p = PayloadBuilder::new()
|
||||
.text(msg)
|
||||
.channel(channel)
|
||||
.username("Lagotto Notify Bot")
|
||||
.icon_emoji(":scream:")
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
slack.send(&p)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user