3
2
2026-04-22
(C) Questetra, Inc. (MIT License)
This item posts a message, or a reply to a message, in a channel on Microsoft Teams.
この工程は、Microsoft Teams のチャンネルに、メッセージまたはメッセージへの返信を投稿します。
https://support.questetra.com/bpmn-icons/service-task-microsoft-teams-channel-post/
https://support.questetra.com/ja/bpmn-icons/service-task-microsoft-teams-channel-post/
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
{
const oauth2 = httpClient.createAuthSettingOAuth2(
'Microsoft Teams',
'https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize',
'https://login.microsoftonline.com/organizations/oauth2/v2.0/token',
'https://graph.microsoft.com/ChannelMessage.Send offline_access',
'client_id',
'client_secret',
'access_token'
);
configs.putObject('conf_OAuth2', oauth2);
configs.put('conf_TargetUrl', targetUrl);
configs.put('conf_Subject', subject);
configs.put('conf_Markdown', markdownText);
if (savePostUrl) {
const postUrlDef = engine.createDataDefinition('投稿 URL', 1, 'q_postUrl', 'STRING_TEXTFIELD');
configs.putObject('conf_PostUrl', postUrlDef);
return postUrlDef;
}
return null;
};
/**
* 異常系のテスト
* @param {String} errorMsg
*/
const assertError = (errorMsg) => {
let failed = false;
try {
main();
} catch (e) {
failed = true;
expect(e.message).toEqual(errorMsg);
}
if (!failed) {
fail('No error was thrown.');
}
};
/**
* POST リクエストの検証
* @param {Object} request
* @param {String} teamId
* @param {String} channelId
* @param {String|null} messageId
* @param {String} subject
* @param {String} markdownText
*/
const assertPostRequest = ({url, method, contentType, headers, body}, teamId, channelId, messageId, subject, markdownText) => {
let expectedUrl;
if (messageId !== null) {
expectedUrl = `${GRAPH_URI}teams/${encodeURIComponent(teamId)}/channels/${encodeURIComponent(channelId)}/messages/${encodeURIComponent(messageId)}/replies`;
} else {
expectedUrl = `${GRAPH_URI}teams/${encodeURIComponent(teamId)}/channels/${encodeURIComponent(channelId)}/messages`;
}
expect(url).toEqual(expectedUrl);
expect(method).toEqual('POST');
expect(contentType).toEqual('application/json; charset=UTF-8');
expect(headers.Authorization).toEqual('Bearer access_token');
const bodyObj = JSON.parse(body);
expect(bodyObj.body.contentType).toEqual('html');
expect(bodyObj.body.content).toEqual(markdown.toHtml(markdownText));
if (subject !== '' && messageId === null) {
expect(bodyObj.subject).toEqual(subject);
} else {
expect(bodyObj.subject).toEqual(undefined);
}
};
/**
* 投稿先 URL が空(データ項目の値が空)
*/
test('Error - Target URL is empty (data item with null value)', () => {
prepareConfigs('', '', '**Hello**', false);
// conf_TargetUrl をデータ項目に差し替え(値未設定 → null)
const targetUrlDef = engine.createDataDefinition('投稿先 URL', 2, 'q_targetUrl', 'STRING_TEXTFIELD');
configs.putObject('conf_TargetUrl', targetUrlDef);
assertError('Target URL is empty.');
});
/**
* 投稿文が空
*/
test('Error - Post Content is empty', () => {
prepareConfigs(SAMPLE_CHANNEL_URL, '', '', false);
assertError('Post Content is empty.');
});
/**
* URL に channel も message もない
*/
test('Error - Invalid Target URL', () => {
const url = 'https://teams.microsoft.com/l/something/else';
prepareConfigs(url, '', '**Hello**', false);
assertError(`Invalid Target URL: ${url}`);
});
/**
* チャンネル URL に groupId がない
*/
test('Error - Channel URL without groupId', () => {
const url = `https://teams.microsoft.com/l/channel/${encodeURIComponent(SAMPLE_CHANNEL_ID)}/General?tenantId=11111111-2222-3333-4444-555555555555`;
prepareConfigs(url, '', '**Hello**', false);
assertError(`groupId not found in target URL: ${url}`);
});
/**
* メッセージ URL に groupId がない
*/
test('Error - Message URL without groupId', () => {
const url = `https://teams.microsoft.com/l/message/${encodeURIComponent(SAMPLE_CHANNEL_ID)}/${SAMPLE_MESSAGE_ID}?tenantId=11111111-2222-3333-4444-555555555555`;
prepareConfigs(url, '', '**Hello**', false);
assertError(`groupId not found in target URL: ${url}`);
});
/**
* POST リクエストでエラー
*/
test('Error - POST request fails', () => {
prepareConfigs(SAMPLE_CHANNEL_URL, '', '**Hello**', false);
httpClient.setRequestHandler((request) => {
assertPostRequest(request, SAMPLE_TEAM_ID, SAMPLE_CHANNEL_ID, null, '', '**Hello**');
return httpClient.createHttpResponse(400, 'application/json', '{}');
});
assertError('Failed to post message. status: 400');
});
/**
* 成功 - チャンネルに投稿、件名なし、投稿 URL 保存なし
*/
test('Success - Channel post, no subject, postUrl not saved', () => {
prepareConfigs(SAMPLE_CHANNEL_URL, '', '**Hello**', false);
const webUrl = 'https://teams.microsoft.com/l/message/channelId/1234567890';
httpClient.setRequestHandler((request) => {
assertPostRequest(request, SAMPLE_TEAM_ID, SAMPLE_CHANNEL_ID, null, '', '**Hello**');
return httpClient.createHttpResponse(201, 'application/json', JSON.stringify({id: '1234567890', webUrl}));
});
main();
});
/**
* 成功 - チャンネルに投稿、件名あり、投稿 URL 保存あり
*/
test('Success - Channel post, with subject, postUrl saved', () => {
const postUrlDef = prepareConfigs(SAMPLE_CHANNEL_URL, 'Test Subject', '**Hello**', true);
const webUrl = 'https://teams.microsoft.com/l/message/channelId/1234567890';
httpClient.setRequestHandler((request) => {
assertPostRequest(request, SAMPLE_TEAM_ID, SAMPLE_CHANNEL_ID, null, 'Test Subject', '**Hello**');
return httpClient.createHttpResponse(201, 'application/json', JSON.stringify({id: '1234567890', webUrl}));
});
main();
expect(engine.findData(postUrlDef)).toEqual(webUrl);
});
/**
* 成功 - 投稿先 URL をデータ項目から取得
*/
test('Success - Target URL from data item', () => {
prepareConfigs('', '', '**Hello**', false);
// conf_TargetUrl をデータ項目に差し替え
const targetUrlDef = engine.createDataDefinition('投稿先 URL', 2, 'q_targetUrl', 'STRING_TEXTFIELD');
engine.setData(targetUrlDef, SAMPLE_CHANNEL_URL);
configs.putObject('conf_TargetUrl', targetUrlDef);
const webUrl = 'https://teams.microsoft.com/l/message/channelId/1234567890';
httpClient.setRequestHandler((request) => {
assertPostRequest(request, SAMPLE_TEAM_ID, SAMPLE_CHANNEL_ID, null, '', '**Hello**');
return httpClient.createHttpResponse(201, 'application/json', JSON.stringify({id: '1234567890', webUrl}));
});
main();
});
/**
* 成功 - メッセージへの返信、件名なし
*/
test('Success - Reply, no subject', () => {
prepareConfigs(SAMPLE_MESSAGE_URL, '', '**Reply**', false);
const webUrl = 'https://teams.microsoft.com/l/message/channelId/9876543210';
httpClient.setRequestHandler((request) => {
assertPostRequest(request, SAMPLE_TEAM_ID, SAMPLE_CHANNEL_ID, SAMPLE_MESSAGE_ID, '', '**Reply**');
return httpClient.createHttpResponse(201, 'application/json', JSON.stringify({id: '9876543210', webUrl}));
});
main();
});
/**
* 成功 - メッセージへの返信、件名あり(件名は無視される)
*/
test('Success - Reply with subject (subject ignored)', () => {
const postUrlDef = prepareConfigs(SAMPLE_MESSAGE_URL, 'Ignored Subject', '**Reply**', true);
const webUrl = 'https://teams.microsoft.com/l/message/channelId/9876543210';
httpClient.setRequestHandler((request) => {
assertPostRequest(request, SAMPLE_TEAM_ID, SAMPLE_CHANNEL_ID, SAMPLE_MESSAGE_ID, 'Ignored Subject', '**Reply**');
return httpClient.createHttpResponse(201, 'application/json', JSON.stringify({id: '9876543210', webUrl}));
});
main();
expect(engine.findData(postUrlDef)).toEqual(webUrl);
});
]]>