Initial Slack support

This commit is contained in:
Davidson Francis 2024-07-27 02:49:08 -03:00
parent d80425217a
commit db437fb6e3
2 changed files with 111 additions and 18 deletions

View File

@ -12,6 +12,5 @@
extern char *get_formatted_time(time_t time, char *time_str); extern char *get_formatted_time(time_t time, char *time_str);
extern void log_msg(const char *fmt, ...); extern void log_msg(const char *fmt, ...);
extern int send_telegram_notification(const char *msg);
#endif /* ALERTIK_H */ #endif /* ALERTIK_H */

View File

@ -50,15 +50,14 @@ int is_within_notify_threshold(void) {
* *
* @param hnd CURL handle. * @param hnd CURL handle.
* @param url Request URL. * @param url Request URL.
* @return Returns CURLE_OK if successful, otherwise a CURLcode error. * @return Returns 0.
*/ */
static void setopts_get_curl(CURL *hnd, const char *url) static int setopts_get_curl(CURL *hnd, const char *url)
{ {
curl_easy_setopt(hnd, CURLOPT_URL, url); curl_easy_setopt(hnd, CURLOPT_URL, url);
curl_easy_setopt(hnd, CURLOPT_NOPROGRESS, 1L); curl_easy_setopt(hnd, CURLOPT_NOPROGRESS, 1L);
curl_easy_setopt(hnd, CURLOPT_USERAGENT, CURL_USER_AGENT); curl_easy_setopt(hnd, CURLOPT_USERAGENT, CURL_USER_AGENT);
curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 3L); curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 3L);
curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);
curl_easy_setopt(hnd, CURLOPT_WRITEFUNCTION, libcurl_noop_cb); curl_easy_setopt(hnd, CURLOPT_WRITEFUNCTION, libcurl_noop_cb);
#ifdef CURL_VERBOSE #ifdef CURL_VERBOSE
curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L); curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);
@ -66,14 +65,16 @@ static void setopts_get_curl(CURL *hnd, const char *url)
#ifndef VALIDATE_CERTS #ifndef VALIDATE_CERTS
curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYPEER, 0L); curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYPEER, 0L);
#endif #endif
return 0;
} }
/** /**
* *
*/ */
static void do_curl_cleanup(CURL *hnd, char *escape) static void do_curl_cleanup(CURL *hnd, char *escape, struct curl_slist *slist)
{ {
curl_free(escape); curl_free(escape);
curl_slist_free_all(slist);
if (hnd) if (hnd)
curl_easy_cleanup(hnd); curl_easy_cleanup(hnd);
} }
@ -81,7 +82,7 @@ static void do_curl_cleanup(CURL *hnd, char *escape)
/** /**
* *
*/ */
static CURLcode do_curl(CURL *hnd, char *escape) static CURLcode do_curl(CURL *hnd, char *escape, struct curl_slist *slist)
{ {
CURLcode ret_curl = !CURLE_OK; CURLcode ret_curl = !CURLE_OK;
@ -97,7 +98,7 @@ static CURLcode do_curl(CURL *hnd, char *escape)
ret_curl = CURLE_OK; ret_curl = CURLE_OK;
error: error:
do_curl_cleanup(hnd, escape); do_curl_cleanup(hnd, escape, slist);
return ret_curl; return ret_curl;
} }
@ -105,17 +106,80 @@ error:
* @brief Initializes and configures the CURL handle for sending a POST * @brief Initializes and configures the CURL handle for sending a POST
* request with a JSON payload. * request with a JSON payload.
* *
* @param hnd CURL handle. * @param hnd CURL handle.
* @param url Request URL. * @param url Request URL.
* @param payload Payload data in JSON format. * @param json_payload Payload data in JSON format.
* *
* @return Returns CURLE_OK if successful, otherwise a CURLcode error. * @return Returns 0 if successful, 1 otherwise.
*/ */
static void setopts_post_json_curl(CURL *hnd, const char *url, static int setopts_post_json_curl(CURL *hnd, const char *url,
const char *payload) const char *json_payload, struct curl_slist **slist)
{ {
struct curl_slist *s = *slist;
s = NULL;
s = curl_slist_append(s, "Content-Type: application/json");
s = curl_slist_append(s, "Accept: application/json");
if (!s) {
*slist = s;
return 1;
}
curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, s);
curl_easy_setopt(hnd, CURLOPT_URL, url);
curl_easy_setopt(hnd, CURLOPT_NOPROGRESS, 1L);
curl_easy_setopt(hnd, CURLOPT_USERAGENT, CURL_USER_AGENT);
curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 3L);
curl_easy_setopt(hnd, CURLOPT_WRITEFUNCTION, libcurl_noop_cb);
#ifdef CURL_VERBOSE
curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);
#endif
#ifndef VALIDATE_CERTS
curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYPEER, 0L);
#endif
curl_easy_setopt(hnd, CURLOPT_POSTFIELDS, json_payload);
*slist = s;
return 0;
} }
/**
*
*/
static int send_generic_webhook(const char *url, const char *text)
{
CURL *hnd = NULL;
struct curl_slist *s = NULL;
char payload_data[4096] = {0};
if (!(hnd = curl_easy_init())) {
log_msg("Failed to initialize libcurl!\n");
return 1;
}
snprintf(
payload_data,
sizeof payload_data - 1,
"{\"text\":\"%s\"}",
text
);
#if 0
TODO:
- escape "" in the payload, otherwise it will silently
escape from the {"text": }
- think about the return code from the request and
emmit some message if not 200
#endif
if (setopts_post_json_curl(hnd, url, payload_data, &s))
return 1;
log_msg("> Sending notification!\n");
return do_curl(hnd, NULL, s);
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//////////////////////////////// TELEGRAM ////////////////////////////////////// //////////////////////////////// TELEGRAM //////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -143,7 +207,7 @@ void setup_telegram(void)
setup = 1; setup = 1;
} }
int send_telegram_notification(const char *msg) static int send_telegram_notification(const char *msg)
{ {
char full_request_url[4096] = {0}; char full_request_url[4096] = {0};
char *escaped_msg = NULL; char *escaped_msg = NULL;
@ -157,7 +221,7 @@ int send_telegram_notification(const char *msg)
escaped_msg = curl_easy_escape(hnd, msg, 0); escaped_msg = curl_easy_escape(hnd, msg, 0);
if (!escaped_msg) { if (!escaped_msg) {
log_msg("> Unable to escape notification message...\n"); log_msg("> Unable to escape notification message...\n");
do_curl_cleanup(hnd, escaped_msg); do_curl_cleanup(hnd, escaped_msg, NULL);
} }
snprintf( snprintf(
@ -167,11 +231,36 @@ int send_telegram_notification(const char *msg)
telegram_bot_token, telegram_chat_id, escaped_msg); telegram_bot_token, telegram_chat_id, escaped_msg);
setopts_get_curl(hnd, full_request_url); setopts_get_curl(hnd, full_request_url);
log_msg("> Sending notification!\n"); log_msg("> Sending notification!\n");
return do_curl(hnd, escaped_msg, NULL);
return do_curl(hnd, escaped_msg);
} }
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////// SLACK ///////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/* Slack settings. */
static char *slack_webhook_url;
void setup_slack(void)
{
static int setup = 0;
if (setup)
return;
slack_webhook_url = getenv("SLACK_WEBHOOK_URL");
if (!slack_webhook_url) {
panic("Unable to find env vars for, please check if you have set\n"
"the SLACK_WEBHOOK_URL!!\n");
}
setup = 1;
}
static int send_slack_notification(const char *msg) {
return send_generic_webhook(slack_webhook_url, msg);
}
////////////////////////////////// END //////////////////////////////////////// ////////////////////////////////// END ////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -185,5 +274,10 @@ struct notifier notifiers[] = {
{ {
.setup = setup_telegram, .setup = setup_telegram,
.send_notification = send_telegram_notification .send_notification = send_telegram_notification
},
/* Slack. */
{
.setup = setup_slack,
.send_notification = send_slack_notification
} }
}; };