EWS Managed api in JavaScript
npm install ews-javascript-apiews-javascript-api
==================
ews-js-api-browser for more detail
async/await and move to @ewsjs/ namespace
@ewsjs/xhr to wrap all exports from @ewsjs/ews
0.9.0
OAuthCredentials
@ewsjs/xhr version to 3.1.0 (dependency audit update)
ts
import { ExchangeService, OAuthCredentials, ExchangeVersion } from "ews-javascript-api";
import { EwsOAuthHelper } from "ews-javascript-api/lib/EwsOAuthHelper";
const oAuthHelper = new EwsOAuthHelper({ clientId: '', clientSecret: '', tenantId: '' });
const token = await oAuthHelper.getAppAccessToken();
const ews = new ExchangeService(ExchangeVersion.);
ews.Credentials =new OAuthCredentials(token.accessToken);
await ews.();
`
> you will still need to update expired access token by calling oAuthHelper.getAppAccessToken(), you can safely run this when you want to use ews as this can return cached token which is not expired
Whats new v0.14.0
* Updated implementation of @ewsjs/ntlm-client to continue support ntlm with node 18+ (dependency of @ewsjs/xhr)
* This fixes latest support for ntlm with node 18/20+
* This also fixes security warning of new Buffer(...) in the underlying library
Whats new v0.13.0 BREAKING CHANGES
* Security update: removed fetch and bluebird dependency
* removed XHRDefault and ConfigurationApi.ConfigurePromise exported methods
* Exported XHRApi from @ewsjs/xhr to make it easier to use
* Using default implementation of XhrApi from @ewsjs/xhr instead of using fetch
Whats new v0.12.0
* fixed WellKnownFolderNames to be StringPropertyDefinition type instead of Generic which microsoft has changed long back. Part of this was fixed by #414 (thanks @klinki)
* fixes #416 and also cleans up other typing issues
* Security update: updated all dependency to latest version.
Whats new v0.11.0
* BREAKING dependencies upgraded to latest version of commonjs module (still avoiding pure esm modules). The code is now compiled to es6 target, must use nodejs version >= 10
* Security update: updated all dependency to latest version.
Whats new v0.10.0
* new/fix: #324 Autodiscover is back again, improved and supports DNS fallback using Autodiscover SRV records
* new: #320 Allow access to HttpResponseHeaders, you can use to get fresh header from last call to ews service.
* you can also add a delegate (callback) for which is called after each call to service and when headers are returned.
* Breaking Changes: is now Disctionary instance, compatible with c# disctionary. you can no longer do service.HttpHeaders[. do this instead service.HttpHeaders.Add("header", "value");
* fix: #322 you can now delete tasks properly
See older change in CHANGELOG.md
===========================================================================================
EWS managed API for TypeScript/JavaScript - code ported from OfficeDev/ews-managed-api. availbale for nodejs, browser and mobile devices (cordova).
Pluggable XHRApi adapter to replace client (browser) based XHR call with server brokered call (example coming soon). Example Ruby on rails, PHP or any server side framework where c# or nodejs is not available
Works with Office 365/Exchange Online and on-premises Exchange (2007 - 2016)
Authentication
* Basic - inbuilt
* OAuth - inbuilt (see https://stackoverflow.com/a/43785262/5884960 for more details on how to use.)
* NTLM and NTLMv2 - using @ewsjs/xhr
* Cookies/FBA Authentication with TMG/ISA - using @ewsjs/xhr
> use SSL for basic authentication
NTLM and Cookies Authentication works with nodejs only
> NTLM issue with invalid tagName gibrish character is due to gzip encoding, see #334.
>
> Solution use gzip: true in XhrApi({ gzip: true }) constructor options of @ewsjs/xhr.
Modules
* commonjs module for NodeJs
AMD module for other scenarios (not documented yet)
~~All http call is wrapped in promise using default BlueBird promise. You can also interchange compatible promise api.~~
Code sample from EWS Managed API 2.1. should work with little modificaion to Promise format
async/await latest nodejs
You can also leverage new async/await feature of nodejs (>7.0.6) or in TypeScript transpilation with es5/es6 code.
Documentation
Api document generated using TypeDoc and is hosted at ews-javascript-api.github.io/api. ** outdated
Check Wiki for more details
keep track of what is coming in backlog, keep eye on milestones when I start working on it
Getting Started
install
`shell
[sudo] npm install ews-javascript-api
`
use
`javascript
//classic Javascript style
var ews = require('ews-javascript-api');
var exch = new ews.ExchangeService(ews.ExchangeVersion.Exchange2013);
//ES6 TypeScript style
import {ExchangeService, AutodiscoverService, Folder, Item, ExchangeVersion} from "ews-javascript-api";
var exch = new ExchangeService(ExchangeVersion.Exchange2013);
`
Autodiscover user settings ( Working again as of 0.10 )
`javascript
//import ews module
var ews = require('ews-javascript-api');
//create AutodiscoverService object
var autod = new ews.AutodiscoverService(new ews.Uri("https://autodiscover-s.outlook.com/autodiscover/autodiscover.svc"), ews.ExchangeVersion.Exchange2010);
//you can omit url and it will autodiscover the url, version helps throw error on client side for unsupported operations.example - //var autod = new ews.AutodiscoverService(ews.ExchangeVersion.Exchange2010);
//set credential for service
autod.Credentials = new ews.WebCredentials("userName", "password");
//create array to include list of desired settings
var settings = [
ews.UserSettingName.InternalEwsUrl,
ews.UserSettingName.ExternalEwsUrl,
ews.UserSettingName.UserDisplayName,
ews.UserSettingName.UserDN,
ews.UserSettingName.EwsPartnerUrl,
ews.UserSettingName.DocumentSharingLocations,
ews.UserSettingName.MailboxDN,
ews.UserSettingName.ActiveDirectoryServer,
ews.UserSettingName.CasVersion,
ews.UserSettingName.ExternalWebClientUrls,
ews.UserSettingName.ExternalImap4Connections,
ews.UserSettingName.AlternateMailboxes
];
//get the setting
autod.GetUserSettings(["email1@domain.com", "email2@domain.com"], settings)
.then(function (response) {
//do what you want with user settings
var tabcount = 0;
var tabs = function () { return ews.StringHelper.Repeat("\t", tabcount); };
console.log(autod.Url.ToString());
//uncoment next line to see full response from autodiscover, you will need to add var util = require('util');
//console.log(util.inspect(response, { showHidden: false, depth: null, colors: true }));
for (var _i = 0, _a = response.Responses; _i < _a.length; _i++) {
var resp = _a[_i];
console.log(ews.StringHelper.Format("{0}settings for email: {1}", tabs(), resp.SmtpAddress));
tabcount++;
for (var setting in resp.Settings) {
console.log(ews.StringHelper.Format("{0}{1} = {2}", tabs(), ews.UserSettingName[setting], resp.Settings[setting]));
}
tabcount--;
}
}, function (e) {
//log errors or do something with errors
});
`
Example EWS operations
Example of user availability
`javascript
var ews = require('ews-javascript-api');
//create ExchangeService object
var exch = new ews.ExchangeService(ews.ExchangeVersion.Exchange2013);
exch.Credentials = new ews.WebCredentials("userName", "password");
//set ews endpoint url to use
exch.Url = new ews.Uri("https://outlook.office365.com/Ews/Exchange.asmx"); // you can also use exch.AutodiscoverUrl
var attendee =[ new ews.AttendeeInfo("email1@domain.com"), new ews.AttendeeInfo("email2@domain.com")];
//create timewindow object o request avaiability suggestions for next 48 hours, DateTime and TimeSpan object is created to mimic portion of .net datetime/timespan object using momentjs
var timeWindow = new ews.TimeWindow(ews.DateTime.Now, ews.DateTime.Now.AddDays(2));
exch.GetUserAvailability(attendee, timeWindow, ews.AvailabilityData.FreeBusyAndSuggestions)
.then(function (availabilityResponse) {
//do what you want with user availability
}, function (errors) {
//log errors or do something with errors
});
`
Use with React Native
there is some issues with how react native exposes native browser methods, here are changes needs to be done to us ews-js-api-browser with react native.
Add following lines to some place before requiring ews-js-api-browser. you need to use @xmldom/xmldom and base-64 packages.
`js
if (!global.DOMParser) {
global.DOMParser = require('@xmldom/xmldom').DOMParser;
}
if (!global.atob || !global.btoa) {
global.atob = require('base-64').decode;
global.btoa = require('base-64').encode;
}
``