slackA :: Channel -> T.Text -> [(T.Text, T.Text)] -> Z ()
slackA channel text attached = do
  conf <- ask
  let opts = defaults
           & param "token"       .~ [apiToken conf]
           & param "channel"     .~ [channel]
           & param "text"        .~ [text]
           & param "username"    .~ [botName conf]
           & param "as_user"     .~ ["false" :: T.Text]
           & param "icon_emoji"  .~ [":star2:" :: T.Text]
           & param "attachments" .~ [formatAttachments attached]
  let body = [] :: [FormParam]

  _ <- liftIO $ postWith opts "http://slack.com/api/chat.postMessage" body
  -- TODO: check response, handle non-200s
  return ()
slackA :: Channel -> T.Text -> [(T.Text, T.Text)] -> Z ()
slackA channel text attached = do
  conf <- ask
  let opts = defaults
           & param "token"       .~ [apiToken conf]
           & param "channel"     .~ [channel]
           & param "text"        .~ [text]
           & param "username"    .~ [botName conf]
           & param "as_user"     .~ ["false" :: T.Text]
           & param "icon_emoji"  .~ [":star2:" :: T.Text]
           & param "attachments" .~ [formatAttachments attached]
  let body = [] :: [FormParam]

  _ <- liftIO $ postWith opts "http://slack.com/api/chat.postMessage" body
  -- TODO: check response, handle non-200s
  return ()
slackA channel text attached = do
  conf <- ask
  let opts = defaults
           & param "token"       .~ [apiToken conf]
           & param "channel"     .~ [channel]
           & param "text"        .~ [text]
           & param "username"    .~ [botName conf]
           & param "as_user"     .~ ["false" :: T.Text]
           & param "icon_emoji"  .~ [":star2:" :: T.Text]
           & param "attachments" .~ [formatAttachments attached]
  let body = [] :: [FormParam]

  _ <- liftIO $ postWith opts "http://slack.com/api/chat.postMessage" body
  -- TODO: check response, handle non-200s
  return ()