Morning Girl

Web API, Windows, C#, .NET, Dynamics 365/CRM etc..

Dynamics 365 / CDS ActivityLog(活動ログ)を触ってみる:June 2019 Monthly Update

Dynamics 365 Monthly Update-June で Activity Log(活動ログ)というものが追加されていました!

結構面白い機能なので、記事として残しておきたいと思います。

community.dynamics.com

ActivityLog(活動ログ)とは?

Dynamics 365 for Customer Engagement の操作ログを取得できると思っておけばOKです。

docs.microsoft.com

データの作成・更新・削除はもちろんのこと、レコードの表示、一覧の表示、ExcelExportやエンティティのカスタマイズ、フィールドの追加、カスタマイズの公開といった情報まで取得することが可能です。

Plugin開発を行ったことがある方ならわかりやすいかもですが、Microsoft.Crm.Sdk.Messages に載っているほとんどのものが取得できます。

Microsoft.Crm.Sdk.Messages Namespace | Microsoft Docs

現在取得できない Messageは以下のリンクで確認できます。

https://docs.microsoft.com/ja-jp/dynamics365/customer-engagement/admin/enable-use-comprehensive-auditing#whats-logged

WhoAmIや、QueryExpressionToFetchXmlといった並びを見ると、Utility系のMessageとかかなと見えますね。

  • WhoAmI
  • RetrieveFilteredForms
  • TriggerServiceEndpointCheck
  • QueryExpressionToFetchXml
  • FetchXmlToQueryExpression
  • FireNotificationEvent
  • RetrieveMetadataChanges
  • RetrieveEntityChanges
  • RetrieveProvisionedLanguagePackVersion
  • RetrieveInstalledLanguagePackVersion
  • RetrieveProvisionedLanguages
  • RetrieveAvailableLanguages
  • RetrieveDeprovisionedLanguages
  • RetrieveInstalledLanguagePacks
  • GetAllTimeZonesWithDisplayName
  • GetTimeZoneCodeByLocalizedName
  • IsReportingDataConnectorInstalled
  • LocalTimeFromUtcTime
  • IsBackOfficeInstalled
  • FormatAddress
  • IsSupportUserRole
  • IsComponentCustomizable
  • ConfigureReportingDataConnector
  • CheckClientCompatibility
  • RetrieveAttribute

監査ログとの大まかな違い

一応以下のURLにも書かれていますが、あくまでレコードの変更(追加・更新・削除)あとアクセスくらいを記録するためのものでした。

それに対して、ActivityLogは上記の通り、監査ログよりももっと広い範囲の情報を取得しておけます。

https://docs.microsoft.com/ja-jp/dynamics365/customer-engagement/admin/enable-use-comprehensive-auditing#how-this-differs-from-past-audit-logging

それからデータの格納先、閲覧先もDynamics365からOffice365のセキュリティ・コンプライアンスセンターに変わっています。

現在ここには、Dynamics365以外のActivityLogも格納されているので、システム管理者が横断的にMicrosoft クラウド・プラットフォームの状況を把握することができるようにという考慮かなと思います。

ただ、私が触ってみて感じたちょっとした違いですが、監査ログでは、更新前のレコードと更新後のレコードの値が確認できましたが、ActivityLogではアップデートされたレコードしか確認することができませんでした。

f:id:sugimomoto:20190710001231p:plain

f:id:sugimomoto:20190710001236p:plain

何が見えるの?

監査ログは以下のようにOffice365セキュリティ・コンプライアンスセンターで検索できるようになります。

f:id:sugimomoto:20190710001241p:plain

CSV形式でダウンロードもできるので便利ですねー。

f:id:sugimomoto:20190710001251p:plain

あと、いくつか私が取得したログの詳細を紹介したいと思います。

RetrieveMultiple(ビューの表示・一覧の取得)

一覧表示のアクセスですね。これが今までの監査ログでは取れなかったので、大きなポイントですね。アクセスユーザーやUser Agentなども取得できています。

アクセスもとのIPアドレスが表示されるのも地味にいいですね。

f:id:sugimomoto:20190710001302p:plain

詳細のほうを見ると、RetrieveMultipleにリクエストされたクエリも見れますね。今回はアクティブな自分の取引先企業ビューを使ったので、それがQueryの欄に設定されていることがわかります。

QueryResultsで実際に取得したレコードのGUIDも確認できます。

f:id:sugimomoto:20190710001308p:plain

Create

Createは作成時のフィールド情報が表示されます。これは取引先企業に企業名だけを入力して作成したものですが、2つのオプションのデフォルト値も一斉に入力されるので、少し情報量が多いですね。

f:id:sugimomoto:20190710001315p:plain

Update

Updateはもう少しシンプルになります。YOみなめだけ上書きしたことが、リクエストからはっきりと読み取れますね。ただ、以前の値がなんであったのかはわかりません。

f:id:sugimomoto:20190710001322p:plain

Asociate(関連付け)

関連付けは関連元と関連先のGUIDがわかるだけでなく、関連付けしたルックアップフィールド名も確認できました。

f:id:sugimomoto:20190710001328p:plain

SetState

SetStateはちょっとおもしろいですね。これは非アクティブ化を実行したログです。SetStateがコールされた後にUpdate Accountが行われています。

f:id:sugimomoto:20190710001334p:plain

実際のリクエストはUpdateを見たほうがわかりやすいですね。StateCodeとStatusCodeがUpdateされていることがわかります。

f:id:sugimomoto:20190710001341p:plain

以上ですが、こんな感じの情報を見ることができました。

設定方法

それでは、AcitivityLogの設定を解説していきます。

設定は、Dynamics 365とOffice365両方で設定が必要です。特に面倒なことはありませんが、ちょっとわかりづらい部分もあるので、画面キャプチャベースで解説します。

必要要件

まず、必要要件ですが、Dynamics365のライセンス以外にもOffice365 E3もしくはE5のライセンスが必要となるので要注意です。

https://docs.microsoft.com/ja-jp/dynamics365/customer-engagement/admin/enable-use-comprehensive-auditing#requirements

  • Office365 E3 or E5

  • Dynamics 365 for CE

  • Dynamics 365のバージョンは「8.2.2.1310 」以降。今トライアルを取得する場合は特に気にしなくてOKです。

f:id:sugimomoto:20190710001347p:plain

Dynamics 365 側の設定

まずDynamics 365側の設定です。(ちなみにOffice365からやっても大丈夫です)

設定画面に移動して「管理」メニューを表示し

f:id:sugimomoto:20190710001353p:plain

「システム設定」を開きます。

f:id:sugimomoto:20190710001400p:plain

その中から、監査タブに移動して、監査をONにします。そして、「読み取り監査を開始する」にチェックを入れると、ActivityLogの設定が行われます。

また、基本的にデフォルトの監査ログと設定は共通のようです。監査対象とするエンティティや領域には今までと同じようにチェックを入れておく必要があります。

f:id:sugimomoto:20190710001407p:plain

また、エンティティのカスタマイズ画面でも設定を有効化します。以下は取引先企業のエンティティ設定画面です。

監査のチェックを入れるのはもちろんですが、今回のAcitivityLogで追加された設定である「単一レコード監査」「複数レコード監査」も確認できます。

前者がフォームなどでレコードを表示した場合(Retrieve)のログを出力し、後者が一覧画面やExcelエクスポートなどでレコードを表示した場合(RetrieveMultiple)のログ出力設定です。

読み取りはやはり1番ログを発生させやすいので、こういった形で細かく区切られているのだと思います。必要なものにチェックを入れて、「保存」→「公開」すれば設定は完了です。

f:id:sugimomoto:20190710001413p:plain

Office365 セキュリティ・コンプライアンスセンターの設定

次にOffice365 セキュリティ・コンプライアンスセンターで監査ログの有効化を行います。

セキュリティ・コンプライアンスセンターには「protection.office.com」のURLでアクセスできます。

アクセスしたら、左ナビゲーションから「検索」→「監査ログの検索」を選択します。デフォルトの環境では監査が有効化されていないので、以下のようにボタンをクリックします。

f:id:sugimomoto:20190710001421p:plain

※ちなみに、アカウントを取得したばかりだと、以下のように表示されません。少し時間を置いてアクセスし直す必要があります。(トライアルを取得したばかりの時がこうでした。)

f:id:sugimomoto:20190710001429p:plain

監査を有効化すると、以下のように監査の検索ができるようになります。ただ、最初はデータがクローリングされるまでにまた時間がかかるみたいです。1日くらい置いたほうがいいかもです。

f:id:sugimomoto:20190710001436p:plain

実際に監査ログを検索するには、そのまま検索ボタンを押してもいいですが、ここにはDynamics以外の監査ログも表示されるので、Dynamics 365 のアクティビティだけに絞ったほうがいいです。

f:id:sugimomoto:20190710001444p:plain

これで以下のように Dynamics 365 のActivityLogが表示されます。

f:id:sugimomoto:20190710001453p:plain

PowerApps CDS ではどうなの?

さすが同じアーキテクチャ! 同じように利用可能です!

f:id:sugimomoto:20190710001502p:plain

新しいデータ可視化ソリューション「Reveal」を使ってみた(#Dynamics365 for CE に接続)

UIコンポーネントベンダーであるインフラジスティックス(https://jp.infragistics.com/)から新しいデータ可視化ソリューション「Reveal」の提供が開始されました!

他のデータ可視化ツール(BIツール等)とは違って、自社サービスやアプリケーションに組み込むことを前提に提供されているのが、大きく違う点ですねー!(ここはすごくインフラジスティックスさんらしい。)

どんなソリューションなのか、実際にWeb上で触ってみることができたので、記事としてまとめてみました。

公式サイトは以下から。ここからトライアルも可能です。

revealbi.io

f:id:sugimomoto:20190702125938p:plain

ちなみに、今回の記事では組み込みではなく、シンプルにWeb版で提供されているアプリケーションとしてどんな感じのものか触ってた記録になります。でも、これだけでも組み込んだ時のイメージが結構湧きますね。

https://cdatajbuilds.s3-ap-northeast-1.amazonaws.com/sugimototest/Reveal3.gif

なお、日本ではインフラジスティックスジャパン主催のイベント「Distinct 2019」で正式発表になるみたいです。(と言いながら、このBlogを書いている数時間後に開催です)

connpass.com

続きを読む

#decode19 に参加&登壇してきましたレポート

年に1回開催される Microsoft の技術者向けカンファレンスであるdecode 2019 に参加&登壇してきました!

https://www.microsoft.com/ja-jp/events/decode/2019/default.aspx

f:id:sugimomoto:20190603214538p:plain

本当は去年 CData Software Japan のスポンサー枠で出展・登壇する予定だったのですが、私用で急遽参加できなくなっていたので、リベンジも兼ねて行ってきました!

私のセッション:誰のための API?

私のセッションでは、API Provider(提供側)に向けて、これからのAPI時代に向けて、使われる・活用されるAPIになるためには、どのように取り組むべきか? をテーマに Azure API ManagementとWeb API Standardで取り組むAPIエコシステム、Developer Experienceのあり方を解説しました。

セッションスライドおよび資料は以下のGistにまとめています。

www.slideshare.net

de:code 2019 Session Information MW04 誰のための API? Azure デベロッパーにもエンド ユーザーにも嬉しい API エコシステム活用アプローチ · GitHub

2週間前に開催されたJJUGでは、API 利用者側目線でのAPIエコシステムに触れましたが、今回は私が CData Software Japanに入ったぐらいから考え始めていたAPI 提供者側視点でのエコシステムの話です。

私のBlogでもちまちまと触れている要素ではあるんですが、こうしてまとまった形でセッションに起こすのは初めてだったので、そういった意味でも大変ありがたい機会になりました。

実は発表時は「うーん、反応いまいちかなぁ」と思っていたんですが、Twitterでありがたいコメントを頂いたりして、やってよかった! と今では思っています!

私が参加したセッション:1日目

以下、私が参加したセッションのざっくりとした感想を。

基調講演 #KN01

https://www.microsoft.com/ja-jp/events/decode/2019session/detail.aspx?sid=KN01

基調講演はなんともHoloLens押しでしたねー。ただ、今回は Dynamics 365 と組み合わせたサービスが大きく出てきたところが、個人的に大きなポイントでした。

dynamics.microsoft.com

f:id:sugimomoto:20190603214748p:plain

そのためか、今まで以上にDynamics 365が重要なポジションとして紹介されていましたね。

あと衝撃的だったのは平野社長のダンスですよねw ネタとしても秀逸ですが、テクニカル面の宣伝効果としても絶大だったのではw

Azure Data Services で実現するエンタープライズ データ分析基盤解説 #DP04

https://www.microsoft.com/ja-jp/events/decode/2019session/detail.aspx?sid=DP04

Azure Data Lake Storage Gen2がちゃんと理解できればいいかなーと思って結構気軽に参加したセッションだったんですが、Azure Databricks や Azure Data Factoryとの連携、プラクティスを押さえたセッションになっていて、個人的に思わぬ収穫でした。

もちろん、Azure Data Lake Storage Gen2の立ち位置も明確に解説してくれて、ようやく全体像がすっきりした感がありました。

HoloLens を活用した働き方改革! Dynamics 365 Guides・Remote Assist 活用手法と環境構築を解説します #CM05

https://www.microsoft.com/ja-jp/events/decode/2019session/detail.aspx?sid=CM05

今までちゃんとリアルでデモを見ていなかったので、参加してみたセッション。でも、HoloLens以上に、CDS・PowerBIも駆使して、Traningの各工程にかかった時間を可視化しているところが個人的に大ヒットでしたね。

今は目新しさの方が強くて、こんなことができるんだぜ! が先行してしまう感じですが、こういったビジネスニーズにぐさっとささる機能が出てくると、ぐっと導入した時の数字が見えてきていいですね。

SNS 分析を 20 分で作成! Power Platform の活用術 #PR81

https://www.microsoft.com/ja-jp/events/decode/2019session/detail.aspx?sid=PR81

写真を取り忘れたので拝借。Twitter分析は私も以前やっていたので、自分のやったアプローチとの比較やシナリオの参考にしたいなーと思っての参加でした。

ポイントはCognitiveを介して、キーフレーズの抽出ですかね! そのあたりを丁寧に解説されていたのが印象的でした。あとは物量が増えた時どうなるのかなーと思ったりです。


私が参加したセッション:2日目

.NET とクラウド ネイティブ ~ 本格化するクラウド移行とそのアーキテクチャ (前編) #DT07

https://www.microsoft.com/ja-jp/events/decode/2019session/detail.aspx?sid=DT07

なんといってもgRPC!

特に併せて.NET 5にWCFSOAP)が含まれなくなるというのが衝撃的でしたね。

もちろん、SOAPそのものはもう終わりでしょ感がありましたが、それに併せてgRPCへのシフトを打ち出してくるのは意外でした。

あとはgRPCがマイクロサービスレイヤーまでなのか、それともオープンAPI領域まで足を伸ばしてくるのかどうかが気になるところ。(プロトコルパッファーだとつらいかな) でも、これを期にC#でgRPCを攻めてみようと思ったりした次第。

デモで魅せます! 近未来の企業システム #SP04

https://www.microsoft.com/ja-jp/events/decode/2019session/detail.aspx?sid=SP04

いろんな製品カットで企業システムのデモを見せてくれたこのセッションでしたが、個人的にぐぐっと来たのは、最初に出てきたデータ活用促進のための解決アプローチ。ソフト面からハード面まで、どんな観点で取り組むべきか? が見えてきますね。

デモはDynamics 365 からPower Platform・IoTまで全部入。これがMicrosoft プラットフォームの強みだよなぁと改めて思ったり。

SQL Server 2019 Big Data Cluster 入門 #DP01

https://www.microsoft.com/ja-jp/events/decode/2019session/detail.aspx?sid=DP01&dy=2

SQL Server 2019 のBig Data 処理関連機能、SQL Server 2019の全体像を通して、Big Data Cluster(以下BDC)のポジション、捉え方から丁寧に解説されたセッションでした!

もともとBDC単体だけをさらっと見ていて、かつまあまあHortoneworksみたいなものでしょ?(穿った見方・・・)とぶっちゃけ思っていた私にとって、SQL Server との親和性、全体アーキテクチャを懇切丁寧に解説してもらえたので、BDCをなぜ使うのか? がとても腹落ちしたセッションでした。

特にSQL Server・BDCを通じて、今SQL Server以外にも多数存在している外部データをどのように処理していくのか? といったパターン、考え方、機能差の解説はすごくよかったです。このスライドだけでも、個人的には参加した価値がありました。

セッション資料はこちらで公開中。 https://github.com/MasayukiOzawa/decode-2019

C# ドキドキ・ライブコーディング対決 @ de:code - ONLY C#!! Blazor Web 開発バトル - #MW51

https://www.microsoft.com/ja-jp/events/decode/2019session/detail.aspx?sid=MW51

Burikaigi恒例コンテンツ! ドキドキライブコーディングが decodeに!

decodeらしく、いつも以上にMS最新テクノロジーを意識しているのかなーという回でしたが、Blazorの解説としてこれ以上適切なものはないんじゃないか!? というくらいテック解説コンテンツとしても素晴らしいものでした!

あまりBlazorに注目していなかった(ry)自分も、思わずやってみたくなるほど。(そういえば、CData ADO.NET ProviderもWebAssemblyとしてロードできたりするのかな? 調べてみよう)

技術カンファレンスの締めとして、素晴らしいセッションでした!

おわりに

実は4月末から咳が止まらないなーと思っていたら、1週間前に肺炎と診断されて「やばたにえん!」という感じだったんですが、なんとか気合とおくすりで直して、参加できて、本当によかったです!

自分のセッションとしては、反省点も多くありましたが、何はともあれとても素晴らしい経験をさせていただきました。

来年もまた参加するぞー!

LogicAppsでHTTPコネクタを使う時、SwaggerSpec(OpenAPI)を挟むと楽ができるよというお話

SwaggerってなんとなくAPIを開発する側やAPIを使ってプログラミングする側が嬉しいよねー、っていうシチュエーションで語られることが多いと思うんですが、今ローコードな界隈でも結構役立ちます。

Swagger なにそれ? みたいな方は以下の記事をどうぞ。

bit.ly

その一例がMicrosoftが提供している「LogicApps」での活用です。

https://azure.microsoft.com/ja-jp/services/logic-apps/

f:id:sugimomoto:20190524232549p:plain

LogicAppsではフローチャートを描くようにGUIベースでデータ統合処理を開発することができる、PaaS基盤です。

標準のHTTPコネクタはこんな感じ

LogicAppsは標準でも数多くのSaaSクラウドサービス・DBに接続するためのコネクタが提供されていますが、標準提供以外のWeb APIなどと連携するために「HTTP」コネクタが用意されています。

コネクタを開くと、おそらくPostmanなどを普段使う人にとっては馴染み深い画面が表示されます。 「あー、Method選んで、URI書いて、ヘッダー書いて、URLパラメータとしてクエリ書けばいいのね。ふむふむ」みたいな人はこれで済みますが、そういったことに馴染みが薄い人はなかなか大変です。

(知っている人でもちまちまドキュメントからコピペしてくるのは面倒だと思う)

f:id:sugimomoto:20190524232558p:plain

せっかくなのでこのAPIを通じてCustomer情報を取得して、Dynamics 365 に取引先担当者を作るための処理をGIF動画に撮ってみました。

https://s3-ap-northeast-1.amazonaws.com/cdatajbuilds/sugimototest/LogicApps/NormalHTTPRequest.gif

URLやヘッダー、パラメータを手打ちしなければいけず、また取得した本文も一度JSON解析をしなければいけないのが若干面倒ですね。(慣れてしまえばそんなことも無いかもだけど)

そこで HTTP + Swagger を使おう

そこで、Swagger ベースで公開されている API であればさくっとHTTPリクエストが使えるようになる「HTTP + Swagger」を使ってみます。

f:id:sugimomoto:20190524232616p:plain

https://s3-ap-northeast-1.amazonaws.com/cdatajbuilds/sugimototest/LogicApps/SwaggerHTTPRequest.gif

今回使うAPIは以下のとおりです。顧客情報であるCustomerリソースを取得・作成・更新・削除するエンドポイントを備えています。

https://decodeapiserverdemo.azurewebsites.net/api.rst

f:id:sugimomoto:20190524232624p:plain

このAPIの作り方は、以下のURLから。

kageura.hatenadiary.jp

このAPIではSwaggerで作られているのと同時にSwagger Specを取得するためのエンドポイントもサポートしています。以下のURLでアクセス可能。

https://decodeapiserverdemo.azurewebsites.net/api.rsc/@1q0E5n7v8V1k4r1U5g0e/$swagger

f:id:sugimomoto:20190524232711p:plain

これを「HTTP+Swagger」に取り込むと

f:id:sugimomoto:20190524232717p:plain

こんな感じで、APIの機能をリストアップ

f:id:sugimomoto:20190524232725p:plain

URLパラメータや認証処理なんかもさくっと選択して入力することができます。

f:id:sugimomoto:20190524232745p:plain

また予めレスポンスオブジェクトのフォーマットがわかっているのでそのままValueを取り出して、値を設定することができます。

f:id:sugimomoto:20190524232753p:plain

注意点

Swaggerを取り込むためのURLはCORSが許可されていないとLogicAppsがアクセスできないです。

もし、CORSが許可されていない場合は、Azure Storeageに配置してCORSを許可する方法があります。(ただちょっと面倒か)

Reference

docs.microsoft.com

Slack の利用状況を可視化して見えてくるものってなんだろう? Power BI と CData Slack Connector で利用状況レポートを作る方法

最近Twitterでこんなご意見をもらいました!

社内利用状況レポート! なるほど!

最近はビジネスチャット戦国時代ですもんね。Slackを筆頭に、TeamsやChatWork、LineWorkなど、どんどんサービスが増えて、盛り上がっているなーと感じます。

boxil.jp

ただ、導入したとしても、うまく活用されているのかってやっぱり気になりますよね。もっと有効活用されるには、もっとコミュニケーションが活発になるにはどうしたらいいのか? いろんな会社・コミュニティで試行錯誤しているのかなとも感じています。

そこでやっぱりひとつの指針として(サブスクリプションサービスにお金を払っているなら尚更)、利用状況というのは可視化したいというニーズは強いのでしょうね。

でも実際のところ利用状況レポートってどうなの? 役立つの? 

ただ、私自身実際にデータは取れることは理解していても、Slackのデータを分析することで見えてくるものが本当にあるのか? ってわからなかったんですよね。

そこで今回は、Slackをベースにチャットツールからのデータの取得の仕方だけでなく、実際にレポートとして作成したものを紹介して、どんな情報が可視化できるのか!? 試してみた結果をお届けします。

また、チャットツールって結構会社さんごとに使い方にばらつきがあるのではないかと思っているので、SNSを通じて、みんなが使っているSlackの状況を共有してもらおうと考えています!

いい感じに協力してくれた方のレポートが集まったら、それをまとめた記事+勉強会での発表もしようかなと考えていますので、是非ご協力いただければと思います!

こんなレポートが出来上がった!

早速ですが、作成した Slack 利用状況レポートを紹介したいと思います。

今回はなんと Microsoft Power BI MVP の清水さんに協力頂いてレポートを作成してもらうことができました!

こんな感じのレポートです! 接続先は清水さんがイベントの管理などで利用しているSlackとのこと。

f:id:sugimomoto:20190516195540p:plain

Messages数の偏りやチャネルごとの投稿状況、時間帯別の投稿状況が可視化されていて、面白いレポートに仕上がっています!

f:id:sugimomoto:20190516195546p:plain

そのSlackの役割にもよるかもしれませんが、メインのチャネルが固定されていて、ユーザー投稿にもかなり偏りがあることが見て取れます。

私は勝手に、チャネルごとにみんなバラバラ投稿しているんじゃないかなと思っていたりしたのですが、やはりSlackごとに特色があるものですねー。

ちなみに、以下のURLでReportのテンプレートの使い方を公開しています!

bit.ly

是非試してみてください! そしてよかったら、Poewr BI Facebook Groupかツイッターで流してもらえると、みんなで比較ができるので、いろんな考察が捗るのではないかと思っています。

Slackのデータはどうやって取得するの?

それでは実際にレポートを作るためのデータ取得方法を解説したいと思います。

Slackのデータは現状Power BI に標準のコネクタが無いので、基本的には Web API 経由で取得しないといけません。ただ、認証だったり、取得したJsonのパースだったり、テーブル形式に直したりと、手間がかかることが多いので、CData Slack Power BI Connectorを使って、楽をします。

f:id:sugimomoto:20190516195636p:plain

https://www.cdata.com/jp/drivers/slack/powerbi/

こちらのページから「ダウンロード」をクリックして、評価版を入手してみてください。

継続的にデータを分析するのであれば製品版が必要ですが、一回きりの取得であれば、機能差は無いので評価版で大丈夫です。

ダウンロード後、インストーラーが起動するので、そのまま次へ進めていきます。

f:id:sugimomoto:20190516195702p:plain

インストールが完了すると、以下のように接続設定の画面が表示されます。

特に入力は不要で、そのまま「接続のテスト」をクリックすればOKです。

f:id:sugimomoto:20190516195708p:plain

すると、以下のようにOAuthの承認画面が表示されるので、内容を確認の上「許可する」をクリックしてください。

f:id:sugimomoto:20190516195714p:plain

f:id:sugimomoto:20190516195719p:plain

以下のような画面が表示されれば接続OKです。接続画面もそのままOKをクリックして閉じます。

f:id:sugimomoto:20190516195725p:plain

Power BI でのデータ取得方法

それでは、Power BIからSlackのデータを取得してみます。

まずは手軽にチャンネルの一覧から。

f:id:sugimomoto:20190516195731p:plain

CData Power BI Connectorのインストールが正常に完了していると、データを取得の一覧で、以下のようにCData Slackのアイコンが追加されます。これを選択して、「接続」をクリックします。

f:id:sugimomoto:20190516195738p:plain

最初にサードパーティサービスの確認が出てくるので、そのまま続行をクリック

f:id:sugimomoto:20190516195743p:plain

Data Source Nameを選択(1種類しか無いはずです)して、OKをクリックします。ちなみに、CData Power BI ConnectorはSQLでSlackのデータが取得できるようになっているので、SQL Statementのところに「SELECT * FROM hogehoge」と書いてもデータが取得できますが、それは後ほど。

f:id:sugimomoto:20190516195749p:plain

ナビゲーターの画面では、取得できるテーブルの一覧が表示されるので、Channelsを選択して、読み込みます。

f:id:sugimomoto:20190516195755p:plain

すると、こんな感じでチャンネルの一覧が取得できます。

f:id:sugimomoto:20190516195801p:plain

Messageの取得方法

Messageの取得方法は若干特殊です。

もともとSlackのAPIでは、Messageの取得処理にChannelIdが必要となっているので、CData Power BI Connectorを使う場合も、ChannelIdをWhere句で指定する必要があります。

今回はすべてのチャネルからメッセージを取得したいので、Power Queryを使ってこれを実現します。

新しくデータを追加するため、「クエリの編集」をクリックし

f:id:sugimomoto:20190516195943p:plain

「空のクエリ」を追加します。

f:id:sugimomoto:20190516200107p:plain

詳細エディタを開いて、以下のようなクエリを追加します。

let
    Source = "CData Power BI Slack",
    ChannelsQuery = "select * from Channels ",
    MessagesQuery = "select * from Messages Where ChannelId = '",
    
    Channels = CData.Slack.DataSource(Source, null, [Query = ChannelsQuery]),

    ChannelRecoreds = Table.Column(Channels,"Id"),

    AllData = Table.Combine(
    List.Transform(
        ChannelRecoreds,
        each CData.Slack.DataSource(Source, null, [Query = MessagesQuery & _ & "'" ])
        )
    )
in
    AllData

f:id:sugimomoto:20190516200327p:plain

やっていることは単純で「select * from Channels」で取得してきたチャネル一覧を元に、「"select * from Messages Where ChannelId = 」で各チャネルからメッセージを取得しています。

これで、以下のようにメッセージ一覧が取得できます。

f:id:sugimomoto:20190516200505p:plain

あとは取得したデータのリレーションを構成して、レポートを作成できる環境が整います。

f:id:sugimomoto:20190516200607p:plain

おわりに

Power BI で Slack の利用状況を可視化しよう!How to use Power BI Template & CData Power BI Connectoer

この記事では、Power BI Slack 利用状況可視化レポートの使い方を解説します。

実行すると、自身のSlack環境に接続でき、以下のようなレポートが自動で表示されます!

レポートは初期状態でチャネル名やユーザー名を伏せた状態になるので、このままキャプチャしたものを公開してもSlack内の情報が漏れることは無いので安心してください。

f:id:sugimomoto:20190516193809p:plain

f:id:sugimomoto:20190516193815p:plain

Report のTemplateは以下のURLから入手できます。

https://s3-ap-northeast-1.amazonaws.com/cdatajbuilds/sugimototest/SlackPowerBI.zip

Power BI Report Templateの作成には、Power BI の Microsoft MVP である清水さんにご協力いただきました! ありがとうございます!

twitter.com

清水さんは他にも様々なレポートを公開しています。是非見てみてください。

qiita.com

必要なもの

実施にあたり必要なものは以下のとおりです。

  1. Power BI Desktop ※古いバージョンの場合、Templeateが利用できない可能性があるため、最新バージョンをインストールしてください。

  2. Power BI Slack Report Template(こちらからダウンロード https://s3-ap-northeast-1.amazonaws.com/cdatajbuilds/sugimototest/SlackPowerBI.zip

  3. CData Power BI Slack Connector (https://www.cdata.com/jp/drivers/slack/powerbi/

  4. Slack アカウント

注意事項

  1. 無償版 Slack の場合、1環境に登録できるアプリが10までとなっているため、すでに10個アプリを接続している場合は、使用することができません。

  2. 無償版Slackの場合、取得できるメッセージの上限が10,000件までです。そのため、チャネルによっては、

1. CData Power BI Slack Connector のダウンロード・セットアップ

まず Power BI から Slackに接続できるようにするために、CData Power BI Connector を入手します。

以下のURLから30日間のトライアル版がダウンロード可能です。機能制限は無いため、今回はそのまま利用できます。

https://www.cdata.com/jp/drivers/slack/powerbi/

ダウンロードをクリックし

f:id:sugimomoto:20190516194003p:plain

「ダウンロード評価版」を選択します。

f:id:sugimomoto:20190516194011p:plain

必要情報を入力して、「ダウンロード」をクリックしてください。

f:id:sugimomoto:20190516194017p:plain

ダウンロードした、インストーラーはそのまま次へ次へと進めれば、完了します。

f:id:sugimomoto:20190516194023p:plain

2. Slack への接続設定

インストール後、以下のような画面が立ち上がるので、特に何も入力せず「接続のテスト」をクリックしてください。

(ProxyServerなどを経由したい場合は別途設定ができます。わからないことがあれば、私のTwitterFacebookまでどうぞ。@sugimomoto)

f:id:sugimomoto:20190516194029p:plain

「接続のテスト」をクリックすると、OAuth認証処理が開始されるので、ログインするSlackのアカウントを選択した後、接続の許可を行います。

f:id:sugimomoto:20190516194034p:plain

f:id:sugimomoto:20190516194040p:plain

最終的に以下のような画面が表示されれば、接続構成はOKです。

f:id:sugimomoto:20190516194048p:plain

3. Report Template を立ち上げる

最後にダウンロードした Report Template を開きます。

f:id:sugimomoto:20190516194053p:plain

立ち上げるとODBCの接続情報入力が表示されるので「CData Power BI Slack」と入力します。(※スペースなどに気をつけてください)

f:id:sugimomoto:20190516194058p:plain

すると、先程接続構成を行ったSlackからデータの取得処理が開始されます。

f:id:sugimomoto:20190516194105p:plain

取得が完了すると、以下のようにレポートが表示されます。

f:id:sugimomoto:20190516194113p:plain

4. よかったら FacebookTwitter でシェアしてください。

Facebook で Power BI Groupがあるので、是非投稿してください。

www.facebook.com

また、ツイッターでのツイートも大歓迎です! 以下はハッシュタグ付きのツイート用URLです。

twitter.com

Office365 GraphAPI で認証アプローチ毎のアクセス範囲にハマった話 ユーザーの予定(Event)を横断的に取得したい! 

先週くらいに、Office365 のCalendar情報を横断的に取得したいという要望があって調べていたんですが、ちょっと変に先入観があって躓いていました。

https://twitter.com/sugimomoto/status/1113275622841737218?s=20

いろいろと試行錯誤を経て解決したんですが、改めて全体像を調べてスッキリ理解できたので、GraphAPIにおける認証アプローチとアクセス範囲に関する考え方をまとめておきたいと思います。

ちなみにわかり易さから予定表(イベント)の取得に焦点を当てていますが、考え方はファイルやメールなどにも共通するお話です。

なお、Exchange Online(EWS)ベースのアプローチであれば、以前取り組んでいたのをBlogにしています。

kageura.hatenadiary.jp

やりたかったこと

Office365の予定表では、以下のような感じにいろんな人の予定が見えるようになっていると思いますが、これをGraphAPI経由で横断的に取得したい、というのが今回の目的です。

こんな感じの予定データを

f:id:sugimomoto:20190422185231p:plain

横断的に取得して、分析活用したい、というイメージですね。

f:id:sugimomoto:20190422185236p:plain

データ連携的観点でも、例えば外部のCRMアプリケーションなどで作られた営業案件の再訪問スケジュールを連携して、結果を確認したい、みたいなことがあると思います。

それを実現するための、GraphAPIアクセス範囲・アクセス許可の考え方です。

今回のお話の焦点:Azure AD アプリにおけるGraphAPIのアクセス許可

今回とりあげるのは、Azure ADのアプリケーション登録で行う以下のアクセス許可の話です。

f:id:sugimomoto:20190422185247p:plain

以下のリファレンスがベースになりますが、私の解釈も踏まえてざっくりお話していきます。

docs.microsoft.com

ベースとなるアクセス許可は2種類

まず、大前提として抑えておきたいことは、ベースとなる「アクセス許可」は2種類存在するということです。

docs.microsoft.com

それが、「委任されたアクセス許可」と「アプリケーションのアクセス許可」です。

f:id:sugimomoto:20190422185322p:plain

なんのことを言っているんだ、となるかもしれませんが、これはOAuthのAuthorizationURLが2種類

「委任されたアクセス許可」の場合以下のようなURLで

https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?client_id=6731de76-14a6-49ae-97bc-6eba6914391e&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F&response_mode=query&scope=offline_access%20user.read%20mail.read&state=12345

このようなアクセス許可を求められますね。

f:id:sugimomoto:20190422185349p:plain

https://docs.microsoft.com/ja-jp/graph/auth-v2-user#2-get-authorization

「アプリケーションのアクセス許可」の場合は、URL構成が変わって、

https://login.microsoftonline.com/{tenant}/adminconsent?client_id=6731de76-14a6-49ae-97bc-6eba6914391e&state=12345&redirect_uri=https://localhost/myapp/permissions

ちょっとだけ、メッセージも変わったことがわかると思います。

f:id:sugimomoto:20190422185355p:plain

https://docs.microsoft.com/ja-jp/graph/auth-v2-service#3-get-administrator-consent

メッセージが示すとおりでもありますが、それぞれで役割が違います。

  • 委任されたアクセス許可

明示的なサインインユーザーが存在する場合に利用するアプローチです。 これは言ってしまえば、ユーザー自身がOffice365を利用する時と同様のアクセス範囲を想定した 自分の予定、自分のメール、自分のファイルをベースに、アクセス許可を行ったユーザーに共有されたgファイル、予定などにもアクセスすることを想定しています。

  • アプリケーションのアクセス許可

明示的なサインインユーザーが存在しないアプリで利用するアプローチです。たとえば、バックグラウンド でデータ連携をしたり、強力な権限で組織全体のリソースにアクセスしたい場合に使用します。そして注意したいのが、アプリケーションのアクセス許可は「管理者のみが同意」してはじめて利用できるようになるという点です。

GraphAPIリソースへのアクセス許可は「リソース:操作:制約」の3つで捉える

その上で、GraphAPIのアクセス許可は以下の図に示すように、「リソース:操作:制約」の3つで捉えるのが個人的にいいと思っています。

  • リソースは「Event、File」など、どんなデータにアクセスするのか
  • 操作は「Read、Write」など、データに対してどんな処理を行うのか
  • 制約は「All、Shared、None」など、どの範囲までアクセスするのか

f:id:sugimomoto:20190422185433p:plain

今回の図は趣旨を理解しやすくするために単純化していますが、「操作」と「制約」はこれ以外にもいくつかあります。

必要な操作とリソースの特定方法

おそらく、操作とリソースは比較的わかりやすいでしょう。

予定を取りたいなら、CalenderのRead

予定の書き込みも行いたいなら、CalenderのReadWrite

各必要なリソース名、操作はそれぞれのリソースページから確認することができます。

例えば予定(Event)の主得であれば、以下の通り。

docs.microsoft.com

f:id:sugimomoto:20190422185443p:plain

アクセス範囲の肝となる「制約」の考え方

そして、今回のポイントになるのは、この「制約」の部分になります。

基本的な制約の種類は以下の3種類。一番上が強い権限です。

  • All
  • Shared
  • None(制約の指定無し)

Noneだけちょっと分かりづらいですが、一番弱い(アクセス範囲が狭い)権限です。ドキュメントでは「制約の指定無し」と書かれていて、混乱を招きやすいですね・・・。一番弱い制約って言うと語弊がありますし。

これ以外に、AppFolderや各リソース固有のものが存在しますが、基本的には上記の3種類がベースになっていると思っていいと思います。

それぞれの制約の範囲イメージ

これらの制約をEventのリソースをベースに表したのが、以下のそれぞれの図になります。

Noneの場合は、アプリケーションにログインしたユーザー自身のリソースにしかアクセスできません。これは、予定が共有されていたとしても変わりません。

f:id:sugimomoto:20190422185507p:plain

そして、もう少しアクセス範囲を広げたい場合は、Sharedが必要になります。この場合は自分の予定に加えて、共有されている予定にもアクセスできます。

f:id:sugimomoto:20190422185515p:plain

そして、最後に共有されていない予定にもアクセスしたい場合は、「All」が必要になります。これが今回私が必要としていたアクセス範囲です。

一番注意したいのが、委任されたアクセス許可では、この制約範囲を利用できない、ということです。

f:id:sugimomoto:20190422185522p:plain

制約で「All」を使いたい場合は 2種類のアクセス許可に気をつける

ここが今回私が躓いたポイントでした。

アプリケーションの権限で「Calender.ReadAndWrite.All」を付与していたにも関わらず、アクセス許可は「委任されたアクセス許可」で実施していなかったので、他のユーザーのリソースにアクセスしようとしても「Access is denied.」になってしまいました。

f:id:sugimomoto:20190422185534p:plain

それぞれの「アクセス許可」方法の確認

ここまで来れば、あとはそれぞれの「アクセス許可」を使ってAccessTokenを取得するだけです。

アプリケーションの登録方法はどちらも同じですが、アクセス許可の方法は

「委任されたアクセス許可」の場合、「AuthorizationCode」

「アプリケーションのアクセス許可」の場合、「ClientCredential」

で実施します。

ちなみに、Graphエクスプローラーは現在「AuthorizationCode」にしか対応していないみたいなのでご注意ください。

「委任されたアクセス許可」を使ってユーザーの代わりにアクセスを取得する

ほとんどリファレンスに書かれている通りなので、要点だけ記載します。

docs.microsoft.com

1. AuthorizationURLを生成して、ユーザーへログイン要求を実施

この時ポイントになるのが、Scopeパラメータ。アプリ側で権限を許可していても、ここでスコープの要求をしない限り、操作を実施することはできないので要注意。

https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize?client_id=6731de76-14a6-49ae-97bc-6eba6914391e&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F&response_mode=query&scope=offline_access%20user.read%20mail.read&state=12345

f:id:sugimomoto:20190422185554p:plain

2. アクセス許可後のリダイレクトURLに含まれる「Code」を使って、AccessTokenを取得

Callbackとして、以下のようなデータが返却されるので、Stateをチェックし、Codeを取得したら

https://localhost/myapp/?
code=M0ab92efe-b6fd-df08-87dc-2c6500a7f84d
&state=12345

そのCodeを利用して、TokenエンドポイントにAccessTokenを要求します。この時GrantTypeはAuthoricationCodeを指定します。

POST https://login.microsoftonline.com/common/oauth2/v2.0/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded

client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&scope=user.read%20mail.read
&code=OAAABAAAAiL9Kn2Z27UubvWFPbm0gLWQJVzCTE9UkP3pSx1aXxUjq3n8b2JRLk4OxVXr...
&redirect_uri=http%3A%2F%2Flocalhost%2Fmyapp%2F
&grant_type=authorization_code
&client_secret=JqQX2PNo9bpM0uEihUPzyrh

これで晴れてAccessTokenが取得できます。

{
    "token_type": "Bearer",
    "scope": "user.read%20Fmail.read",
    "expires_in": 3600,
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...",
    "refresh_token": "AwABAAAAvPM1KaPlrEqdFSBzjqfTGAMxZGUTdM0t4B4..."
}

「アプリケーションのアクセス許可」の仕方、ユーザーなしでアクセスを取得する

docs.microsoft.com

アプリケーションのアクセス許可も基本プロセスは似ていますが、要所要所でちょっと違います。

1. Adminconsentエンドポイントを使って、管理者の同意を実施

前述したとおり、一番最初に必要なことは、対象のアプリケーション(ClientID)に対して、管理者が同意するというプロセスです。「委任されたアクセス許可」とはURLやパラメータが違うことに注意してください。

GET https://login.microsoftonline.com/{tenant}/adminconsent
?client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&state=12345
&redirect_uri=https://localhost/myapp/permissions

f:id:sugimomoto:20190422185624p:plain

また、レスポンスも変わり、「委任されたアクセス許可」であったようなCodeは含まれません。つまり、「アプリケーションのアクセス許可」の場合、同意と後続のプロセスは独立した形になります。

GET https://localhost/myapp/permissions
?tenant=a8990e1f-ff32-408a-9f8e-78d3b9139b95&state=12345
&admin_consent=True

2. 同意された後、AccessTokenを取得する

同意が完了したら、あとはAccessTokenを取得するだけです。前述したとおり、Codeを渡す必要は無いので、同意さえ取っていれば、どのタイミングで実施しても問題ありません。

POST https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token HTTP/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

client_id=535fb089-9ff3-47b6-9bfb-4f1264799865
&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&client_secret=qWgdYAmab0YSkuL1qKv5bPX
&grant_type=client_credentials

あとは、同じようにAccessTokenがレスポンスで変えるだけですが、Scopeが含まれないので要注意。

{
  "token_type": "Bearer",
  "expires_in": 3599,
  "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1uQ19WWmNBVGZNNXBP..."
}

※ちなみに、管理者の同意はAzure ADのアプリケーション管理画面で「アクセス許可の付与」をクリックすれば、特にURLの生成などは必要なく実施することができます。(逆に手軽に実施できてしまうので要注意)

f:id:sugimomoto:20190422185652p:plain

余談:そもそも「管理者」ってどんな「管理者」?

GraphAPIとAzure ADのアプリリファレンスを見ていると、たくさんの「管理者」というキーワードに遭遇します。

そして、今ひとつどの管理者設定を入れておけば、この管理者という要件を満たすのかが、いまいちわかりづらいですね。

管理者の同意に必要な権限は何か?

結論から言うと、Azure AD ロールの「アプリケーション管理者(全体管理者でももちろんOK)」が必要です。

アプリケーション管理者:このロールのユーザーは、エンタープライズ アプリケーション、アプリケーション登録、アプリケーション プロキシの設定の全側面を作成して管理できます。 さらに、このロールは、委任されたアクセス許可とアプリケーション アクセス許可 (Microsoft Graph と Azure AD Graph を除く) に同意する権限を付与します。 このロールに割り当てられたユーザーは、新しいアプリケーション登録またはエンタープライズ アプリケーションを作成する際に、所有者として追加されません。

https://docs.microsoft.com/ja-jp/azure/active-directory/users-groups-roles/directory-assign-admin-roles

以下の画面で付与することができます。

f:id:sugimomoto:20190422185718p:plain

なので、例えば、予定表を取得したいからといって、Exchangeの管理者権限が必要か? といえばそんなことは無いようです。アプリケーション管理者が同意してしまえば、そのClientIDはその権限にしたがって効力を発揮します。

ちなみに、私がはじめ勘違いしていたのですが、Office365 管理画面で表示できる、この画面の役割とさっきのAzure ADロール管理画面の役割は一緒です。同期されてます。

f:id:sugimomoto:20190422185708p:plain

ただし、アプリケーション管理者のロールはAzure ADロール管理画面でしか付与することができませんので要注意。

実際に予定を取得してみる

というわけで、実際に予定を取得してみます。せっかくなので「アプリケーションのアクセス許可」で試してみましょう。シェアをしていないユーザーの想定です。

docs.microsoft.com

1. Azure AD アプリケーション登録

まず、リファレンスにある通り、「Calendars.Read.All」の権限を持ったAzure ADアプリを作成。

CientIDとCientSecretを取得します。(アプリの作り方は以前Blogで書いているので割愛。)

kageura.hatenadiary.jp

2. 管理者の同意を取得

さくっと、Azure ADの画面から実施してしまいます。

f:id:sugimomoto:20190422185652p:plain

3. アクセストークンの取得

そして、アクセストークンを取得します。

POST /a67527d4-180e-4472-bcdd-bca82c56c70a/oauth2/token?api-version=1.0 HTTP/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
client_id=XXXXXXXXXXXXXXXXXXXXXXXXXX
&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&client_secret=XXXXXXXXXXXXXXXXXXXXXXXXXXXX=
&grant_type=client_credentials

4. 指定ユーザーのイベントを取得

通常、自分自身のイベントを取得する場合は以下のようなURLですが

GET /me/events

他のユーザーのイベントを取得する場合はUsersの後にXXX@XXX.onmicrosoft.comといった形でユーザーを指定することで、予定を取得できます。

GET /users/{id | userPrincipalName}/events

実際にはこんな感じのリクエストですね。

GET /v1.0/users/user01@sugimomoto21.onmicrosoft.com/events HTTP/1.1
Host: graph.microsoft.com
Authorization: Bearer eyJ0XXXXXXXXX

CData Office365 Driverの対応状況

ちなみに、CData Office365 Driverを使って、予定やファイルの取得が可能なのですが、今の所「委任されたアクセス許可」のみに対応中でした。

でも、やっぱり管理権限でバッチ処理を動かしたり、予定を横断的に取得したいというシナリオはよく聞くので、現在USチームと実装に向けてディスカッション中です。

もし、そういった使い方

https://www.cdata.com/jp/drivers/office365/

ちなみに、Excel-Addinで予定を取得する場合は、Office365 Excel Add-inをインストールして

Excelのリボンから「From Office365」をクリック

f:id:sugimomoto:20190422191723p:plain

接続画面はDefaultのままでいいので、「Test Connection」をクリック

f:id:sugimomoto:20190422191756p:plain

同意画面が表示されるので、内容を確認して、承諾するだけ。

f:id:sugimomoto:20190422192313p:plain

接続が完了します。

f:id:sugimomoto:20190422192328p:plain

あとは、Eventsテーブルを選択して、OKをクリックすれば

f:id:sugimomoto:20190422192422p:plain

自分自身の予定データがずらっと取得できます。

f:id:sugimomoto:20190422192551p:plain

おわりに

結構権限周りを調べるのはめんどいことがわかった記事でした。

結構悩む人は多いのではなかろうか。。。