├── README.md ├── app.js ├── bin └── www ├── config.js ├── doc ├── login-sample.html ├── post-html-sample.html ├── post-multi-part-with-image.html ├── post-pdf-attachment.html ├── post-with-url-as-image.html └── readme.html ├── file.pdf ├── image.jpg ├── images ├── HostsFile.png └── OneNoteMSAScreen.png ├── lib ├── create-examples.js └── liveconnect-client.js ├── package.json ├── public ├── images │ └── spinner.gif ├── javascripts │ └── index.js └── stylesheets │ └── style.css ├── routes ├── callback.js └── index.js └── views ├── callback.jade ├── error.jade ├── index.jade ├── layout.jade └── result.jade /README.md: -------------------------------------------------------------------------------- 1 | 2 | ## OneNote API Node.js Sample README 3 | 4 | Created by Microsoft Corporation, 2014. Provided As-is without warranty. Trademarks mentioned here are the property of their owners. 5 | 6 | ### API functionality demonstrated in this sample 7 | 8 | The following aspects of the API are covered in this sample. You can 9 | find additional documentation at the links below. 10 | 11 | * [Log-in the user](http://msdn.microsoft.com/EN-US/library/office/dn575435.aspx) 12 | * [POST simple HTML to a new OneNote QuickNotes page](http://msdn.microsoft.com/EN-US/library/office/dn575428.aspx) 13 | * [POST multi-part message with image data included in the request](http://msdn.microsoft.com/EN-US/library/office/dn575432.aspx) 14 | * [POST page with a URL rendered as an image](http://msdn.microsoft.com/EN-US/library/office/dn575431.aspx) 15 | * [POST page with HTML rendered as an image](http://msdn.microsoft.com/en-us/library/office/dn575432.aspx) 16 | * [POST page with a PDF file rendered and attached](http://msdn.microsoft.com/EN-US/library/office/dn655137.aspx) 17 | * [Extract the returned oneNoteClientURL and oneNoteWebURL links](http://msdn.microsoft.com/EN-US/library/office/dn575433.aspx) 18 | 19 | ### Prerequisites 20 | 21 | **Tools and Libraries** you will need to download, install, and configure for your development environment. 22 | 23 | * [Node.js](http://nodejs.org/download) 24 | * [Express framework for Node.js](http://expressjs.com) 25 | * You have a normal URL with hostname (not just an IP address) to use for the Redirect URL. If you run this from your own desktop, you'll need to modify your Hosts file (in C:\Windows\System32\drivers\etc for Windows machines and /private/etc for Macs) and map your local server IP address to a new domain name, as in the following example. 26 |  27 | 28 | **Accounts** 29 | 30 | * As the developer, you'll need to [have a Microsoft account and get a client ID string](http://msdn.microsoft.com/EN-US/library/office/dn575426.aspx) 31 | so your app can authenticate with the Microsoft Live connect SDK. 32 | * As the user of the sample, you'll need a Microsoft account so the OneNote API can 33 | send the pages to your OneDrive. 34 | 35 | ### Using the sample 36 | 37 | After you've setup your web server described above,.... 38 | 39 | 1. Download the repo as a ZIP file to your local computer, and extract the files. Or, clone the repository into a local copy of Git. 40 | 2. Go to the [Microsoft app registration page](https://account.live.com/developers/applications/index). 41 | 3. On the API Settings page, set Mobile or desktop setting to No. 42 | 4. Set the Redirect URI to the domain name of your web site, as in the following example. The root domain name must be unique, so if you use one domain for testing and another for production, you'll need to register separate client ids and secrets for each domain. 43 |  44 | 5. On the App Setting page, copy the client ID and secret into the config.js file. 45 | 6. Open a command prompt and go to the root directory of the project. 46 | 7. Setup project dependencies with the `npm install` command. 47 | 8. Run the app with the `npm start` command. 48 | 9. Open a browser and navigate to the app running by default on port 3000. 49 | 10. Login using your Microsoft account, and allow the app to create pages in your OneNote notebooks. 50 | 51 | ### Version info 52 | 53 | This is the initial public release for this code sample. 54 | 55 | 56 | ### Learning more 57 | 58 | * Visit the [dev.onenote.com](http://dev.onenote.com) Dev Center 59 | * Contact us on [StackOverflow (tagged OneNote)](http://go.microsoft.com/fwlink/?LinkID=390182) 60 | * Follow us on [Twitter @onenotedev](http://www.twitter.com/onenotedev) 61 | * Read our [OneNote Developer blog](http://go.microsoft.com/fwlink/?LinkID=390183) 62 | * Explore the API using the [apigee.com interactive console](http://go.microsoft.com/fwlink/?LinkID=392871). 63 | Also, see the [short overview/tutorial](http://go.microsoft.com/fwlink/?LinkID=390179). 64 | * [API Reference](http://msdn.microsoft.com/en-us/library/office/dn575437.aspx) documentation 65 | * [Debugging / Troubleshooting](http://msdn.microsoft.com/EN-US/library/office/dn575430.aspx) 66 | * [Getting Started](http://go.microsoft.com/fwlink/?LinkID=331026) with the OneNote API 67 | 68 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 69 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var path = require('path'); 3 | var cookieParser = require('cookie-parser'); 4 | var bodyParser = require('body-parser'); 5 | 6 | var routes = require('./routes/index'); 7 | var callback = require('./routes/callback'); 8 | 9 | var app = express(); 10 | 11 | // view engine setup 12 | app.set('views', path.join(__dirname, 'views')); 13 | app.set('view engine', 'jade'); 14 | 15 | app.use(bodyParser()); 16 | app.use(cookieParser()); 17 | app.use(express.static(path.join(__dirname, 'public'))); 18 | 19 | app.use('/', routes); 20 | app.use('/callback', callback); 21 | 22 | // catch 404 and forwarding to error handler 23 | app.use(function (req, res, next) { 24 | var err = new Error('Not Found'); 25 | err.status = 404; 26 | next(err); 27 | }); 28 | 29 | /// error handler 30 | app.use(function (err, req, res, next) { 31 | res.status(err.status || 500); 32 | res.render('error', { 33 | message: err.message, 34 | error: { 35 | status: err.status, 36 | details: err.stack 37 | } 38 | }); 39 | }); 40 | 41 | module.exports = app; 42 | -------------------------------------------------------------------------------- /bin/www: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | var debug = require('debug')('onenote-nodejs-sample'); 3 | var app = require('../app'); 4 | 5 | app.set('port', process.env.PORT || 3000); 6 | 7 | var server = app.listen(app.get('port'), function () { 8 | debug('Express server listening on port ' + server.address().port); 9 | }); 10 | -------------------------------------------------------------------------------- /config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | //Live Connect API information 3 | clientId: '000000004011C945', 4 | clientSecret: 'U5ofKaQiol75VbohV4hh-2x8XZpcJoPf ', 5 | redirectUrl: 'http://onenoteapisamples.com:3000/callback' 6 | }; -------------------------------------------------------------------------------- /doc/login-sample.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |One of the ways to sign a user in with Node.js is to have a route handle the Live Connect Authentication callback. 11 | The route controller would take the authorization code supplied by the callback and request an access token with a REST client. 12 | The access token is sent back to the client in a cookie. 13 |
14 | 15 |The REST client:
16 |27 | var oauthAuthorizeUrl = 'https://login.live.com/oauth20_authorize.srf', 28 | oauthTokenUrl = 'https://login.live.com/oauth20_token.srf', 29 | clientId = config.clientId, 30 | clientSecret = config.clientSecret, 31 | redirectUrl = config.redirectUrl; 32 | 33 | // Helper function to create an encoded url query string from an object 34 | function toQueryString(obj) { 35 | var str = []; 36 | for (var p in obj) 37 | if (obj.hasOwnProperty(p)) { 38 | str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p])); 39 | } 40 | return str.join("&"); 41 | } 42 | 43 | /** 44 | * Obtain a Live Connect authorization endpoint URL based on configuration. 45 | * @returns {string} The authorization endpoint URL 46 | */ 47 | this.getAuthUrl = function () { 48 | var scopes = ['wl.signin', 'wl.basic', 'wl.offline_access', 'office.onenote_create']; 49 | var query = toQueryString({ 50 | 'client_id': clientId, 51 | 'scope': scopes.join(' '), 52 | 'redirect_uri': redirectUrl, 53 | 'display': 'page', 54 | 'locale': 'en', 55 | 'response_type': 'code' 56 | }); 57 | return oauthAuthorizeUrl + "?" + query; 58 | }; 59 | 60 | /* Live Connect API request sender */ 61 | function requestAccessToken(data, callback) { 62 | request.post({url: oauthTokenUrl, 63 | form: _.extend({ 64 | 'client_id': clientId, 65 | 'client_secret': clientSecret, 66 | 'redirect_uri': redirectUrl 67 | }, data)}, 68 | function (error, response, body) { 69 | if (error) { 70 | callback({}); 71 | } else { 72 | callback(JSON.parse(body)); 73 | } 74 | }); 75 | } 76 | 77 | /** 78 | * @callback accessTokenCallback 79 | * @param {object} Response data parsed from JSON API result 80 | */ 81 | 82 | /** 83 | * Request an access token by supplying an authorization code. 84 | * @param {string} authCode The authorization code 85 | * @param {accessTokenCallback} callback The callback with response data 86 | */ 87 | this.requestAccessTokenByAuthCode = function (authCode, callback) { 88 | requestAccessToken({'code': authCode, 'grant_type': 'authorization_code'}, callback); 89 | }; 90 | 91 | /** 92 | * Request an access token by supplying a refresh token. 93 | * @param {string} refreshToken The refresh token 94 | * @param {accessTokenCallback} callback The callback with response data 95 | */ 96 | this.requestAccessTokenByRefreshToken = function(refreshToken, callback) { 97 | requestAccessToken({'refresh_token': refreshToken, 'grant_type': 'refresh_token'}, callback); 98 | }; 99 |100 |
The callback route controller:
106 | (The liveConnect
variable is an instance of the REST client snippet above)
118 | /* GET Live Connect Auth callback. */ 119 | router.get('/', function (req, res) { 120 | // Get the auth code from the callback url query parameters 121 | var authCode = req.query['code']; 122 | 123 | if (authCode) { 124 | // Request an access token from the auth code 125 | liveConnect.requestAccessTokenByAuthCode(authCode, 126 | function (responseData) { 127 | var accessToken = responseData['access_token'], 128 | refreshToken = responseData['refresh_token'], 129 | expiresIn = responseData['expires_in']; 130 | if (accessToken && refreshToken && expiresIn) { 131 | // Save the access token on a session. Using cookies in this case: 132 | res.cookie('access_token', accessToken, { maxAge: expiresIn * 1000}); 133 | res.cookie('refresh_token', refreshToken); 134 | 135 | res.render('callback'); 136 | } else { 137 | // Handle an authentication error response 138 | res.render('error', { 139 | message: 'Invalid Live Connect Response', 140 | error: {details: JSON.stringify(responseData, null, 2)} 141 | }); 142 | } 143 | }); 144 | } else { 145 | // Handle an error passed from the callback query params 146 | var authError = req.query['error'], 147 | authErrorDescription = req.query['error_description']; 148 | res.render('error', { 149 | message: 'Live Connect Auth Error', 150 | error: {status: authError, details: authErrorDescription} 151 | }); 152 | } 153 | 154 | }); 155 |156 |
This snippet creates a basic OneNote page from HTML by placing the HTML directly in the HTTPS request body. 13 | It doesn't use the multi-part format. The snippet also adds the Content-Type and Authentication headers to the POST request.
14 | 15 |27 | /** 28 | * Create OneNote Page with Text 29 | * 30 | * @param {string} accessToken The access token 31 | * @param {createPageCallback} callback The callback with response data 32 | */ 33 | this.createPageWithSimpleText = function (accessToken, callback) { 34 | var htmlPayload = 35 | "<!DOCTYPE html>" + 36 | "<html>" + 37 | "<head>" + 38 | " <title>A page created from basic HTML-formatted text (Node.js Sample)</title>" + 39 | " <meta name=\"created\" value=\"" + dateTimeNowISO() + "\">" + 40 | "</head>" + 41 | "<body>" + 42 | " <p>This is a page that just contains some simple <i>formatted</i>" + 43 | " <b>text</b></p>" + 44 | "</body>" + 45 | "</html>"; 46 | 47 | createPage(accessToken, htmlPayload, callback, false); 48 | }; 49 | /** 50 | * @callback createPageCallback 51 | * @param {object} Error 52 | * @param {object} HTTP Response 53 | * @param {string} Response body 54 | */ 55 | 56 | var oneNotePagesApiUrl = 'https://www.onenote.com/api/v1.0/pages'; 57 | 58 | /* Pages API request builder & sender */ 59 | function createPage(accessToken, payload, callback, multipart) { 60 | var options = { 61 | url: oneNotePagesApiUrl, 62 | headers: {'Authorization': 'Bearer ' + accessToken} 63 | }; 64 | // Build simple request 65 | if (!multipart) { 66 | options.headers['Content-Type'] = 'text/html'; 67 | options.body = payload; 68 | } 69 | var r = request.post(options, callback); 70 | // Build multi-part request 71 | if (multipart) { 72 | var CRLF = '\r\n'; 73 | var form = r.form(); // FormData instance 74 | _.each(payload, function (partData, partId) { 75 | form.append(partId, partData.body, { 76 | // Use custom multi-part header 77 | header: CRLF + 78 | '--' + form.getBoundary() + CRLF + 79 | 'Content-Disposition: form-data; name=\"' + partId + '\"' + CRLF + 80 | 'Content-Type: ' + partData.contentType + CRLF + CRLF 81 | }); 82 | }); 83 | } 84 | } 85 | 86 | function dateTimeNowISO() { 87 | return new Date().toISOString(); 88 | } 89 |90 |
The following snippet builds a multi-part request that contains a "Presentation" part with HTML, 13 | and a second part with binary image data. 14 | In this example, a logo image is compiled into the app, but the technique is the same for other images.
15 | 16 |28 | /** 29 | * Create OneNote Page with Text and Images 30 | * 31 | * @param {string} accessToken The access token 32 | * @param {createPageCallback} callback The callback with response data 33 | */ 34 | this.createPageWithTextAndImage = function (accessToken, callback) { 35 | var htmlPayload = 36 | "<!DOCTYPE html>" + 37 | "<html>" + 38 | "<head>" + 39 | " <title>A page created containing an image (Node.js Sample)</title>" + 40 | " <meta name=\"created\" value=\"" + dateTimeNowISO() + "\">" + 41 | "</head>" + 42 | "<body>" + 43 | " <p>This is a page that just contains some simple <i>formatted</i>" + 44 | " <b>text</b> and an image</p>" + 45 | " <img src=\"name:ImageData\" width=\"426\" height=\"68\">" + 46 | "</body>" + 47 | "</html>"; 48 | 49 | createPage(accessToken, { 50 | 'Presentation': { 51 | body: htmlPayload, 52 | contentType: 'text/html' 53 | }, 54 | 'ImageData': { 55 | body: fs.readFileSync(path.normalize(__dirname + '/../image.jpg')), 56 | contentType: 'image/jpeg' 57 | } 58 | }, callback, true); 59 | }; 60 | /** 61 | * @callback createPageCallback 62 | * @param {object} Error 63 | * @param {object} HTTP Response 64 | * @param {string} Response body 65 | */ 66 | 67 | var oneNotePagesApiUrl = 'https://www.onenote.com/api/v1.0/pages'; 68 | 69 | /* Pages API request builder & sender */ 70 | function createPage(accessToken, payload, callback, multipart) { 71 | var options = { 72 | url: oneNotePagesApiUrl, 73 | headers: {'Authorization': 'Bearer ' + accessToken} 74 | }; 75 | // Build simple request 76 | if (!multipart) { 77 | options.headers['Content-Type'] = 'text/html'; 78 | options.body = payload; 79 | } 80 | var r = request.post(options, callback); 81 | // Build multi-part request 82 | if (multipart) { 83 | var CRLF = '\r\n'; 84 | var form = r.form(); // FormData instance 85 | _.each(payload, function (partData, partId) { 86 | form.append(partId, partData.body, { 87 | // Use custom multi-part header 88 | header: CRLF + 89 | '--' + form.getBoundary() + CRLF + 90 | 'Content-Disposition: form-data; name=\"' + partId + '\"' + CRLF + 91 | 'Content-Type: ' + partData.contentType + CRLF + CRLF 92 | }); 93 | }); 94 | } 95 | } 96 | 97 | function dateTimeNowISO() { 98 | return new Date().toISOString(); 99 | } 100 |101 |
The following snippet builds a multi-part request that contains a "Presentation" part with HTML, 13 | and a second part with binary data, that will be inserted into the page as an embedded file. 14 | In this example, a PDF document is compiled into the app, but the technique is the same for other files.
15 | 16 |28 | /** 29 | * Create OneNote Page with an Embedded File 30 | * 31 | * @param {string} accessToken The access token 32 | * @param {createPageCallback} callback The callback with response data 33 | */ 34 | this.createPageWithFile = function (accessToken, callback) { 35 | var htmlPayload = 36 | "<!DOCTYPE html>" + 37 | "<html>" + 38 | "<head>" + 39 | " <title>A page with a file on it (Node.js Sample)</title>" + 40 | " <meta name=\"created\" value=\"" + dateTimeNowISO() + "\"/>" + 41 | "</head>" + 42 | "<body>" + 43 | " <object data-attachment=\"PDF File.pdf\" data=\"name:EmbeddedFile\" type=\"application/pdf\"></object>" + 44 | " <img data-render-src=\"name:EmbeddedFile\" />" + 45 | "</body>" + 46 | "</html>"; 47 | 48 | createPage(accessToken, { 49 | 'Presentation': { 50 | body: htmlPayload, 51 | contentType: 'text/html' 52 | }, 53 | 'EmbeddedFile': { 54 | body: fs.readFileSync(path.normalize(__dirname + '/../file.pdf')), 55 | contentType: 'application/pdf' 56 | } 57 | }, callback, true); 58 | } 59 | /** 60 | * @callback createPageCallback 61 | * @param {object} Error 62 | * @param {object} HTTP Response 63 | * @param {string} Response body 64 | */ 65 | 66 | var oneNotePagesApiUrl = 'https://www.onenote.com/api/v1.0/pages'; 67 | 68 | /* Pages API request builder & sender */ 69 | function createPage(accessToken, payload, callback, multipart) { 70 | var options = { 71 | url: oneNotePagesApiUrl, 72 | headers: {'Authorization': 'Bearer ' + accessToken} 73 | }; 74 | // Build simple request 75 | if (!multipart) { 76 | options.headers['Content-Type'] = 'text/html'; 77 | options.body = payload; 78 | } 79 | var r = request.post(options, callback); 80 | // Build multi-part request 81 | if (multipart) { 82 | var CRLF = '\r\n'; 83 | var form = r.form(); // FormData instance 84 | _.each(payload, function (partData, partId) { 85 | form.append(partId, partData.body, { 86 | // Use custom multi-part header 87 | header: CRLF + 88 | '--' + form.getBoundary() + CRLF + 89 | 'Content-Disposition: form-data; name=\"' + partId + '\"' + CRLF + 90 | 'Content-Type: ' + partData.contentType + CRLF + CRLF 91 | }); 92 | }); 93 | } 94 | } 95 | 96 | function dateTimeNowISO() { 97 | return new Date().toISOString(); 98 | } 99 |100 |
The following code snippet builds a simple multi-part POST request with some HTML in a "Presentation" block. 13 | In that HTML is an <img> tag that shows how to specify an internet URL to the page rendering engine.
14 | 15 |26 | /** 27 | * Create OneNote Page with a Screenshot of a URL 28 | * 29 | * @param {string} accessToken The access token 30 | * @param {createPageCallback} callback The callback with response data 31 | */ 32 | this.createPageWithScreenshotFromUrl = function (accessToken, callback) { 33 | var htmlPayload = 34 | "<!DOCTYPE html>" + 35 | "<html>" + 36 | "<head>" + 37 | " <title>A page created with a URL snapshot on it (Node.js Sample)</title>" + 38 | " <meta name=\"created\" value=\"" + dateTimeNowISO() + "\"/>" + 39 | "</head>" + 40 | "<body>" + 41 | " <img data-render-src=\"http://www.onenote.com\" alt=\"An important web page\" />" + 42 | " Source URL: <a href=\"http://www.onenote.com\">http://www.onenote.com</a>" + 43 | "</body>" + 44 | "</html>"; 45 | 46 | createPage(accessToken, htmlPayload, callback, false); 47 | }; 48 | /** 49 | * @callback createPageCallback 50 | * @param {object} Error 51 | * @param {object} HTTP Response 52 | * @param {string} Response body 53 | */ 54 | 55 | var oneNotePagesApiUrl = 'https://www.onenote.com/api/v1.0/pages'; 56 | 57 | /* Pages API request builder & sender */ 58 | function createPage(accessToken, payload, callback, multipart) { 59 | var options = { 60 | url: oneNotePagesApiUrl, 61 | headers: {'Authorization': 'Bearer ' + accessToken} 62 | }; 63 | // Build simple request 64 | if (!multipart) { 65 | options.headers['Content-Type'] = 'text/html'; 66 | options.body = payload; 67 | } 68 | var r = request.post(options, callback); 69 | // Build multi-part request 70 | if (multipart) { 71 | var CRLF = '\r\n'; 72 | var form = r.form(); // FormData instance 73 | _.each(payload, function (partData, partId) { 74 | form.append(partId, partData.body, { 75 | // Use custom multi-part header 76 | header: CRLF + 77 | '--' + form.getBoundary() + CRLF + 78 | 'Content-Disposition: form-data; name=\"' + partId + '\"' + CRLF + 79 | 'Content-Type: ' + partData.contentType + CRLF + CRLF 80 | }); 81 | }); 82 | } 83 | } 84 | 85 | function dateTimeNowISO() { 86 | return new Date().toISOString(); 87 | } 88 |89 |
Created by Microsoft Corporation, 2014. Provided As-is without warranty. Trademarks mentioned here are the property of their owners.
11 |The following aspects of the API are covered in this sample. You can find additional documentation at the links below.
13 |Tools and Libraries you will need to download, install, and configure for your development environment.
24 | 32 | 33 |Accounts
34 | 35 |After you've setup your development tools, and checked the prerequisites listed above,....
42 | 43 |npm install
npm start
This is a page that just contains some simple formatted" + 64 | " text
" + 65 | "" + 66 | ""; 67 | 68 | createPage(accessToken, htmlPayload, callback, false); 69 | }; 70 | 71 | /** 72 | * Create OneNote Page with Text and Images 73 | * 74 | * @param {string} accessToken The access token 75 | * @param {createPageCallback} callback The callback with response data 76 | */ 77 | this.createPageWithTextAndImage = function (accessToken, callback) { 78 | var htmlPayload = 79 | "" + 80 | "" + 81 | "" + 82 | "This is a page that just contains some simple formatted" + 87 | " text and an image
" + 88 | "" + 131 | " Lorem ipsum dolor sit amet, consectetur adipiscing elit." + 132 | " Nullam vehicula magna quis mauris accumsan, nec imperdiet nisi tempus. " + 133 | " Suspendisse potenti. Duis vel nulla sit amet turpis venenatis elementum. " + 134 | " Cras laoreet quis nisi et sagittis. Donec euismod at tortor ut porta. " + 135 | " Duis libero urna, viverra idaliquam in, ornare sed orci. " + 136 | " Pellentesque condimentum gravida felis, sed pulvinar erat suscipit sit amet. Nulla id felis quis " + 137 | " sem blandit dapibus. " + 138 | " Utviverra auctor nisi ac egestas. " + 139 | " Quisque ac neque nec velit fringilla sagittis porttitor sit amet quam." + 140 | "
" + 141 | "" + 142 | ""; 143 | 144 | createPage(accessToken, { 145 | 'Presentation': { 146 | body: htmlPayload, 147 | contentType: 'text/html' 148 | }, 149 | 'HtmlForScreenshot': { 150 | body: htmlForScreenshot, 151 | contentType: 'text/html' 152 | } 153 | }, callback, true); 154 | }; 155 | 156 | /** 157 | * Create OneNote Page with a Screenshot of a URL 158 | * 159 | * @param {string} accessToken The access token 160 | * @param {createPageCallback} callback The callback with response data 161 | */ 162 | this.createPageWithScreenshotFromUrl = function (accessToken, callback) { 163 | var htmlPayload = 164 | "" + 165 | "" + 166 | "" + 167 | "