基于Microsoft Graph打造自己的Timeline应用
原文链接:https://github.com/chenxizhang/office365dev/blob/e9b5a59cb827841d36692cc4ec52c11d43062e04/docs/timeline.md
前言
前不久微软正式放出了Windows 10 春季更新(1803),其中有一个非常有特色的应用,就是Windows 10 新增了一个Timeline(时间线)的应用,这个应用可以让用户一目了然地看到最近一段时间所有在Windows中的活动,包括浏览过什么网页,打开过什么文档,设置过什么选项等。下图是一个示范的效果图:
请注意,这里看到的信息不是一个静态的图片,每一个卡片都是可以点击的,而且点击之后会通过调用对应的应用程序自动打开这些活动(恢复到之前的状态),就好像时光倒流了一样。
看起来很酷,不是吗?那么,这样一个应用到底是怎么实现的呢?我们如果也想实现类似的场景,有什么样的思路呢?答案在上周的Microsoft Build 大会上做了揭晓:其实Timeline是一个基于Microsoft Graph实现的应用,只不过他读取的数据,不仅限于Office 365的文档历史,还包括了Windows 10 上面的活动,这也是近年来一个重大的变化:微软已经把Office 365、Windows 10、EMS这三个产品合并为一个——Microsoft 365,将为最终用户提供最佳的体验,他们的能力也将统一通过Microsoft Graph向开发者提供服务。
原理解析
首先,从技术上说,要实现这个Timeline应用,用户需要允许相关的活动源将有关信息发送给Microsoft Graph。这里所谓的活动源
,可以是Office客户端,也可以是Windows 10的应用程序。微软一直致力于保护用户的隐私,所以这个Timeline的功能,默认是不开启的,只有用户在被明确告知上述行为并且选择接受的情况下,才会开始收集数据并进行展现。
其次,除了Windows 10自带的Timeline应用,其实只要几行代码,就能实现一个类似的时间线应用。那么问题就来了,这些应用之间的数据是不是隔离的呢?答案是肯定的,也就是说Windows 10这个Timeline应用只能读取到它在经用户同意的前提下收集的那部分活动数据,而我们自定义的应用也是如此。
最后,这里面还有一个有意思的概念。一个活动(Activity)可以对应一个或者多个历史记录(History Items)。历史纪录相当于是活动在某个时间点的快照。
据说这个技术,最早在内部有一个代码叫做“Project Rome”,现在合并到了Microsoft Graph中,并且已经在V1.0中提供。相关官方文档请参考 https://developer.microsoft.com/en-us/graph/docs/concepts/activity-feed-concept-overview .
创建Timeline应用
有了如上概念,我们就闲话少说,撸起袖子加油干吧。因为要访问Microsoft Graph,所以你就必须要注册一个AAD的应用程序。注册这样一个应用程序没有什么特别的,唯一要了解的是,要支持用户活动的读写,需要申请一个UserActivity.ReadWrite.CreatedByApp的委派权限(Delegated Permission),如下图所示
大家可以看到,这个权限并不需要管理员认可就能工作。
请注意,目前UserActivity.ReadWrite.CreatedByApp这个权限,仅在国际版的环境中可以用,而且必须在AAD 1.0的环境中实现。AAD 2.0还不支持,国内版(Gallatin)也暂时不支持。
如何发布Activity
Windows 10自带的Timeline其实是一个UWP应用,不过你可以用你最熟悉的方式来实现自定义的Timeline应用。但抛开这些具体的界面,我们可以快速了解一下如何创建和更新用户活动(Activity)。
创建或更新Activity的API,请参考 https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/projectrome_put_activity, 大体上说,这里的关键是用PUT方法操作,同时我们既可以单独创建Activity,也可以在创建Activity的时候同时创建History Item,后者也称为“Deep Insert”。
为了给大家直观演示效果,我这里简化一下步骤。我将采用官方的Microsoft Graph Explorer来模拟一个客户端,并且直接用REST API来进行操作。如果你对Microsoft Graph Explorer不太熟悉,你可能需要先阅读一下这篇文章。
正如上一节提到的,你需要确保授予了UserActivity.ReadWrite.CreatedByApp这个权限,请参考下图
我直接用官方给的例子,为当前用户新增一个网络文章浏览的活动,请注意下面的appActivityId
、activitySourceHost
、activationUrl
、visualElements
是必须的。这个例子的意思是指定义了用户这个活动是浏览了 http://www.contoso.com/article?id=12345
这个Url所指向的一篇文章。
{
"appActivityId": "/article?12345",
"activitySourceHost": "https://www.contoso.com",
"userTimezone": "Africa/Casablanca",
"appDisplayName": "Contoso, Ltd.",
"activationUrl": "http://www.contoso.com/article?id=12345",
"contentUrl": "http://www.contoso.com/article?id=12345",
"fallbackUrl": "http://www.contoso.com/article?id=12345",
"contentInfo": {
"@context": "http://schema.org",
"@type": "Article",
"author": "Jennifer Booth",
"name": "How to Tie a Reef Knot"
},
"visualElements": {
"attribution": {
"iconUrl": "http://www.contoso.com/icon",
"alternateText": "Contoso, Ltd.",
"addImageQuery": "false",
},
"description": "How to Tie a Reef Knot. A step-by-step visual guide to the art of nautical knot-tying.",
"backgroundColor": "#ff0000",
"displayText": "Contoso How-To: How to Tie a Reef Knot",
"content": {
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"body":
[{
"type": "TextBlock",
"text": "Contoso MainPage"
}]
}
}
}
在Microsoft Graph Explorer 中用PUT方法,将上述数据,发送到https://graph.microsoft.com/v1.0/me/activities/%2Farticle%3F12345
, 同时记得设置Content-Type为application/json
如果一切正常的话,你将收到一个回复,里面包含了在Microsoft Graph中创建的Activity的信息,这里会返回全局唯一的id
属性。
请注意,如果要更新,也是使用同样的一个命令。而如果要进行删除,则需要用 DELETE 方法,请参考 https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/projectrome_delete_activity。
如何查询Activity
有两个接口用来查询用户活动(Activity),分别是
- 获取用户活动(可以获取全部,也可以获取指定筛选条件的活动),如果需要同时包含历史信息,则需要添加查询参数 $expand=historyitems。 详细的API说明,请参考 https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/projectrome_get_activities 。
- 获取用户最近的活动。可以理解为上一种的简化版本,Microsoft Graph会查询最近的一个History Items,然后找到它们对应的活动条目。详细的API说明,请参考 https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/projectrome_get_recent_activities。
下面是一个简单的查询例子
结语
这一篇文章带领大家了解了Windows 10最新版本中Timeline这个功能的实现原理,并且用实例演示了如何使用Microsoft Graph来实现自定义的类似应用,我用Microsoft Graph Explorer做了演示,大家可以一目了然地看到接口的调用和返回值。
因为这个功能比较新,Microsoft Graph的SDK中,还没有完全包含这个功能,我还发现.NET SDK中存在一点小问题,已经跟产品团队反馈了。所以,如果你现在开始做实践,建议还使用REST API的方式。
基于Microsoft Graph打造自己的Timeline应用的更多相关文章
- 扩展Microsoft Graph数据结构(开放扩展)
作者:陈希章 发表于 2018年1月2日 前言 Microsoft Graph是一张拥有巨大价值的网络,它定义了包括Office 365在内的资源的实体及其关系,它的价值体现在,随着用户积累的数据越来 ...
- 基于Microsoft Azure、ASP.NET Core和Docker的博客系统
欢迎阅读daxnet的新博客:一个基于Microsoft Azure.ASP.NET Core和Docker的博客系统 2008年11月,我在博客园开通了个人帐号,并在博客园发表了自己的第一篇博客 ...
- 在无人值守程序(服务)中调用Microsoft Graph
作者:陈希章 发表于 2017年5月31日 什么是无人值守程序(服务) 我在此前用了几篇文章分别介绍了在桌面应用程序(控制台),Web应用程序(ASP.NET MVC),以及PowerSehll脚本中 ...
- 在PowerShell脚本中集成Microsoft Graph
作者:陈希章 发表于2017年4月23日 我旗帜鲜明地表态,我很喜欢PowerShell,相比较于此前的Cmd Shell,它有一些重大的创新,例如基于.NET的类型系统,以及管道.模块的概念等等.那 ...
- 扩展Microsoft Graph数据结构 - 架构扩展
前言 此前我有一篇 文章 讲解了Microsoft Graph的一种数据扩展技术-- 开发扩展(Open Extensions),它可以实现在支持的对象(例如用户,组等)上面附加任意的数据.但开放扩展 ...
- 基于windows 10打造的kali工具集
基于windows 10打造的kali工具集.iso,适合于习惯使用windows的安全从业者.if you like it,please touch star! 作为安全从业主,Kali都是必备工具 ...
- win10 uwp 使用 Microsoft.Graph 发送邮件
在 2018 年 10 月 13 号参加了 张队长 的 Office 365 训练营 学习如何开发 Office 365 插件和 OAuth 2.0 开发,于是我就使用 UWP 尝试使用 Micros ...
- 如何使用 Azure Active Directory 认证和 Microsoft Graph 构建 Blazor Web 应用
如何使用 Azure Active Directory 认证和 Microsoft Graph 构建 Blazor Web 应用 英文原文:https://developer.microsoft.co ...
- 跨平台应用集成(在ASP.NET Core MVC 应用程序中集成 Microsoft Graph)
作者:陈希章 发表于 2017年6月25日 谈一谈.NET 的跨平台 终于要写到这一篇了.跨平台的支持可以说是 Office 365 平台在设计伊始就考虑的目标.我在前面的文章已经提到过了,Micro ...
随机推荐
- How to Enable Trace or Debug for APIs executed as SQL Script Outside of the Applications ?
In this Document Goal Solution 1: How do you enable trace for an API when executed from a SQL ...
- (NO.00001)iOS游戏SpeedBoy Lite成形记(十一)
之前的10篇内容主要实现了选手从起点移动至终点的动作,比较随机的模拟了选手的速度变化,另外完成了选手到达终点时该做的事情. 接下来的几篇中我们进一步完善SpeedBoy Lite项目,使它真正成为一个 ...
- linux知识汇总
1. 利用Ctrl+Alt+F1到Ctrl+Alt+F6在6个虚拟控制台之间切换,利用Ctrl+Alt+F7切换回图形界面. 2. 使用who命令来判断谁在系统上及其登录方式.id命令 ...
- python 2.4 的字符串转时间(日期减法取间隔时间)
python 2.4中datetime有strftime方法,而无strptime方法.不能对字符串进行格式转换.比如不能将"2013-10-22"转化为日期. 2.4中字符串转日 ...
- android Native堆
Android 应用开发大家都知道可以通过DDMS来查看应用程序进程占用的内存大小:然而Native 内存并不能在虚拟堆上看到:Android系统基于Linux,这样的话其具备Linux的大多数特性: ...
- 苹果新的编程语言 Swift 语言进阶(十)--类的继承
一.类的继承 类能够从其它类继承方法.属性以及其它特性,当一个类从另外的类继承时,继承的类称为子类,它继承的类称为超类.在Swift中,继承是类区别与其它类型(结构.枚举)的基础行为. 1.1 .类的 ...
- HBase写被block的分析
一个线上集群出现莫名奇妙不能写入数据的bug,log中不断打印如下信息: 引用 2011-11-09 07:35:45,911 INFO org.apache.hadoop.hbase.regions ...
- LeetCode(33)-Pascal's Triangle II
题目: Given an index k, return the kth row of the Pascal's triangle. For example, given k = 3, Return ...
- Oracle :%TYPE 和 %ROWTYPE
1. 使用%TYPE 在许多情况下,PL/SQL变量可以用来存储在数据库表中的数据.在这种情况下,变量应该拥有与表列相同的类型.例如,students表的first_name列的类型为VARCHAR2 ...
- C# / VB.NET合并PDF指定页
在前面的文章中,我们已经知道如何合并.拆分多个PDF文件,在这篇文章中的合并.拆分PDF文档主要是以方便文档管理的目的来操作文档,在文档查阅.管理及存储上很方便实用.但是我们如果想要合并多个文档中的部 ...