Slack: Slack Message JSON Parsing

Slack: Slack メッセージ JSON パース

Extract text from Message JSON data received from Slack. If there are attached files, the files are downloaded. However, only one attachment file is supported.

Auto Step icon
Configs for this Auto Step
conf_Json
C1: STRING DATA for received Message JSON from Slack *
conf_Text
C2: STRING DATA for Slack Message Text (update) *
conf_Url
C3: STRING DATA for Slack Message URL (update)
conf_ChannelId
C4: STRING DATA for Slack Message Channel ID (update)
conf_Ts
C5: STRING DATA for Slack Message thread_ts (update)
conf_OAuth2
C6: OAuth2 Setting (for attachment download)
conf_Attachment
C7: FILE DATA for Slack Message Attachment (update)
Script (click to open)

main();
function main() {

  //// == Config Retrieving / 工程コンフィグの参照 ==
  const json = engine.findDataByNumber( configs.get("conf_Json") ) + "";

  const dataId_text = configs.get( "conf_Text" );
  const dataId_url  = configs.get( "conf_Url" );
  const dataId_channelId  = configs.get( "conf_ChannelId" );
  const dataId_ts  = configs.get( "conf_Ts" );

  const oauth2 = configs.get("conf_OAuth2");
  const dataId_attachment = configs.get( "conf_Attachment" );
  let processFiles;
  if ( dataId_attachment !== "" ) {
    processFiles = engine.findDataByNumber( dataId_attachment );
    // java.util.ArrayList <com.questetra.bpms.core.event.scripttask.QfileView>
  }
  if (processFiles === null) {
    processFiles = new java.util.ArrayList();
  }

  //// == Calculating / 演算 ==
  const jsonObj = JSON.parse( json );
  //JSONがない・JSONにeventがない場合はエラー
  if ( !( jsonObj ) ) {
    throw `JSON data none`;
  }
  if ( !( 'event' in jsonObj ) ) {
    throw `json.event none`;
  }

  const text    = jsonObj.event.text + "";

  const teamId    = jsonObj.team_id + "";
  const channelId = jsonObj.event.channel + "";
  const ts        = jsonObj.event.event_ts + "";
  const messageUrl = "https://app.slack.com/client/" + teamId + "/" + channelId + "/" + ts + "/"


  //// == Data Retrieving / ワークフローデータへの代入 == 
  engine.setDataByNumber( dataId_text, text );
  if ( dataId_url !== "" ) {
    engine.setDataByNumber( dataId_url, messageUrl );
  }
  if ( dataId_channelId !== "" ) {
    engine.setDataByNumber( dataId_channelId, channelId );
  }
  if ( dataId_ts !== "" ) {
    engine.setDataByNumber( dataId_ts, ts );
  }

  if ( dataId_attachment !== "" ) {
    if ( jsonObj.event.files ) {
      const fileUrl = jsonObj.event.files[0].url_private_download + "";
      engine.log("fileUrl:" + fileUrl);
      const fileName = jsonObj.event.files[0].name + "";
      engine.log("fileName:" + fileName);

      const response = accessToTheUrl( oauth2, fileUrl );
      const qfile = saveFile( fileName, response );
      updateData( processFiles, dataId_attachment, qfile );
    }
  }
}

/**
  * ダウンロードファイルの URL に GET リクエストを送信し、ファイルを取得する
  * @param {String} oauth2
  * @param {String} fileUrl  ダウンロードファイルの URL
  * @return {HttpResponseWrapper} response  レスポンス
  */
function accessToTheUrl( oauth2, fileUrl ) {
  let response;
  
  try {
    let httpRequest = httpClient.begin()
    if ( oauth2 !== "" && oauth2 !== null ) {
      httpRequest = httpRequest.authSetting(oauth2);
    }
    response = httpRequest.get( fileUrl );
  } catch (e) {
    throw `Unable to access ${fileUrl}.`;
  }

  const httpStatus  = response.getStatusCode();
  engine.log( `STATUS: ${httpStatus}` );
  if (httpStatus >= 300) {
    engine.log( response.getResponseAsString() );
    throw `Failed to download. STATUS: ${httpStatus}`;
  }

  return response;
}


/**
  * ダウンロードしたファイルを名前を付けて保存する
  * @param {String} name  保存する際のファイル名
  * @param {HttpResponseWrapper} response  レスポンス
  * @return {Qfile} qfile  ファイル
  */
function saveFile( name, response ) {
  const qfile = new com.questetra.bpms.core.event.scripttask.NewQfile(
    name, response.getContentType(), response.getResponse()
  );
  return qfile;
}

/**
  * ダウンロードしたファイルをデータ項目に出力する
  * @param {Array<Qfile>} processFiles  ファイルの配列
  * @param {String} dataId  ダウンロードファイルを追加保存するデータ項目のデータ定義番号
  * @param {Qfile} qfile  ファイル
  */
function updateData( processFiles, dataId, qfile ) {
  processFiles.add( qfile );
  engine.setDataByNumber( dataId, processFiles );
}

Download

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

Notes

  • Configuration on the Questetra side
    • The following settings should be made so that the JSON received from the HTTP response content of the Message Start Event (Webhook) can be folded back, and then release the app
{
  "challenge": #{#q_Slack_JSON},
  "processInstanceId" : #{processInstanceId}
}
  • Configuration on the Slack side
    • Configuration example
      • Select From scratch
        • App Name: Questetra App (Any name is acceptable)
        • Pick a workspace to develop your app in: (Select the workspace you want to link to)
      • Event Subscriptions
        • Enable Events: Set to “On”
        • Request URL: Enter the URL of the Questetra-side Webhook (note that verification will not pass if the aforementioned Questetra-side HTTP response settings have not been made).
        • Subscribe to bot events: Add ‘message.channels’
      • OAuth & Permissions
      • Basic Information
        • Install to Workspace in Building Apps for Slack > Install your app
    • Add apps created from the ‘Integration’ section of the target channel details in Slack

Capture

See Also

%d bloggers like this: