Mark
Mark

Reputation: 172

How to improve formatting of slack messages using slackr?

I'm using slackr to send alert messages to a Slack channel. It works great except the message format is not great and I want to improve it.

install_github("hrbrmstr/slackr")
library(slackr)
slackr_setup(channel="#alerts", username="Mark Davis", 
         incoming_webhook_url = "https://hooks.slack.com/services/T31P8UDAB/BCH4HKQSC/*********", 
         api_token = "*********", echo = F)

alert="On Monday, 2018-09-03 @ 2pm Pacific..."
slackr(alert)

Here is an example of how a message from slackr looks in Slack:

enter image description here

Here is an example of how I'd like it to look:

enter image description here

slackr doesn't seem to have many options in the way of formatting. I was thinking of building an image and inserting that, but I'm having trouble building an image out of a text file using R.

Perhaps there is another api I could call that could take my text and format it for slack?

I'm open to any suggestions.

Addendum: Slackr has an option to upload files, so my latest attempt is to create an image from the text message and upload that object.

I am able to create a png file from the text message using the magick library. I created an image with a colored background, and I simply add the message text to the image:

library(magick)
alert_picture <- image_read('alert_480x150_dark_red.png')
alert_picture=image_annotate(alert_picture, DreamCloud_Alert, size = 20, gravity = "southwest", 
                           color = "white", location = "+10+10")
image_write(alert_picture, path = "alert_picture.png", format = "png")

enter image description here

The image looks pretty good (although there doesn't seem to be an easy way to bold or underline specific words in the message), but the obstacle now is that I can't get the upload command to work.

slackr_upload(filename = "alert_picture.png")

I don't get any error messages but nothing is uploaded to slack.

Upvotes: 0

Views: 1116

Answers (2)

Corel
Corel

Reputation: 633

I am not sure this is what you meant, but I solved allowing formatting like in a regular slack message by altering the slackr_bot() function and just removing the 2 sets of 3 back-ticks at the end of the code where it says text. Then just call it slackr_bot1() or something, and then you can post formatted messages. This is the function after the back-ticks removal:

    slackr_bot1 <- function(...,
                       channel=Sys.getenv("SLACK_CHANNEL"),
                       username=Sys.getenv("SLACK_USERNAME"),
                       icon_emoji=Sys.getenv("SLACK_ICON_EMOJI"),
                       incoming_webhook_url=Sys.getenv("SLACK_INCOMING_URL_PREFIX")) {

  if (incoming_webhook_url == "") {
    stop("No incoming webhook URL specified. Did you forget to call slackr_setup()?", call. = FALSE)
  }

  if (icon_emoji != "") { icon_emoji <- sprintf(', "icon_emoji": "%s"', icon_emoji)  }

  resp_ret <- ""

  if (!missing(...)) {

    # mimics capture.output

    # get the arglist
    args <- substitute(list(...))[-1L]

    # setup in-memory sink
    rval <- NULL
    fil <- textConnection("rval", "w", local = TRUE)

    sink(fil)
    on.exit({
      sink()
      close(fil)
    })

    # where we'll need to eval expressions
    pf <- parent.frame()

    # how we'll eval expressions
    evalVis <- function(expr) withVisible(eval(expr, pf))

    # for each expression
    for (i in seq_along(args)) {

      expr <- args[[i]]

      # do something, note all the newlines...Slack ``` needs them
      tmp <- switch(mode(expr),
                    # if it's actually an expresison, iterate over it
                    expression = {
                      cat(sprintf("> %s\n", deparse(expr)))
                      lapply(expr, evalVis)
                    },
                    # if it's a call or a name, eval, printing run output as if in console
                    call = ,
                    name = {
                      cat(sprintf("> %s\n", deparse(expr)))
                      list(evalVis(expr))
                    },
                    # if pretty much anything else (i.e. a bare value) just output it
                    integer = ,
                    double = ,
                    complex = ,
                    raw = ,
                    logical = ,
                    numeric = cat(sprintf("%s\n\n", as.character(expr))),
                    character = cat(sprintf("%s\n\n", expr)),
                    stop("mode of argument not handled at present by slackr"))

      for (item in tmp) if (item$visible) { print(item$value, quote = FALSE); cat("\n") }
    }

    on.exit()

    sink()
    close(fil)

    # combined all of them (rval is a character vector)
    output <- paste0(rval, collapse="\n")

    loc <- Sys.getlocale('LC_CTYPE')
    Sys.setlocale('LC_CTYPE','C')
    on.exit(Sys.setlocale("LC_CTYPE", loc))

    resp <- POST(url = incoming_webhook_url, encode = "form",
                 add_headers(`Content-Type` = "application/x-www-form-urlencoded",
                             Accept = "*/*"), body = URLencode(sprintf("payload={\"channel\": \"%s\", \"username\": \"%s\", \"text\": \"%s\"%s}",
                                                                       channel, username, output, icon_emoji)))
    warn_for_status(resp)
  }
  return(invisible())
}

slackr_bot1("*test* on time")

enter image description here

Upvotes: 1

Mark
Mark

Reputation: 172

I got around this issue by using the httr package to execute the post image function to slack.

Thanks to Adil B. for providing the solution:

Post Image to Slack Using HTTR package in R

Upvotes: 1

Related Questions