在本教程中,你将学习如何使用 O365 Outlook 服务和 Ionic 框架来创建邮件、日历和联系人客户端。 此应用允许用户通过 O365 Outlook 服务 API 访问他们的邮件、日历和联系人。 该示例使用 JavaScript 代码,但你也可以使用 TypeScript 来编写 Cordova 应用。
在本课程中,你将遵循以下步骤:
创建项目
将 Ionic 框架添加到你的项目
将 NProgress 添加到你的项目
将 O365 服务添加到你的应用
设置 O365 邮件、日历和联系人原则的权限,以授予对应用的适当的访问权限
使用 Ionic 控件创建应用文件夹结构、UI 路由和布局
使用 AngularJS 工厂获取访问令牌和 Outlook 服务客户端
使用 O365 API 提取 Outlook 服务数据:
对于邮件应用,标记为重要的邮件、未读邮件和全部邮件
对于日历应用,今天的会议(事件开始日期等于今天)、明天的会议(事件开始日期等于明天)和开始日期大于或等于今天的所有事件
对于联系人应用,所有联系人
使用 O365 API 创建和删除数据:
删除邮件、日历事件
创建新的日历事件、联系人
运行应用
下面的屏幕截图显示完成时正在运行的日历应用。
下面的屏幕截图显示完成时正在运行的邮件应用。
下面的屏幕截图显示完成时正在运行的联系人应用。
先决条件
在创建新项目前,请确保满足了所有系统要求,并针对 Visual Studio 安装了 Visual Studio Tools for Apache Cordova 的扩展。 有关详细信息,请参阅安装 Visual Studio Tools for Apache Cordova
创建项目
通过以下方式在 Visual Studio 中创建一个新的 Cordova 项目,依次选择“文件”、“新建项目”、“JavaScript”、“Apache Cordova 应用”和“空白应用”模板。
将 Ionic 框架添加到你的项目
添加 Ionic 框架
从 Ionic 框架网站中选择“下载 beta 版本”。
解压缩 zip 文件。
在 Visual Studio 中,在解决方案资源管理器中的 Cordova 项目下创建名为 lib 的新文件夹,然后在 lib 文件夹下复制解压缩的内容。
更新脚本引用。
在 index.html 中,先在 <head> 元素中添加 Cordova 和 platformOverrides 脚本引用,然后添加以下 Ionic 引用。
<script src="lib/ionic/js/ionic.bundle.min.js"></script>
在 index.html 中,添加以下 ionic CSS 引用。
<link href="lib/ionic/css/ionic.min.css" rel="stylesheet" />
将 NProgress 添加到你的项目
NProgress 将用于显示从 O365 中提取邮件、日历和联系人时的进度栏。
将 NProgress 添加到你的项目
从 NProgress 网站中,选择“下载”。
解压缩 zip 文件。
在解决方案资源管理器中的 lib 文件夹下创建名为 nprogress 的文件夹,并将 nprogress.js 复制到该文件夹下。
在 css 文件夹下复制 nprogress.css
在 index.html 中,将以下 NProgress 引用添加到 <head> 元素中。
<link href="css/nprogress.css" rel="stylesheet" /> <script src="lib/nprogress/nprogress.js"></script>
将 O365 服务添加到你的应用
注册 Office 365 开发人员网站并按设置 Office 365 开发环境中的以下说明设置开发人员网站的 Azure Active Directory 访问权限
设置开发人员网站后,使用 Visual Studio 中的服务管理器按照以下步骤添加和配置 Office 365 API。
添加和配置 Office 365 API
从 Visual Studio 库下载并安装 Office 365 API 工具。
从项目节点的快捷菜单中选择“添加”,然后选择“连接的服务”。
在“服务管理器”对话框的顶部,选择“Office 365”链接,然后选择注册应用。
使用Office 365 开发人员组织的租户管理员帐户登录。
设置 O365 邮件、日历和联系人原则的权限,以授予对应用的访问权限
登录到 O365 帐户之后,你将在你的租户帐户下看到 O365 服务(如邮件、日历、联系人和文件)的列表。 选择你想要在应用中使用的服务,并设置你想要应用访问的权限,如下文对每个应用进行的指定所述。
邮件应用
在右侧窗格中选择“邮件”并单击“权限...”链接。 然后,选择读取和写入用户的邮件,因为应用将需要执行读取和删除邮件操作。 同样,如果你希望应用发送邮件,则选择邮件作为用户选项。
日历应用
在右侧窗格中选择“日历”并单击“权限...”链接,然后选择“具有对用户日历的完全访问权限”。 同样,如果你只想为应用授予读取权限,则选择“读取用户的日历”。
联系人应用
在右侧窗格中选择“联系人”并单击“权限...”链接,然后选择“具有对用户联系人的完全访问权限”。 同样,如果你只想为应用授予读取权限,则选择“读取用户的联系人”。
应用更改并更新引用
应用更改并更新引用
单击“应用”和“确定”以设置权限,并将 O365 API 添加到你的项目。
服务管理器将服务文件夹添加到你的项目。
在 index.html 中,将以下 O365 引用添加到 <head> 元素中。
<script src="services/office365/scripts/o365loader.js"></script> <script src="services/office365/settings/settings.js"></script>
使用 Ionic 控件和导航创建应用文件夹结构、UI 路由和布局
按照下列步骤构建应用 UI 和 JavaScript 代码。
在项目根节点下创建一个名为“应用”的文件夹。 该应用文件夹将包含特定于应用的文件。 每个提取数据并将数据绑定到 UI 的 UI 组件都将有一个相应的控制器(遵循代码置于 UI 之后的模式)。 例如,mail-list.html 将显示一个列表控件来显示用户的邮件,而 mail-list-ctrl.js 将包含使用 O365 API 来提取用户的邮件的代码。
以下是一些有关项目中的文件夹和文件的详细信息。
“身份验证”文件夹中包含用于登录和注销的 UI 和代码。
“布局”文件夹包含用于显示应用内容和导航的 UI(如 ion-pane、ion-side-menus 和 ion-nav-bar)以及用于绑定用户名的代码。
app.js 包含的 UI 路由可导航到不同的页面。
service-o365.js 包含用于获取访问令牌、创建 Outlook 服务客户端对象、注销和获取用户名的实用工具函数。 这作为 AngularJS 工厂实现,因此这些函数可以跨不同的页作为实用工具函数公开。
使用 AngularJS 路由导航到不同的页面。 例如,以下是邮件应用的路由:
// Layout page
.state('app', {
abstract: true,
url: "/app",
templateUrl: "app/layout/layout.html"
})
// Sign-in page
.state('sign-in', {
url: "/sign-in",
templateUrl: "app/auth/sign-in.html"
})
// Sign-out page
.state('app.sign-out', {
url: "/sign-out",
views: {
'mainContent': {
templateUrl: "app/auth/sign-out.html"
}
}
})
// Mail list page
.state('app.mail', {
url: "/mail",
views: {
'mainContent': {
templateUrl: "app/mail/mail-tabs.html"
}
}
})
// Mail list containing mails flagged as important
.state('app.mail.imp', {
url: "/imp/id:important",
views: {
"tab-imp-mail": {
templateUrl: "app/mail/mail-list.html"
}
}
})
// Mail detail page
.state('app.mail-detail', {
url: "/mail/:id",
views: {
'mainContent': {
templateUrl: "app/mail/mail-detail.html"
}
}
})
// Unread mail list page
.state('app.mail.unread', {
url: "/unread/id:unread",
views: {
"tab-unread-mail": {
templateUrl: "app/mail/mail-list.html"
}
}
})
// All mail list page
.state('app.mail.all', {
url: "/all/id:all",
views: {
"tab-all-mail": {
templateUrl: "app/mail/mail-list.html"
}
}
});
// Navigate to sign-in page when app starts.
$urlRouterProvider.otherwise('sign-in');
对于应用布局(菜单、导航栏),使用 Ionic 侧面菜单和窗格。
<ion-side-menus ng-controller="layoutCtrl as vm">
<ion-pane ion-side-menu-content>
<ion-nav-bar class="bar-positive">
<ion-nav-back-button class="button-clear icon ion-ios7-arrow-back"></ion-nav-back-button>
<button menu-toggle="left" class="button button-icon icon ion-navicon"></button>
</ion-nav-bar>
<ion-nav-view name="mainContent" animation="slide-left-right"></ion-nav-view>
</ion-pane>
<ion-side-menu side="left">
<header class="bar bar-header bar-positive">
<h1 class="title">{{vm.userName}}</h1>
</header>
<ion-content class="has-header">
<ion-list>
<ion-item nav-clear menu-close ui-sref="app.sign-out">Sign-out</ion-item>
</ion-list>
</ion-side-menu>
</ion-side-menus>
使用 Ionic 选项卡在单独的选项卡中显示不同的内容。 例如,使用下面 Ionic 控件来创建邮件选项卡页,以在不同的选项卡下显示重要邮件、未读邮件和所有邮件。
<ion-view>
<ion-tabs class="tabs-positive tabs-icon-top">
<ion-tab title="Imp" icon="ion-star" ui-sref="app.mail.imp">
<ion-nav-view name="tab-imp-mail"></ion-nav-view>
</ion-tab>
<ion-tab title="Unread" icon="ion-ios7-email-outline" ui-sref="app.mail.unread">
<ion-nav-view name="tab-unread-mail"></ion-nav-view>
</ion-tab>
<ion-tab title="All" icon="ion-email" ui-sref="app.mail.all">
<ion-nav-view name="tab-all-mail"></ion-nav-view>
</ion-tab>
</ion-tabs>
</ion-view>
下图显示邮件选项卡页。
使用 AngularJS 工厂获取访问令牌和 Outlook 服务客户端
创建 AngularJS 工厂来公开 O365 API,以便获取访问令牌、创建 Outlook 服务客户端、注销,并执行应用中的不同控制器使用的其他实用工具函数。
以下是用于获取访问令牌的代码。
var authContext = new O365Auth.Context();
authContext.getIdToken("https://outlook.office365.com/")
.then((function (token) {
// Get auth token
authtoken = token;
// Get user name from token object.
userName = token.givenName + " " + token.familyName;
}), function (error) {
// Log sign-in error message.
console.log('Failed to login. Error = ' + error.message);
});
以下是用于创建 Outlook 服务客户端对象的代码。
var outlookClient = new Microsoft.OutlookServices.Client('https://outlook.office365.com/api/v1.0', authtoken.getAccessTokenFn('https://outlook.office365.com'));
以下是用于公开 O365 API 的完整 AngularJS 工厂代码。
(function () {
'use strict';
angular.module('app365').factory('app365api', [app365api]);
function app365api() {
var authContext;
var authtoken;
var outlookClient;
var userName;
// Login to O365
function login(callback) {
if (!authContext) {
authContext = new O365Auth.Context();
}
authContext.getIdToken("https://outlook.office365.com/")
.then((function (token) {
// Get auth token
authtoken = token;
// Get user name from token object.
userName = token.givenName + " " + token.familyName;
// Create Outlook client object.
outlookClient = new Microsoft.OutlookServices.Client('https://outlook.office365.com/api/v1.0', authtoken.getAccessTokenFn('https://outlook.office365.com'));
// Callback without parameter to indicate successful sign-in.
callback();
}), function (error) {
// Log sign-in error message.
console.log('Failed to login. Error = ' + error.message);
callback(error.message);
});
};
// Logout
function logout() {
if (!authContext) {
authContext = new O365Auth.Context();
}
authContext.logOut();
};
// Get signed-in user name.
function getUserName() {
return userName;
};
return {
login: login,
logout: logout,
getUserName: getUserName,
exchangeClientObj: function () { return outlookClient; }
};
};
})();
使用 Outlook 客户端对象来访问 O365 服务(如邮件、日历和联系人)
可以使用 Outlook 客户端对象来对邮件、日历和联系人执行读取和写入操作。
使用 Outlook 客户端对象读取邮件、日历和联系人
下面的代码读取标记为重要的所有邮件。
// Get all mails flagged as important.
function getImpMails() {
NProgress.start();
// Filter to fetch all important mails received after 2000-10-20
var filterQuery = "Importance eq 'High' and DateTimeReceived gt 2000-10-20";
outlookClient.me.folders.getFolder("Inbox").fetch()
.then(function (folder) {
// Fetch all important mails sorted by DateTimeReceived.
folder.messages.getMessages().filter(filterQuery).orderBy('Importance,DateTimeReceived desc').fetch()
.then(function (mails) {
// Get current page. Use getNextPage() to fetch next set of mails.
vm.mails = mails.currentPage;
$scope.$apply();
NProgress.done();
}, function (error) {
console.log("Error encountered while fetching mails. Error: " + error.message);
});
}, function (error) {
console.log("Error encountered while fetching inbox folder. Error: " + error.message);
});
};
下面的代码读取开始日期等于今天的所有事件。
var filterQuery = 'start gt ' + today.toISOString() + ' and start lt ' + tomorrow.toISOString();
NProgress.start();
// Get events with filter.
outlookClient.me.calendar.events.getEvents().filter(filterQuery).fetch()
.then(function (events) {
// Get current page. Use getNextPage() to fetch next set of events.
vm.events = events.currentPage;
$scope.$apply();
NProgress.done();
});
下面的代码读取所有联系人。
function getContacts() {
NProgress.start();
// Fetch all the contacts.
outlookClient.me.contacts.getContacts().fetch()
.then(function (contacts) {
// Get the current page. Use getNextPage() to fetch next set of contacts.
vm.contacts = contacts.currentPage;
$scope.$apply();
NProgress.done();
});
};
使用 Outlook 客户端对象删除邮件和日历事件
可以使用 Outlook 客户端对象删除邮件。 若要删除邮件,请使用邮件 ID 获取你想要删除的邮件,然后在邮件对象上调用 delete() 以删除特定邮件。
备注
delete() 会永久删除邮件。若要将邮件移动到“已删除的项”,请改用 move()。
以下是用于删除邮件的代码。
// Fetch the mail with specified mail id. outlookClient.me.folders.getFolder("Inbox").messages.getMessage(mail.id).fetch()
.then(function (mail) {
// Delete the mail.
mail.delete()
.then((function (response) {
// mail deleted successfully.
}), function (error) {
// Log the error message when error is encountered while deleting the mail.
console.log('fail to delete mail. Error = ' + error.message);
});
以下是用于删除事件的代码。
// Fetch event with specified event id.
outlookClient.me.calendar.events.getEvent(event.id).fetch()
.then(function (event) {
// Delete event.
event.delete()
.then((function (response) {
// Refresh event list.
}).bind(this), function (reason) {
// Log delete event error.
console.log('Fail to delete event. Error = ' + reason.message);
});
使用 Outlook 客户端对象创建新的联系人和日历事件
可以使用 Outlook 客户端对象创建新的联系人和日历事件,以及发送邮件。
以下是用于添加新日历事件的代码。
// Event body content
var eventBody = new Microsoft.OutlookServices.ItemBody();
eventBody.contentType = Microsoft.OutlookServices.BodyType.HTML;
eventBody.content = $scope.newEvent.body;
// Event attendee.
var attendee = new Microsoft.OutlookServices.Attendee();
// Attendee email address.
var emailAddress = new Microsoft.OutlookServices.EmailAddress();
emailAddress.address = $scope.newEvent.toRecipients;
attendee.emailAddress = emailAddress;
// Event object.
var event = new Microsoft.OutlookServices.Event();
// Event start date.
event.start = new Date($scope.newEvent.start).toISOString();
// Event end date time
event.end = new Date($scope.newEvent.end).toISOString();
// Event subject.
event.subject = $scope.newEvent.subject;
// Event body.
event.body = eventBody;
// Add event attendee.
event.attendees.push(attendee);
// Event ___location.
event.___location = new Microsoft.OutlookServices.Location();
event.___location.displayName = 'Sample Location';
// Add event
outlookClient.me.calendar.events.addEvent(event)
.then((function (response) {
// New event created successfully.
})
.bind(this), function (reason) {
// Log the error message encountered while adding the event.
console.log('Fail to add event. Error = ' + reason.message);
});
以下是用于添加新联系人的代码。
// Contact object
var contact = new Microsoft.OutlookServices.Contact();
// First and last name
contact.givenName = $scope.newContact.firstname;
contact.surname = $scope.newContact.lastname;
// Mobile phone
contact.mobilePhone1 = $scope.newContact.phone;
// Email address
var emailAddress = new Microsoft.OutlookServices.EmailAddress();
emailAddress.address = $scope.newContact.email;
contact.emailAddresses.push(emailAddress);
// Add Contact
outlookClient.me.contacts.addContact(contact)
.then((function (response) {
// Contact added successfully.
})
.bind(this), function (reason) {
// Log the error message when add contact fails.
console.log('Fail to add contact. Error = ' + reason.message);
});
运行应用
选择“Android”作为 OS,并将其部署到 Android 仿真器或 Android 设备。
备注
O365 身份验证当前不支持 Ripple。
按 F5 运行应用。
有关跨多个平台运行 Cordova 应用的详细信息,请参阅部署和运行使用 Visual Studio Tools for Apache Cordova 生成的应用。
试一试
可在 Github 上下载完整的应用程序。 请下载并试用示例应用,并让我们知道你的想法。 我们想知道你对于 Visual Studio 中的新 O365 API 和 Cordova 工具支持的意见!
应用 |
描述 |
---|---|
使用 Ionic 创建的示例 Cordova 应用演示如何使用 O365 日历 API 来读取、筛选、删除和添加事件。 它将事件分为三组:(1) 今天的事件、(2) 明天的事件和 (3) 开始日期 > = 今天的所有事件。 |
|
使用 Ionic 创建的示例 Cordova 应用演示如何使用 O365 邮件 API 来读取、筛选和删除邮件。 它将邮件分为三组:(1) 重要邮件、(2) 未读邮件和 (3) 所有邮件。 |
|
使用 Ionic 创建的示例 Cordova 应用演示如何使用 O365 联系人 API 来读取和添加联系人。 |