Created
October 29, 2017 09:55
-
-
Save andrei-markeev/5764e7b2177de73f0f5e0e34696857ec to your computer and use it in GitHub Desktop.
Node.js Azure Functions #spsbcn
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var csomapi = require("csom-node"); | |
// this is an example of Azure Function that connects to SharePoint via JSOM | |
module.exports = function (azureContext, req) { | |
var web; | |
initializeJSOM() | |
.then(ctx => { | |
web = ctx.get_web(); | |
ctx.load(web); | |
return executeJSOM(ctx); | |
}) | |
.then(() => { | |
azureContext.log(web.get_title()); | |
azureContext.res = { body: "Success!" }; | |
azureContext.done(); | |
}) | |
.catch(function() { | |
azureContext.log("ERROR", arguments); | |
azureContext.res = { status: 500, body: "Error occured!" }; | |
azureContext.done(); | |
}); | |
function initializeJSOM() { | |
return new Promise(function(resolve, reject) { | |
var settings = { | |
url: "https://markeev.sharepoint.com/", | |
clientId: process.env.SP_APP_ID, | |
clientSecret: process.env.SP_APP_SECRET | |
}; | |
csomapi.setLoaderOptions({url: settings.url}); //set CSOM library settings | |
var authCtx = new AuthenticationContext(settings.url); | |
authCtx.acquireTokenForApp(settings.clientId, encodeURIComponent(settings.clientSecret), function (err, data) { | |
if (err) { | |
reject(err); | |
return; | |
} | |
var ctx = new SP.ClientContext("/"); //set root web | |
authCtx.setAuthenticationCookie(ctx); //authenticate | |
resolve(ctx); | |
}); | |
}); | |
} | |
function executeJSOM(ctx) { | |
return new Promise((resolve, reject) => ctx.executeQueryAsync(resolve, reject)); | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var XMLHttpRequest = require("xhr2"); | |
// this is an example of Azure Function that connects to SharePoint via REST without using ADAL.js | |
module.exports = function (azureContext, req) { | |
var sp_url = "https://markeev.sharepoint.com/"; | |
var sp_access_token = ''; | |
getSharePointAccessToken(sp_url) | |
.then(access_token => { | |
sp_access_token = access_token; | |
// do REST calls here | |
return request(sp_url + "_api/web/title", { access_token: sp_access_token }); | |
}) | |
.then(responseText => { | |
azureContext.log(JSON.parse(responseText).value); | |
azureContext.done(); | |
}) | |
.catch(handleError); | |
function handleError(e) { | |
azureContext.log("Critical Error: ", e); | |
azureContext.res = { status: 500, body: e }; | |
azureContext.done(e); | |
} | |
function getSharePointAccessToken(url) { | |
return new Promise((resolve, reject) => { | |
var redirecturi = "https://localhost" | |
var appResource = "00000003-0000-0ff1-ce00-000000000000" | |
request(url + "_vti_bin/client.svc", { method: 'POST', body: "", access_token: " ", returnHeader: "WWW-Authenticate" }) | |
.then(wwwAuthHeader => { | |
if (!wwwAuthHeader) { | |
reject("Error retrieving realm!"); | |
return; | |
} | |
var realm = wwwAuthHeader.split(",")[0].split("=")[1].slice(1, -1); | |
var body = { | |
grant_type: 'client_credentials', | |
client_id: process.env.SP_APP_ID + "@" + realm, | |
client_secret: process.env.SP_APP_SECRET, | |
resource: appResource + "/" + url.match(/^https:\/\/([A-Za-z\.-]+)\//)[1] + "@" + realm, | |
redirect_uri: redirecturi | |
}; | |
var oauthUrl = "https://accounts.accesscontrol.windows.net/" + realm + "/tokens/OAuth/2"; | |
request(oauthUrl, { format: 'urlencoded', body, method: 'POST' }) | |
.then(responseText => resolve(JSON.parse(responseText).access_token)) | |
.catch(reject); | |
}) | |
.catch(reject); | |
}); | |
} | |
function request(url, options) { | |
return new Promise((resolve, reject) => { | |
var postBody = null; | |
options = options || {}; | |
if (options.body != null) { | |
if (options.format == 'urlencoded') | |
postBody = Object.keys(options.body).map(k => k + '=' + encodeURIComponent(options.body[k])).join('&'); | |
else if (options.format == 'json') | |
postBody = JSON.stringify(options.body); | |
else | |
postBody = options.body; | |
} | |
var xhr = new XMLHttpRequest(); | |
azureContext.log(options.method || "GET", url, "\n"); | |
xhr.open(options.method || "GET", url, true); | |
//Send the proper header information along with the request | |
if (options.format == 'urlencoded') | |
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); | |
else | |
xhr.setRequestHeader("Content-Type", "application/json"); | |
xhr.setRequestHeader("Accept", "application/json"); | |
if (options.access_token != null) | |
xhr.setRequestHeader("Authorization", "Bearer " + options.access_token); | |
xhr.onreadystatechange = function () {//Call a function when the state changes. | |
if (xhr.readyState == 4) { | |
//azureContext.log('\n\nHTTP/1.1 ' + xhr.status + '\n' + xhr.getAllResponseHeaders() + '\n\n' + xhr.responseText); | |
if (options.returnHeader) | |
resolve(xhr.getResponseHeader(options.returnHeader)); | |
else if (xhr.status >= 200 && xhr.status <= 299) | |
resolve(xhr.responseText); | |
else | |
reject(xhr.status); | |
} | |
} | |
xhr.send(postBody); | |
}); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var webpack = require('webpack'); | |
// this webpack build is alternative to azure-functions-pack | |
// how to pack modules for using with Azure Functions (you need to know webpack basics to do it): | |
// 1. install modules that you want to pack with npm install <module> | |
// 2. provide the entry files of those modules under "entry" node | |
// 4. run webpack using this config file | |
// 5. packed modules will be in build/node_modules | |
// for more details, please see webpack documentation | |
// if a node module uses dynamic imports, you might need to do some more steps | |
// example of custom packaging for csom-node with explanations can be found in https://markeev.com/posts/jsom-azure-function | |
module.exports = { | |
entry: { | |
'xhr2': './node_modules/xhr2/lib/xhr2.js', | |
'lodash': './node_modules/lodash/lib/lodash.js' | |
}, | |
output: { | |
path: __dirname + '/build', | |
libraryTarget: 'commonjs2', | |
filename: 'node_modules/[name].js' | |
}, | |
target: 'node', | |
node: { | |
__dirname: false | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment