UPDATED QUESTION 16-10-2020 I simplified the code so it doesn't contain an if statement anymore to run the postMessageToTeams function and I added the error response I receive in the catch. Hopefully this makes it easier to debug.
It works when I run the script from my Visual Studio terminal but it doesn't when running it from my cmder. So I reckon it has something to do with my cmder settings.
Goal
I'm running some automated tasks through testcafe and would like to be notified in Microsoft Teams when a certain task is done. To do so, I created a webhook in my channel and wanted to send a POST request to my webhook URL. However, when doing so, I receive a 405 error. When trying it out in Postman it does work with the same JSON data.
My code (I slightly altered the code from https://gist.github.com/johnsibly/806a7190fbdc4b439ed040f327e6e679 for this test)
const axios = require('axios'); // axios must be installed via npm i axios
const webhookURL = "https://outlook.office.com/webhook/xxxxx"; // this holds my webhook URL
postMessageToTeams();
async function postMessageToTeams(title, message) {
const card = {
"@type": "MessageCard",
"@context": "http://schema.org/extensions",
"themeColor": "0072C6",
"summary": "Summary description",
"sections": [
{
"activityTitle": "Testcafe",
"text": "Testcafe is talking to you"
}
]
};
try {
const response = await axios.post(webhookURL, card, {
headers: {
'content-type': 'application/vnd.microsoft.teams.card.o365connector',
'content-length': `${card.toString().length}`,
},
});
return `${response.status} - ${response.statusText}`;
} catch (err) {
console.log(err)
return err;
}
}
Error response
{
status: 405,
statusText: 'Method Not Allowed',
headers: {
'cache-control': 'no-cache',
pragma: 'no-cache',
allow: 'POST',
'content-length': '43',
'content-type': 'text/plain; charset=utf-8',
expires: '-1',
server: 'Microsoft-IIS/10.0',
'request-id': 'b565e1ec-79a2-4fc1-99e1-56e8caa98a48',
'strict-transport-security': 'max-age=31536000; includeSubDomains; preload',
'x-calculatedbetarget': 'AM0PR02MB5570.eurprd02.prod.outlook.com',
'x-backendhttpstatus': '405',
'x-aspnet-version': '4.0.30319',
'x-cafeserver': 'AM3PR07CA0145.EURPRD07.PROD.OUTLOOK.COM',
'x-beserver': 'AM0PR02MB5570',
'x-proxy-routingcorrectness': '1',
'x-proxy-backendserverstatus': '405',
'x-powered-by': 'ASP.NET',
'x-feserver': 'AM3PR07CA0145',
date: 'Fri, 16 Oct 2020 07:58:34 GMT',
connection: 'close'
},
config: {
url: 'https://outlook.office.com/webhook/xxxx',
method: 'post',
data: '{"@type":"MessageCard","@context":"http://schema.org/extensions","themeColor":"0072C6","summary":"Summary description","sections":[{"activityTitle":"Testcafe","text":"Testcafe is talking to you"}]}',
headers: {
Accept: 'application/json, text/plain, */*',
'User-Agent': 'axios/0.20.0'
},
transformRequest: [ [Function: transformRequest] ],
transformResponse: [ [Function: transformResponse] ],
timeout: 0,
adapter: [Function: httpAdapter],
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
maxBodyLength: -1,
validateStatus: [Function: validateStatus]
},
request: <ref *1> ClientRequest {
_events: [Object: null prototype] {
socket: [Function (anonymous)],
abort: [Function (anonymous)],
aborted: [Function (anonymous)],
connect: [Function (anonymous)],
error: [Function (anonymous)],
timeout: [Function (anonymous)],
prefinish: [Function: requestOnPrefinish]
},
_eventsCount: 7,
_maxListeners: undefined,
outputData: [],
outputSize: 0,
writable: true,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: false,
useChunkedEncodingByDefault: false,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: 0,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
socket: TLSSocket {
_tlsOptions: [Object],
_secureEstablished: true,
_securePending: false,
_newSessionPending: false,
_controlReleased: true,
_SNICallback: null,
servername: 'outlook.office.com',
alpnProtocol: false,
authorized: true,
authorizationError: null,
encrypted: true,
_events: [Object: null prototype],
_eventsCount: 9,
connecting: false,
_hadError: false,
_parent: null,
_host: 'outlook.office.com',
_readableState: [ReadableState],
readable: true,
_maxListeners: undefined,
_writableState: [WritableState],
writable: false,
allowHalfOpen: false,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: undefined,
_server: null,
ssl: [TLSWrap],
_requestCert: true,
_rejectUnauthorized: true,
parser: null,
_httpMessage: [Circular *1],
[Symbol(res)]: [TLSWrap],
[Symbol(asyncId)]: 15,
[Symbol(kHandle)]: [TLSWrap],
[Symbol(lastWriteQueueSize)]: 0,
[Symbol(timeout)]: null,
[Symbol(kBuffer)]: null,
[Symbol(kBufferCb)]: null,
[Symbol(kBufferGen)]: null,
[Symbol(kCapture)]: false,
[Symbol(kBytesRead)]: 0,
[Symbol(kBytesWritten)]: 0,
[Symbol(connect-options)]: [Object]
},
_header: 'GET /webhook/xxxx HTTP/1.1\r\n' +
'Accept: application/json, text/plain, */*\r\n' +
'User-Agent: axios/0.20.0\r\n' +
'Host: outlook.office.com\r\n' +
'Connection: close\r\n' +
'\r\n',
_onPendingData: [Function: noopPendingOutput],
agent: Agent {
_events: [Object: null prototype],
_eventsCount: 2,
_maxListeners: undefined,
defaultPort: 443,
protocol: 'https:',
options: [Object],
requests: {},
sockets: [Object],
freeSockets: {},
keepAliveMsecs: 1000,
keepAlive: false,
maxSockets: Infinity,
maxFreeSockets: 256,
maxCachedSessions: 100,
_sessionCache: [Object],
[Symbol(kCapture)]: false
},
socketPath: undefined,
method: 'GET',
maxHeaderSize: undefined,
path: '/webhook/xxxx',
_ended: true,
res: IncomingMessage {
_readableState: [ReadableState],
readable: false,
_events: [Object: null prototype],
_eventsCount: 3,
_maxListeners: undefined,
socket: [TLSSocket],
httpVersionMajor: 1,
httpVersionMinor: 1,
httpVersion: '1.1',
complete: true,
headers: [Object],
rawHeaders: [Array],
trailers: {},
rawTrailers: [],
aborted: false,
upgrade: false,
url: '',
method: null,
statusCode: 405,
statusMessage: 'Method Not Allowed',
client: [TLSSocket],
_consuming: false,
_dumped: false,
req: [Circular *1],
responseUrl: 'https://outlook.office.com/webhook/xxxx',
redirects: [],
[Symbol(kCapture)]: false
},
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
reusedSocket: false,
_redirectable: Writable {
_writableState: [WritableState],
writable: true,
_events: [Object: null prototype],
_eventsCount: 2,
_maxListeners: undefined,
_options: [Object],
_ended: true,
_ending: true,
_redirectCount: 1,
_redirects: [],
_requestBodyLength: 197,
_requestBodyBuffers: [],
_onNativeResponse: [Function (anonymous)],
_currentRequest: [Circular *1],
_currentUrl: 'https://outlook.office.com/webhook/xxxx',
_isRedirect: true,
[Symbol(kCapture)]: false
},
[Symbol(kCapture)]: false,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype] {
accept: [Array],
'user-agent': [Array],
host: [Array]
}
},
data: 'Invalid webhook request - GET not supported'
}
If you'd need the entire error message in order to properly debug this, please let me know.
Postman
Body (raw) of POST request
{
"@type": "MessageCard",
"@context": "http://schema.org/extensions",
"themeColor": "0072C6",
"summary": "Summary description",
"sections": [
{
"activityTitle": "Testcafe",
"text": "Testcafe is talking to you"
}
]
}
Response
1, and the message is posted in my Teams channel