Currently a http response exists in two forms:
context.res = bodyValue; // res is interpreted as 200 with body bodyValuecontext.res = { body: bodyValue, headers: ..., status: ... } // res is fully specified objectRemoving option 1 is something we ought to consider, as it has some negatives:
bodyValue has a body property (workaround is nested body inside body)headers and statuscontext.res = bodyValue; context.done(); vs context.res.send(bodyValue);figured this one out. 1.0 don't like raw body content. can't validate webhook that wanted text/plain response. argh.
@johnnliu for full control of the response (send raw payload, manage content type, etc), we've added a flag you can set.
Details are available here: https://github.com/Azure/azure-webjobs-sdk-script/issues/965#issuecomment-262618266
@fabiocav I tried this snippet to validate the SharePoint List web hook:
context.res = {
status: 200,
body: req.query.validationtoken,
headers: {
'Content-Type': 'text/plain'
},
isRaw: true
}
In req.query.validationtoken there is the sharepoint token for the validation that the function must to send back to SharePoint like a response in text plain, but I receive ever the message "Failed to validate the notification URL" in fact with postman if I call my function there is no response and the content type is not available
No news about this issue ?
Can you share the rest of your code? I just tried myself and this works fine - I get the code back with the correct content type. Your issue is likely that your output binding for the response is using $return but in your context.done() you're not returning the response there. If you want to set the response via context.res then change your http output binding name to res.
module.exports = function (context, req) {
context.res = {
status: 200,
body: req.query.validationtoken,
headers: {
'Content-Type': 'text/plain'
},
isRaw: true
};
context.done();
};
Only for testing I created this function:
`module.exports = function (context, req) {
context.log('Node.js HTTP trigger function processed a request. RequestUri=%s', req.originalUrl);
if (req) {
if (req.query && req.query.validationtoken) {
// if validationtoken is specified in query
// immediately return token as text/plain
context.log(req.query);
context.log(req.query.validationtoken);
context.res = {
status: 200,
body: req.query.validationtoken,
headers: {
'Content-Type': 'text/plain'
},
isRaw: true
};
}
}
context.done();
};`
I'm using postman to send a post to my azure function with in query string validationtoken=123456778 as I expect from SharePoint but doesn't work for me:
As I mentioned above, I think the issue is your function.json and how your response is bound. Here's what mine looks like. Note that my output is res not $return. What does yours look like?
{
"bindings": [
{
"authLevel": "function",
"type": "httpTrigger",
"direction": "in",
"name": "req"
},
{
"type": "http",
"direction": "out",
"name": "res"
}
]
}
Thank you @mathewc the bindings was wrong "$return" ;-)
Maybe slightly OT but is there a specific reason you didn't just pass in the standard IncomingMessage and ServerResponse objects from node but rolled your own req and res types?
@stefan-akelius At present all function triggers are routed through a C# process. We use edgejs for interop between node and C#. The requests are served in C# so unfortunately we don't have access to a node generated IncomingMessage or ServerResponse (I'd love to support those types natively as well).
@stefan-akelius You might have a look at azure-function-express (we needs contributors)
Most helpful comment
@stefan-akelius At present all function triggers are routed through a C# process. We use edgejs for interop between node and C#. The requests are served in C# so unfortunately we don't have access to a node generated
IncomingMessageorServerResponse(I'd love to support those types natively as well).