#' @title Send Slack Comment.
#'
#' @description Sends Slack comment.
#'
#' @author Pieter Overdevest
#'
#' @param c.slack.hook String with slack hook.
#' @param c.marker String to code the marker: 'v' for checkbox and 'x' for white cross.
#' @param c.title Title of message (string).
#' @param c.message.main Main message (string).
#' @param v.message.list Message to communicate (vector with strings).
#' @param v.button.txt Text labels on the buttons (vector with strings).
#' @param v.button.url URL behind the buttons (vector with strings).
#' @param c.image.url Link to image to show in Slack message (default NULL).
#'
#' @returns None
#'
#' @details How to obtain a Slack Hook:
#'
#' * Go to https://api.slack.com/apps
#'
#' * If needed, create a new app
#'
#' * Go to ‘Incoming Webhooks’
#'
#' * If not already, activate Incoming Webhooks
#'
#' * Add new webhook to workspace
#'
#' * Select channel
#'
#' * Copy webhook and use for POST() function.
#'
#' * Add app to Slack by ‘Add apps’, or the channel may already be pointing to it for you
#'
#'
#' @export
#'
#' @examples
#' f_send_slack_comment(
#' c.slack.hook = "https://hooks.slack.com/services/........./......../...........",
#' c.marker = "xxx",
#' c.title = "A greate title!",
#' c.message.main = "The main message.",
#' v.message.list = c("Hello World!", "This is item 2", "And a third item"),
#' v.button.txt = c('Dumps', 'Log', 'RDS', 'IPSm'),
#' v.button.url = c(c.ipsm.dumps, c.ipsm.allocatie.log, c.data.repo, "https://ipsm.nl/"),
#' c.image.url = "https://media.licdn.com/dms/image/C560BAQEGsMeS8zRHcg/company-logo_200_200/0/1612876167821?e=1682553600&v=beta&t=ypO6V4vhFioktDnqLdCKra0K6IGaI2bl6klfHaxA0lw"
#' )
#################################################################################
# FUNCTION.
#################################################################################
f_send_slack_comment <- function(
c.slack.hook,
c.marker,
c.title,
c.message.main,
v.message.list,
v.button.txt,
v.button.url,
c.image.url = NULL
) {
# TESTING - Succesfull download
# c.marker = "v"
# c.title = c.file.string
# c.message.main = "File was successfully downloaded from Dumps."
# v.message.list = "See Synology"
# v.button.txt = c('Dumps', 'Log', 'RDS', 'IPSm')
# v.button.url = c(c.ipsm.dumps, c.ipsm.allocatie.log, c.data.repo, "https://ipsm.nl/")
# c.image.url = c.image.url.hrgroep
# c.marker = "v"
# c.title = c.file.string
# c.message.main = paste0("File - ", c.filename, " - was successfully downloaded from the source.")
# v.message.list = "See folder IPSm/Data/EXPORT/."
# v.button.txt = c("Source", "Log", "Destination", "RDS", "IPSm")
# v.button.url = c(c.export.from, c.ipsm.allocatie.log, c.data.export, c.data.rds, "https://ipsm.nl/")
# c.image.url = c.image.url.hrgroep
# Translate marker(s).
c.marker.updated <- lapply(
c.marker %>% strsplit("") %>% unlist(),
function(x) {
if(x == "v") {
":white_check_mark:"
} else if(x == "x") {
":x:"
} else {
stop("Unknown marker.")
}
}) %>%
unlist() %>%
paste0(collapse = "")
# Prepare message from list. Remove "'", because "'" results in issues rendering the JSON.
c.message.list <- paste(
paste0(
# Don't add '-' in case v.message.list contains one element.
ifelse(length(v.message.list) == 1, "", "- "),
v.message.list
),
collapse = "\n"
) %>% gsub("'", "", .)
# URL message in case URL is provided.
c.image.url.message <- ifelse(
is.null(c.image.url),
"",
paste0(", 'accessory': {'type': 'image','image_url': '", c.image.url, "','alt_text': 'ALTERNATIVE'}")
)
# Compose message.
c.message <- paste0(
"{'blocks':[
{
'type': 'section',
'text': {
'type': 'mrkdwn',
'text': '*",
c.marker.updated, "\t" , c.title, "*\n\n",
c.message.main, "\n\n", c.message.list, "'
}", c.image.url.message,
"},
{
'type': 'actions',
'elements': [",
paste(
mapply(
function(c.button.txt, c.button.url) {
paste0(
"{
'type': 'button',
'text': {
'type': 'plain_text',
'text': ':spiral_note_pad: ", c.button.txt, "'
},
'url': '", c.button.url, "'
}"
)
},
c.button.txt = v.button.txt,
c.button.url = v.button.url
),
collapse = ","
),
"]
},
{
'type': 'context',
'elements': [
{
'type': 'plain_text',
'text': ' Timestamp of message: ", Sys.time() , "',
'emoji': true
}
]
},
{
'type': 'divider'
}
]}")
# How many times to attempt to send Slack.
n_counter_max <- 5
# Initialize
b_continue <- TRUE
n_counter <- 1
# Try for at most n_counter_max times.
while ((n_counter <= n_counter_max) & b_continue) {
# Comms to user.
cat(paste0("\n\n", now(), " - Attempt send to Slack ", n_counter, " of ", n_counter_max, ".\n"))
# Ask R to try to download each hour.
result <- try({
httr::POST(
url = c.slack.hook,
encode = "json",
body = c.message
)
# Testing.
#b=a+2
}, silent = FALSE)
# Comms to user.
cat(paste0(
"\n", now(), " - Attempt send to Slack ", n_counter, " of ", n_counter_max,
" passed the 'POST()' function. The class of the result is as follows (class: '",
class(result), "'):\n\n"
))
print(result)
#print(class(result))
#cat("\n")
# Check result of attempt. If attempt was succesful.
if(!"status_code" %in% attributes(result)$names) {
# Comms to user.
cat(paste0(
now(), " - Attempt send to Slack ", n_counter, " of ", n_counter_max,
" was not successful due to a bug in the script and there was no status code returned.",
" We will not try again. Fix the bug.\n"
))
return()
} else {
if(result$status_code == 200) {
b_continue <- FALSE
# Comms to user.
cat(paste0(
now(), " - Attempt send to Slack ", n_counter, " of ", n_counter_max,
" was successful (Status: 200)!\n"
))
return()
# If attempt was not succesfull, we try again after we wait 15 sec.
} else if(result$status_code == 400) {
# Comms to user.
cat(paste0(
now(), " - Attempt send to Slack ", n_counter, " of ", n_counter_max,
" was not successful (Status: 400). We will try again.\n"
))
Sys.sleep(15)
n_counter <- n_counter + 1
} else {
# Comms to user.
cat(paste0(
now(), " - Attempt send to Slack ", n_counter, " of ", n_counter_max,
" was not successful (Status: ", result$status_code,"). We will try again.\n"
))
Sys.sleep(15)
n_counter <- n_counter + 1
}
}
}
# Comms to user.
cat(paste0(
"\n", now(), " - Attempt send to Slack ", n_counter, " of ", n_counter_max,
" was not successful. We tried ", n_counter_max,
" times and we will not try again.\n"
))
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.