2023-10-03 3 2 (C) Questetra, Inc. (MIT License) This item posts a message to Slack. Blocks are available. この工程は、Slack にメッセージを投稿します。Blocks に対応しています。 https://support.questetra.com/bpmn-icons/service-task-slack-message-post/ https://support.questetra.com/ja/bpmn-icons/service-task-slack-message-post/ iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAABFBJREFUWEfN l39ME2cYx79vofwSEljXirCwLWOSYJRotjgnJDPZWNKjg4BYpDgnCCuYKCxmxLUu7pcJZupitmqY XTfFLRnaqeXqYibbXExIdNQ/tj+WLMvCEjPoGGABxULf5b3Sy7W9a0+zhd0f/aP3Ps/zeZ/fR7DE D1Fr31RgygrNh2pBsYmCrAXoYwDyFuUnAPI7AfWB4FtNqsbtueWZVaM7KYBRb8wnIN0UsALIUKMU wF0CnKCgPV6/989EMgkBjIYqKyh9H8AylYZjj82AkL3esYETSvKKANzDnIMStD+g4SgxQnGc/4vv kNMlC2A0cJ+DYuu/YVzUQfCFd4xvjNUZB6Dm5kUlRRj5ZUTUlZOXA41Gg6nxqYTMcp6IAliM+XEl LcyQa9iFzGUZmJ6cxrbVL6PhNTO2dG4BIQS8i4ejW1E8rJaQdmlOiAAs2wHya6KEaznQjNqOWpHv 1MFTgvGMrHBxzAfnUV1YkyxyMwAtjlSHCMDpuaMU6EwkXVZRhoPn3hOPeD+7hBctlUhJTRH/4wxV yQBAgA94P98lOIT9sCazEAyNq6lzBtHR0460jDSc+9CNtndb7xuA9YkUrUbHmpUAwBm4JkpxOha9 4PEVaHmrBfmP5ke9unc3CM9JDwb7B3Hx1oU4gFXrS9HU3YShr4dwofeirEcIwTZ+jO8LA+g5JwWa Y0/2/XQaeYZIt43Xs+eFThy5dDgKwLyyAWd+7kOqNlUQ6GnrwdXzP8QJE+AT3s+3CABGfdUwQNfG nhoY9QjZrfSwJDR3mZGemS4cCd4Lwv2RW/gv8jAvHd51REYF8Xn9A+sWAbi/JYNFPGz71IZnjRtk 7c/dmYOl1ILttu0w7TQJZxyvO6B/RI/63fViVbRteBWjI6NyOia8fv6hCABVumVxWTHWbFyNhfkF TI3fDt90LohrA9dEEZYrLFSjf4xBl6/DqmdKMTt9B5fPXEZoIaToQa+fD/vXqOdkAXbsfwV1u+pA NERwr/nJBnw81AvdCp1wq53rW4XbN7+5Q4y51NqkfxLW8nYEJgKyEFIA2RBIM1wuvr32XjTubUR2 brbiLRN0R2kI5JPw7G/9yMzOFJT7vvdh5vYsyk0bRWOsEZWVr0HhE4WKAM4DTrgdXyVOQqUyfPr5 p9D6TisCkwHYN9vReawrDsD1tgs21xsoWVcSZYTlzPB3PhyyHgINxUc4qgyVGlEs9j7nvjiAXH0u snKy8OOVGwo3lXdOVCNS24rlAKSz4ObVm7BttiuGQ/IiuhWzF2qG0Z6ju1FpqRT19B/rR421Bto0 rfAfc/tLBdVJAeKGUbgUk4/j5UXL4bx+UuiOLK6NpRZhMFVUV4iJaq/fnwxAfhwLEOElNOFGwUpu U91zuPLlIGYD4c2bTci0dC2uf3MjmXHlhSQiqWYlS25FIfFkltP/31L6X3jivtfyCMSSfpiIEEv5 aSZNpSX7OH3QjFcr9w829dcwn81r2gAAAABJRU5ErkJggg== { if (oauth2){ const auth_OAuth2 = httpClient.createAuthSettingOAuth2( 'Slack', 'https://slack.com/oauth/v2/authorize', 'https://slack.com/api/oauth.v2.access', 'chat:write,users:read,users:read.email', 'consumer_key', 'consumer_secret', 'access_token' ); configs.putObject('conf_OAuth2', auth_OAuth2); } else { configs.put('conf_OAuth2', ''); } if (token){ const auth_Token = httpClient.createAuthSettingToken( 'Slack Bot Token', 'slack-bot-token' ); configs.putObject('conf_Token', auth_Token); } else { configs.put('conf_Token', ''); } const channelDef = engine.createDataDefinition('チャンネル', 1, 'q_channel', 'STRING_TEXTFIELD'); engine.setData(channelDef, channel); configs.putObject('conf_Channel', channelDef); const threadDef = engine.createDataDefinition('スレッド', 2, 'q_thread', 'STRING_TEXTFIELD'); engine.setData(threadDef, thread); configs.putObject('conf_Thread', threadDef); configs.putObject('conf_ReplyBroadcast', replyBroadcast); configs.put('conf_Blocks', blocks === null ? '' : JSON.stringify(blocks)); configs.put('conf_Text', text); }; /** * POSTリクエストのテスト(チャット投稿) * @param {Object} request * @param request.url * @param request.method * @param request.contentType * @param request.body * @param channel * @param thread * @param blocks * @param text */ const assertPostRequest = ({url, method, contentType, body}, channel, thread, replyBroadcast, blocks, text) => { expect(url).toEqual('https://slack.com/api/chat.postMessage'); expect(method).toEqual('POST'); expect(contentType).toEqual('application/json; charset=UTF-8'); const bodyObj = JSON.parse(body); expect(bodyObj.channel).toEqual(channel); if (thread === null) { expect(bodyObj['thread_ts']).toEqual(undefined); expect(bodyObj['reply_broadcast']).toEqual(undefined); } else { expect(bodyObj['thread_ts']).toEqual(thread); expect(bodyObj['reply_broadcast']).toEqual(replyBroadcast); } if (blocks === null) { expect(bodyObj.blocks).toEqual(undefined); } else { expect(bodyObj.blocks).toEqual(blocks.blocks); } expect(bodyObj.text).toEqual(text); }; /** * POST リクエストのレスポンスを準備(チャット投稿) * @param channel * @param text * @return responseObj */ const preparePostResponse = (channel, text) => { return { "ok": true, "channel": `${channel}`, "ts": "1650857142.223299", "message": { "type": "message", "subtype": "bot_message", "text": `${text}`, "ts": "1650857142.223299", "bot_id": "B01JPAT1P4J" } }; }; /** * 認証設定が両方されていない場合 */ test('No Authorization Setting', () => { prepareConfigs('channel1', null, false, null, 'text1', false, false); try { main(); } catch (e) { const errorMsg = 'No Authorization Setting.'; expect(e.message).toEqual(errorMsg); } }); /** * POST API リクエストでエラーになる場合(チャット投稿) */ test('POST Failed', () => { prepareConfigs('channel1', null, false, null, 'text1', true, false); httpClient.setRequestHandler((request) => { assertPostRequest(request, 'channel1', null, false, null, 'text1'); return httpClient.createHttpResponse(200, 'application/json', JSON.stringify({ "ok": false, "error": "channel_not_found" })); }); try { main(); } catch (e) { expect(e.message).toEqual('response is not ok. error: channel_not_found'); } }); /** * チャット投稿成功の場合 * スレッド指定なし * Blocks 指定なし * C1-a: HTTP 認証設定 (Questetra が登録済みの Bot を使用する場合) 設定 * C1-b: HTTP 認証設定 (独自に登録した Bot を使用する場合) 設定 */ test('Success - no thread, no blocks', () => { prepareConfigs('channel2', null, false, null, 'text2', true , true); httpClient.setRequestHandler((request) => { assertPostRequest(request, 'channel2', null, false, null, 'text2'); return httpClient.createHttpResponse(200, 'application/json', JSON.stringify(preparePostResponse('channel2', 'text2'))); }); main(); }); /** * チャット投稿成功の場合 * スレッド指定あり * Blocks 指定あり * C1-a: HTTP 認証設定 (Questetra が登録済みの Bot を使用する場合) 設定 * C1-b: HTTP 認証設定 (独自に登録した Bot を使用する場合) 未設定 */ test('Success - with thread, with blocks', () => { const blocks = { "blocks": [ { "type": "section", "text": { "type": "plain_text", "text": "This is a plain text section block.", "emoji": true } }, { "type": "section", "text": { "type": "plain_text", "text": "This is a plain text section block.", "emoji": true } } ] }; prepareConfigs('channel3', 'thread3', false, blocks, 'text3', true , false); httpClient.setRequestHandler((request) => { assertPostRequest(request, 'channel3', 'thread3', false, blocks, 'text3'); return httpClient.createHttpResponse(200, 'application/json', JSON.stringify(preparePostResponse('channel3', 'text3'))); }); main(); }); /** * チャット投稿成功の場合 * スレッド指定あり * reply_broadcast * Blocks 指定なし * C1-a: HTTP 認証設定 (Questetra が登録済みの Bot を使用する場合) 未設定 * C1-b: HTTP 認証設定 (独自に登録した Bot を使用する場合) 設定 */ test('Success - with thread, reply_broadcast, no blocks', () => { prepareConfigs('channel4', 'thread4', true, null, 'text4', false , true); httpClient.setRequestHandler((request) => { assertPostRequest(request, 'channel4', 'thread4', true, null, 'text4'); return httpClient.createHttpResponse(200, 'application/json', JSON.stringify(preparePostResponse('channel3', 'text3'))); }); main(); }); /** * Block Kit が不正な場合 */ test('Invalid Blocks - not JSON', () => { prepareConfigs('channel4', null, false, 'text', 'text4', true , true); try { main(); } catch (e) { const errorMsg = `Block Kit must be JSON like below.\n{ "blocks": [...] }`; expect(e.message).toEqual(errorMsg); } }); /** * Block Kit が不正な場合 */ test('Invalid Blocks - root it not blocks', () => { prepareConfigs('channel5', null, false, {type: 'text'}, 'text5', true , true); try { main(); } catch (e) { const errorMsg = `Block Kit must be JSON like below.\n{ "blocks": [...] }`; expect(e.message).toEqual(errorMsg); } }); /** * Text が不正な場合 */ test('Invalid Text - empty', () => { prepareConfigs('channel6', null, false, { 'blocks': [] }, '', true , true); try { main(); } catch (e) { const errorMsg = `Markdown must not be blank.`; expect(e.message).toEqual(errorMsg); } }); /** * Channel が不正な場合 */ test('Invalid Channel - empty', () => { prepareConfigs(null, null, false, null, 'text7', true , true); try { main(); } catch (e) { const errorMsg = `Channel must not be blank.`; expect(e.message).toEqual(errorMsg); } }); ]]>