Slack: Chat, Post Block

Slack: チャット, ブロック投稿

Slack: Chat, Post Block

Slack: チャット, ブロック投稿

Posts a message in block format. A table data can be attached as needed. It is also possible to change to an ephemeral message that is displayed only to a specific user.

Auto Step icon
Configs for this Auto Step
AuthzConfU
U: Select HTTP_Authz Setting *
StrConfA1
A1: Set Slack Channel to Post (eg “#general”) *#{EL}
StrConfA2
A2: To post in thread, Set thread_ts (eg “1234567890.123456”)#{EL}
StrConfA3
A3: To be Ephemeral, Set UserID to Receive (eg “U0BPQUNTA”)#{EL}
StrConfB1
B1: Set MessageTitle to be Posted *#{EL}
StrConfC1
C1: Set MessageBody to be Posted *#{EL}
StrConfC2
C2: To attache KeyValue, Set 2-col TSV (Upto 5 rows 2000 chars)#{EL}
StrConfC3
C3: Set URL for Category Image#{EL}
SelectConfD1
D1: If necessary, Select STRING that stores MessageTs (update)
Script (click to open)
// GraalJS Script (engine type: 3)

//////// START "main()" /////////////////////////////////////////////////////////////////
// GraalJS Script (engine type: 3)

main();
function main(){ 

//// == Config Retrieving / 工程コンフィグの参照 ==

const oauth2SettingName = configs.get("AuthzConfU");
let oauth2 = null;
if (oauth2SettingName !== "") {
oauth2 = httpClient.findAuthSetting(oauth2SettingName, false);
}

  engine.log( " AutomatedTask Config: Authz Setting: " + oauth2SettingName );
const strSlackChannel     = configs.get      ( "StrConfA1" );    /// REQUIRED
  if( strSlackChannel   === "" ){
    throw new Error( "\n AutomatedTask ConfigError:" +
                     " Config {A1: SlackChannel} is empty \n" );
  }
const strThread           = configs.get      ( "StrConfA2" );    // NotRequired
  if( strThread         !== "" ){
    engine.log( " AutomatedTask ConfigWarning:" +
                " Message is posted in thread " + strThread );
  }
const strToUserId         = configs.get      ( "StrConfA3" );    // NotRequired
  if( strToUserId       !== "" ){
    engine.log( " AutomatedTask ConfigWarning:" +
                " Message is posted with Ephemeral mode " + strToUserId );
  }
const strMessageTitle     = configs.get      ( "StrConfB1" );    /// REQUIRED
  if( strMessageTitle   === "" ){
    throw new Error( "\n AutomatedTask ConfigError:" +
                     " Config {B1: Title} is empty \n" );
  }
const strMessageBody      = configs.get      ( "StrConfC1" );    /// REQUIRED
  if( strMessageBody    === "" ){
    throw new Error( "\n AutomatedTask ConfigError:" +
                     " Config {C1: Message} is empty \n" );
  }
const strTwocolTsv        = configs.get      ( "StrConfC2" );    // NotRequired
const strCategoryImgUrl   = configs.get      ( "StrConfC3" );    // NotRequired
const strPocketMessageTs  = configs.getObject( "SelectConfD1" ); // NotRequired


//// == Data Retrieving / ワークフローデータの参照 ==
// (Nothing. Some workflow data is referenced via Expression Language in Config.)


//// == Calculating / 演算 ==
/// TSV, Check Empty
let strKeyAndValue = "";
if( strTwocolTsv !== "" ){
  let arrRows = strTwocolTsv.split("\n");
  engine.log( " AutomatedTask Config:" +
              " TSV Rows " + arrRows.length );
  for( let i = 0; i < arrRows.length; i++ ){
    let arrCells = arrRows[i].split("\t");
    if( arrCells.length < 2 ){ // load stop with end line or illegal line
      engine.log( " AutomatedTask UnexpectedTsv line: " + i );
      break; 
    }
    for( let j = 0; j < 2; j++ ){
      if( arrCells[j] === "" ){
        strKeyAndValue += "n/a";
      }else{
        strKeyAndValue += arrCells[j];
      }
      strKeyAndValue += "\n";
    }
    if( i === 4 ){ break; } // up to 5
  }
  strKeyAndValue = strKeyAndValue.slice( 0, -1 );
}
/// Post Message
/// Slack API
/// https://api.slack.com/methods/chat.postMessage
/// https://api.slack.com/methods/chat.postEphemeral
/// https://api.slack.com/messaging/sending
/// https://api.slack.com/reference/messaging/payload
/// https://api.slack.com/reference/block-kit/blocks
// request1, prepare
let request1Obj = {};
    request1Obj.channel = strSlackChannel;
    if( strToUserId !== "" ){
      request1Obj.user = strToUserId;
    }
    request1Obj.text = strMessageTitle + "\n" + strMessageBody;
    if( strThread !== "" ){
      request1Obj.thread_ts = strThread;
    }
    request1Obj.blocks = [];
    request1Obj.blocks[0] = {};
    request1Obj.blocks[0].type = "header";
    request1Obj.blocks[0].text = {};
    request1Obj.blocks[0].text.type = "plain_text";
    request1Obj.blocks[0].text.text = strMessageTitle.slice(0,150); // MAX 150
    // https://api.slack.com/reference/block-kit/blocks#header
    request1Obj.blocks[0].text.emoji = true; // No format 'false'
    request1Obj.blocks[1] = {};
    request1Obj.blocks[1].type = "section";
    request1Obj.blocks[1].text = {};
    request1Obj.blocks[1].text.type = "mrkdwn"; // if "plain_text", newline \n not work.
    request1Obj.blocks[1].text.text = strMessageBody.slice(0,3000); // MAX 3000
    // https://api.slack.com/reference/block-kit/blocks#section
    if( strCategoryImgUrl !== "" ){
      request1Obj.blocks[1].accessory = {};
      request1Obj.blocks[1].accessory.type = "image";
      request1Obj.blocks[1].accessory.image_url = strCategoryImgUrl;
      request1Obj.blocks[1].accessory.alt_text  = "CategoryImg";
    }
    if( strKeyAndValue !== "" ){
      let arrKeyAndValue = strKeyAndValue.split("\n");
      request1Obj.blocks[1].fields = [];
      for( let i = 0; i < arrKeyAndValue.length; i++ ){
        request1Obj.blocks[1].fields[i] = {};
        request1Obj.blocks[1].fields[i].type = "mrkdwn"; // No format "plain_text"
        request1Obj.blocks[1].fields[i].text = arrKeyAndValue[i];
      }
    }
let request1Uri = "https://slack.com/api/chat.postMessage";
  if( strToUserId !== "" ){
    request1Uri = "https://slack.com/api/chat.postEphemeral";
  }
let request1    = httpClient.begin(); // HttpRequestWrapper
    request1    = request1.authSetting( oauth2 ); // with "Authorization: Bearer XX"
    // https://questetra.zendesk.com/hc/en-us/articles/360024574471-R2300#HttpRequestWrapper
    request1    = request1.body( JSON.stringify( request1Obj ), "application/json" );
// request1, try
const response1     = request1.post( request1Uri ); // HttpResponseWrapper
engine.log( " AutomatedTask ApiRequest1 Start: " + request1Uri );
const response1Code = response1.getStatusCode() + "";
const response1Body = response1.getResponseAsString() + "";
engine.log( " AutomatedTask ApiResponse Status: " + response1Code );
if( response1Code !== "200"){
  throw new Error( "\n AutomatedTask UnexpectedResponseError: " +
                    response1Code + "\n" + response1Body + "\n" );
}
// response1, parse
/* 
engine.log( response1Body ); // debug
{
  "ok":true,
  "channel":"C029A930R",
  "ts":"1622607940.003700",
  "message":{
    "bot_id":"B02471SR3BJ",
    "type":"message",
      # # #
    "ts":"1622607940.003700",
    "team":"T029A930F",
    "bot_profile":{
      # # #
    },
  }
}

== ephemeral ==
{
  "ok":true,
  "message_ts":"1622179598.000100"
}

== thread ==
{
  "ok":true,
  "channel":"C029A930R",
  "ts":"1622606758.003500",
  "message":{
    "bot_id":"B02471SR3BJ",
    "type":"message",
      # # #
    "ts":"1622606758.003500",
      # # #
    "bot_profile":{
      # # #
    },
    "blocks":[
      # # #
    ],
    "thread_ts":"1622602402.002700",
      # # #
  }
}
*/
const response1Obj = JSON.parse( response1Body );
if( response1Obj.ok !== true ){
  throw new Error( "\n AutomatedTask UnexpectedResponseError: " +
                    response1Code + "\n" + response1Body + "\n" );
}
if( response1Obj.hasOwnProperty('warning') ){
  engine.log( " AutomatedTask ApiResponse Warning: " + response1Obj.warning );
}


//// == Data Updating / ワークフローデータへの代入 ==
if( strPocketMessageTs !== null ){
  engine.setData( strPocketMessageTs, response1Obj.ts );
}

}
//////// END "main()" /////////////////////////////////////////////////////////////////

Download

warning Freely modifiable JavaScript (ECMAScript) code. No warranty of any kind.
(Installing Addon Auto-Steps are available only on the Professional edition.)

Notes

  • Posts to the business communication tool "Slack".
    • Posted via "Slack App".
    • Can post not only on public channels but also on private channels.
  • Automate postings with business data inserted.
    • e.g. Placed before the approval step, automatically notifies "arrival of approval".
    • e.g. Placed after the timer start, announces the "expense application deadline".
    • e.g. Notifies the long URL of Receive-Task.
  • Messages are posted in Block format.
    • The message posted by this Addon consists of a title (header) block and a body (section) block.
    • It is also possible to attach key-value (2-col TSV) information to the body block.
      • Up to the 5th row is displayed.
      • Data that is not tab-delimited will be ignored.
      • Ignored after the 3rd column and 6th row.
      • Empty cells show "n/a".
    • You can use mrkdwn notation or colon emoji notation for the string part.
  • The channel is specified by the channel name (eg "#general") or ID (eg "C1234567890").
    • To reduce the risk of trouble, set an ID that is an invariant value.
  • You need to create a "Slack app" in advance.
    • For new creation, [Settings and Management] > [Manage Apps] > [Build] > "Create New App"
    • Setting Example
      • (Wizard)
        • App Name: "BPMS Notification"
        • Pick a workspace to develop your app in: (Select Your Org)
      • Basic Information
        • Display Information: (Add Bot-Logo)
      • OAuth & Permissions
        • Bot Token Scopes: Added "chat:write" (and "files:write")
        • Click "Install to Workspace" to get "Bot User OAuth Token"
    • You need to add "Slack App" to your workspace in advance.
      • Bottom left of workspace, [Add apps]
    • You need to add "Slack app" to each channel in advance.
      • Upper right of each channel, [Details] > [More] > [Add apps]

Capture

Posts a message in block format. A table data can be attached as needed. It is also possible to change to an ephemeral message that is displayed only to a specific user.
Posts a message in block format. A table data can be attached as needed. It is also possible to change to an ephemeral message that is displayed only to a specific user.
Posts a message in block format. A table data can be attached as needed. It is also possible to change to an ephemeral message that is displayed only to a specific user.

Appendix

  • Setting example of "HTTP Authentication"
    • "Token Fixed Value"
      • Name: NotificatonToSlack
      • Token: {Bot User OAuth Token}
  • Also possible to post an "Ephemeral Message" that is displayed only to that user.
    • Recipients can see the "Only visible to you".
    • The background color of the post will be gray.
    • Ephemeral Message is not persistent between terminals or sessions.
    • If you do something, the message will disappear.
    • The user must be on the specified channel.
    • SLACK USER is specified by the ID of the message receiving user.
    • UserID (Member ID) can be obtained from the details of "Profile" and URL.
    • Ephemeral Messages cannot be threaded.
  • For the thread_ts of the thread post, specify the time stamp (ts) of the parent message.
    • Thread posting to the time stamp (ts) of the child message is not possible.
      • No error will occur on API communication, but it will not be displayed.
  • If the title is set to exceed 150 characters, the 151st and subsequent characters will not be sent.
  • The category image URL must be public.
  • For more information on how to use Slack itself, refer to the Slack documentation.

See Also

Scroll to Top

Discover more from Questetra Support

Subscribe now to keep reading and get access to the full archive.

Continue reading