はじめに
以前こちらの記事でSharePointリストのいいね機能をPower Appsで利用する方法を記載しました。
この機能を使えばPower Appsで簡単に投票機能やちょっと工夫すれば既読機能などを作成できるようになるような組み合わせでしたね。
ただし、この機能の問題点として記事の最後でも記載しているようにPower Appsでこのいいね列が参照できなくなってしまう場合がある。
という重大な問題がありました。
今回はこの問題が発生した場合の対応策(もしくはこの問題を回避するための対策)を記載したいと思います。
対応案/回避案
一度評価の設定をオフにする
一番簡単(でもちょっと怖い)な対応案です。
SharePointリストの設定を開き、「評価の設定」より、「評価の設定」を「いいえ」に戻します。
これにより評価機能はオフになりますが、いいねや評価した結果は(私が検証した結果は)消えませんでした。
評価やいいねの列も残ったままでした。(これはいいのか。。。?)
* あくまで私が検証した結果は。なので自己責任でお願いしますね。
続けて「評価の設定」を再度開き、「評価の設定」を「はい」に戻します。
Power Appsに戻り、接続しているSharePointリストを最新の情報に更新します。
これにより、再度Power Appsで評価(いいね)機能が識別されるようになり、いいね機能が利用できるようになるかと思います。
Graph APIを用いて取得する
Graph APIを用いて、いいね列を明示的に指定してリストのアイテムを取得します。
そもそもの話になりますが・・・ Graph APIを用いてリストのアイテムを取得する方法として以下のような方法がありますが、
Graph API
GET https://graph.microsoft.com/v1.0/sites/{site-id}/lists/{list-id}/items?expand=fields
こちらで取得してみるとわかる通り、Graph API(ついでにいうとSharePoint REST API)でアイテムを取得しても、評価列やいいね列は取得できません。
GET https://{tenant-name}.sharepoint.com/_api/web/lists/GetByTitle('{list-title}')/Items
よって、以下のようにフィールドを明示する必要があります。
Graph API
GET https://graph.microsoft.com/v1.0/sites/{site-id}/lists/{list-id}/items?expand=fields(select=ID,Title,LikesCount,LikedBy)
GET https://{tenant-name}.sharepoint.com/_api/web/lists/GetByTitle('{list-title}')/Items?$select=ID,Title,LikesCount,LikedBy/Title,LikedBy/Id&$expand=LikedBy
このように取得を行なうことで、評価列やいいね列を取得することが可能です。
ただ、このやり方だと利用したいフィールドをすべて指定する必要がありますね。
AddColumns関数によりフィールドを追加する
もし、フィールドをすべて指定するのが面倒であればPower AppsのSharePointコネクタより取得した情報にいいね列の情報を追加する方法もあります。
例えば以下のようにすれば、いいねの数をフィールドに追加することができます。
ClearCollect( col, AddColumns( {SharePoint-List}, "いいね", [ Office365グループ.HttpRequest( $"https://graph.microsoft.com/v1.0/sites/{site-id}/lists/{list-id}/items/{ThisRecord.ID}?expand=fields(select=LikesCount)", "GET", "", {ContentType: "application/json"} ) ] ) )
{SharePoint-List}、{site-id}、{list-id}は自身の環境に合わせて変更してください。
Power AppsからGraph APIを実行する場合は、"Office365グループ"コネクタの"HttpRequest"アクションを利用します。(V2じゃないよ!)
こちらのアクションは動作関数なので、非動作プロパティであるGalleryのItems
には直接設定できないので気を付けてください。
"HttpRequest"アクションを []
で囲っているのはテーブルとして設定するためですね。
この方法で取得した値は、"UntypedObject"になるので、Text関数やTable関数などで型を明示してあげる必要があるのですが、Power Appsにはレコード型だと明示するための関数が存在しません。
なので一度テーブル型にしてあげているわけですね。
ここで追加されるのは対象レコードのアイテムなので複数のレコードが取得されることはありません。
よって上記で取得した結果をPower AppsのGallery内のラベルで表示したい場合は以下のようになります。
Gallery.Label.Text
Text(First(ThisItem.いいね).Value.fields.LikesCount)
APIですべて解決する
Graph APIとSharePoint REST APIだけで、SharePointリストの情報を取得/更新する方法です。
まず取得ですが、先ほどと同じような処理で行います。
Button.OnSelect
UpdateContext( { listItems: Office365グループ.HttpRequest( "https://graph.microsoft.com/v1.0/sites/{site-id}/lists/{list-id}/items/?expand=fields(select=ID,Title,LikesCount,LikedBy)", "GET", "", {ContentType: "application/json"} ) } )
余談ですが、ここで取得した結果はParseJSON関数を使わなくても勝手にParseJSONしてくれます。
便利ですね。
ParseJSONってなに?という方は(少し古いですが)こちらをみていただけると。
いいねなどの値を表示させる
それぞれのフィールドのGalleryでの表示方法を一応記載しておきます。
Gallery.Items
Table(listItems.value)
id
ThisItem.Value.fields.id
Title
ThisItem.Value.fields.Title
LikesCount(いいねの数)
ThisItem.Value.fields.LikesCount
LikedBy(いいねした人)
Concat(Table(ThisItem.Value.fields.LikedBy), ThisRecord.Value.LookupValue, ";")
LikedByの中身をギャラリーに表示したい場合。
Gallery.Items
Table(ThisItem.Value.fields.LikedBy)
いいねした人の表示名
ThisItem.Value.LookupValue
いいねした人のID(※SharePointで利用される方のID)
ThisItem.Value.LookupId
いいねした人のメールアドレス
ThisItem.Value.Email
いいねをすでにしている場合は塗りつぶしの👍、
まだの場合は空白の👍を
表示させる場合は以下のようになります。
If( CountIf( Table(ThisItem.Value.fields.LikedBy), ThisRecord.Value.Email = User().Email ) > 0, Icon.ThumbsUpFilled, Icon.ThumbsUp )
いいね列を更新する
いいね列を更新するには、SharePoint REST APIを利用する必要があります。
よってここからはPower Automateで実施します。
フローの全体像はこんな感じ。
ちなみにリストIDはベタ打ちでもよく、リストIDをベタ打ちするのであれば、サイトIDは不要なのでわざわざAPIで取得する必要はないです。
なのでここは説明は抜きで設定値だけ記載しますね。
サイトIDの取得
サイトのアドレス
リストのあるサイト
方法
GET
_api/v2.1/sites/[your-domain]
リストIDの取得
サイトのアドレス
リストのあるサイト
方法
GET
_api/v2.1/sites/@{body('SharePoint_に_HTTP_要求を送信します(site-id)')?['id']}/lists/{list-name}/
ここで取得できたリストIDとPower Appsから渡された情報を用いて、いいね列の更新を行います。
ちなみにPower Appsからは、更新するレコードのIDと、"いいね"なのか"いいねの取り消し"なのかを受け取ります。
これらの情報を使って以下の設定でアクションを実行させます。
サイトのアドレス
リストのあるサイト
方法
POST
_api/Microsoft.Office.Server.ReputationModel.Reputation.SetLike(listID=@a1,itemID=@a2,like=@a3)?@a1='@{body('SharePoint_に_HTTP_要求を送信します(list-id)')?['id']}'&@a2='@{triggerBody()['number']}'&@a3=@{if( triggerBody()['boolean'], 'true', 'false' )}
注意点として、Power Appsから受け取ったboolean値をそのまま設定しないでください。
これをそのまま設定してしまいますと、"True"や"False"が設定され、APIの実行に失敗します。
あとはPower AppsからPower Automateを呼び出すだけですね。
UpdateLikeFields.Run( Value(ThisItem.Value.fields.id), Self.Icon = Icon.ThumbsUp ); Select(iniBtn)
idは数値型で渡したいので、Value関数で型を数値と明示しています。
アイコンをいいね済みか否かで変化させているのでそれを利用し、いいねをまだしていない場合はtrue
を、いいね済みの場合はfalse
が渡されるようにしています。
多分このやり方がリスト変な操作しなくていいかな?
ただ見てもらえればわかる通り、そこそこの知識が必要なので運用はちょっと注意かもですね。
評価機能を用いず既定列だけで実装する
一応前にまとめていたので紹介。
多分この記事に辿り着いた皆さんがやりたいのこれじゃないと思う。。。
一応これでもできますが、まぁめんどいですね。
おわりに
前回の記事でコメントしてくださった方、回答が遅くなってしまい申し訳ありません。。。
あともう一点質問受けてますが、そちらは私の環境では今のところ再現できないのでまたわかったら追記しますー