4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Low-Code/No-CodeAdvent Calendar 2018

Day 9

PowerAppsのTimerを使った繰り返し処理でYammerのメッセージを取得する

Last updated at Posted at 2018-12-08

はじめに

この記事はノンプログラミングでアプリが作成できるMicrosoftのPowerAppsを使って、同じくMicrosoftの企業向けSNSであるYammerの特定のグループからメッセージを取得しよう、という内容です。
各コントロールの設定のみ説明し、接続やコントロールの配置などの手順については省いています。ご了承ください。

え、20件しか取れないの?

同僚から「Yammerの参加者別に『いいね!』された数を集計出来ないかな?」と相談されたので、そんなの簡単じゃん、とPowerAppsでチョチョっと作ったのですが、どうも数が合わない。調べてみると同じ悩みの人がいて、YammerのAPIでは1回の取得で20メッセージまでしか取れず、呼び出し頻度も30秒に10回以内であることがわかりました。こちらの記事

では3秒待って繰り返せば良い、ということになりますが、困ったことに、PowerAppsには繰り返しのロジックがありません。
普通ならここでMicrosoft Flowに乗り換えるのでしょうが、なんか悔しくて、さらに調べて試してみました。

反復のアイディア

タイマーを使う、という発想

今度はPowerAppsとloopをキーワードに検索してみます。すると**こんな記事**に出合いました。
こちらで質問しているColleenさん、途中で「Timerコントロールを使ってほぼWhileと同じ処理が出来たよ、ちょっと遅いけどね」と書いています。遅くていいんです、どうせ3秒待つんだから。

ではどのように設定するのか

ColleenさんはRe-stateと書いています。本当に状態回復の意味で書いたのかも知れませんが、私はRestartじゃね?、と解釈しました。処理開始でタイマースタート、最初に処理を実行したら3秒待って、Restart。終了条件が来たらRestartをfalseに。いけそうですね。Timerコントロールの設定的には以下のようなものです。

プロパティ 設定値 コメント
Start bool値 trueでタイマースタート
OnTimerStart 処理 メッセージ取得処理を入れる
Duration 3000 3秒待つ
Restart bool値 trueで繰り返し

実装してみよう

実装にあたっては、わかりやすくするために以下の要件としました。

  • ドロップダウンリストでYammerグループを選択後、ボタンを押して取得開始
  • いいねの集計でなく、単にメッセージを取得してギャラリーで内容を表示します(最後でちょっと補足)
  • 取得処理では、最初の1回をボタンで処理した後、タイマーを起動します。そのためOnTimerEndに処理を入れます

まずは最終イメージ

これを作ります。投稿者IDを名前にしたい、とか、日本時間にしたい、とか、メッセージの順番が、なんてのは最後でちょっと補足。(肝心のメッセージが15件しか無い!後半までに水増ししておきます)
サンプル投稿は**こちらの記事**から引用しました。ありがとうございます。
コメント 2018-12-08 110900.jpg

Yammerコネクタ

使うコネクタはYammerのみです。接続すると関数が使えるようになります。使う関数は、上記の状態までなら以下の2つだけです。
詳しくはこちらを参照してください

関数 用途 パラメーター
Yammer.GetGroups() 自分が使えるグループを取得します 今回は設定しません
Yammer.GetMessagesInGroup(id,{older_than:message.id}) idで指定したグループのメッセージを取得します older_than: 指定したmessage.idより古いメッセージを取得

各コントロールの設定内容

1.ドロップダウン(最終イメージのDropdown1)

ここではitemsプロパティを設定するだけで、グループ名が表示されると思います。選択した結果のグループIDには、Dropdown1.Selected.idでアクセス出来ます。

プロパティ 設定値 コメント
Items Yammer.GetGroups() グループ名が表示されなければ、詳細設定のValueでfull_nameを選んでください

2.取得ボタン(最終イメージのButton1)

こちらも設定はOnSelectプロパティのみですが、設定値は結構長文になります。
処理の中心ですので、ひとつひとつ説明して行きますね。

Button1.Onselect
UpdateContext({timerStart:false,pageCount:1,messageRead:0,oldestMessageId:0,totalMessage:0});
ClearCollect(workCollection,Yammer.GetMessagesInGroup(Dropdown1.Selected.id).messages);
ClearCollect(MessagesInGroup,workCollection);
UpdateContext({messageRead:Count(workCollection.id),oldestMessageId:Last(workCollection).id});
UpdateContext({totalMessage:messageRead});
If(messageRead=20,UpdateContext({timerStart:true,pageCount:2}),UpdateContext({pageCount:0}))

2-1.変数を準備

UpdateContext({timerStart:false,pageCount:1,messageRead:0,oldestMessageId:0,totalMessage:0})

変数名 用途
timerStart タイマーを開始する時、および繰り返しする場合にtrueを入れます
pageCount 取得回数をカウントして、終わると0をセットします。Label1でメッセージを出しわけるために使っています
messageRead 取得毎に返されたメッセージ数を保持します。20未満なら最終ページと判断してtimerStartをfalseにします
oldestMessageId 取得した中で一番古いメッセージのIDを保持します。次回の取得ではそれより古いメッセージを対象にします
totalMessage 読み取ったメッセージ総数を保持します

2-2.Yammerからメッセージを取得

ClearCollect(workCollection,Yammer.GetMessagesInGroup(Dropdown1.Selected.id).messages)

Yammerからメッセージを取得して一時的なコレクションworkCollectionにセットします。投稿内容自体はさらに内側のmessagesというレコード(構造体?)の中にありますので、ひと皮剥く感じで戻り値に.messagesを付けています。

2-3.取得したメッセージを蓄積

ClearCollect(MessagesInGroup,workCollection)

コレクションMessageInGroupにメッセージを蓄積します。ここでは初回なのでClearCollectを使っています。

2-4.取得後の変数の更新

UpdateContext({messageRead:Count(workCollection.id),oldestMessageId:Last(workCollection).id});
UpdateContext({totalMessage:messageRead})

変数名 設定値 コメント
messageRead Count(workCollection.id) このidはメッセージ固有のidで、何メッセージ取ってきたのか数えています。後段で20未満ならtimerStartをfalseにしています
oldestMessageId Last(workCollection).id Yammerは新しい順にメッセージを取ってきているようなので、Lastレコードを選んでそのidをセットしています。次回の取得ではそれより古いメッセージを対象にします
totalMessage messageRead 読み込んだ総メッセージ数ですが、ここでは初回なのでmessageReadを直接セットしています

2-5.繰り返すかどうかの判断と変数の更新

If(messageRead=20,UpdateContext({timerStart:true,pageCount:2}),UpdateContext({pageCount:0}))

取得したメッセージが20であれば、残りがあるかも知れないため繰り返す必要があります。
ここでは以降タイマーによる処理に移すために、timerStartをtrueにしpageCountも進めています。20未満であればこれで終わりですので、timerStartをtrueにすることなく、表示を変更するためにpageCountを0にしています。

3.タイマー(最終イメージのTimer1)

タイマーはStartにtrueがセットされると動作を開始し、Durationにセットされたミリ秒だけ処理を待ち、その後OnTimerEndに指定された処理を実行します。Restartがtrueの間は繰り返し、falseになると終了します。

プロパティ 設定値 コメント
Start startTimer trueで始まり、終了させる時にfalseをセットします
Duration 5000 余裕をもって5秒待ちます
OnTimerEnd 処理 1回目の処理とほぼ同じですが、この後説明します
Restart startTimer trueで始まり、終了させる時にfalseをセットします

OnTimerEndプロパティに設定する処理

ボタンに設定した処理からの変更点は以下の太字の部分です。

ClearCollect(workCollection,Yammer.GetMessagesInGroup(Dropdown1.Selected.id,{older_than:oldestMessageId}).messages);
Collect(MessagesInGroup,workCollection);
UpdateContext({messageRead:Count(workCollection.id),oldestMessageId:Last(workCollection).id});
UpdateContext({totalMessage:totalMessage+messageRead});
If(messageRead=20,UpdateContext({pageCount:pageCount+1}),UpdateContext({timerStart:false,pageCount:0}))

  • 取得済のメッセージを除くために、older_than:というオプションを追加しています。
  • メッセージの蓄積については2回目以降なので、ClearCollectではなくCollectを使っています。
  • totalMessage、pageCountの計算方法を汎用的にしています。
  • 取得メッセージ数が20に満たない場合は最終ページなのでtimerStartをfalseにして繰り返しを終了します。

4.ギャラリー(最終イメージのGallery1)

ギャラリーには蓄積したメッセージを表示しましょう。セットするのはデータソースとレイアウト、データ項目です。画像入りのレイアウトから変更したので、コントロール名の後ろに2が付いたりしています。

プロパティ 設定値 コメント
Items MessageInGroup 蓄積したメッセージを対象にします
コントロール名 設定値 コメント
Body1 ThisItem.body.plain 投稿内容です。タグ付きで格納されていますが、plain形式で表示します
SubTitile2 ThisItem.created_at 投稿日時です。UTCで表示されています
Title2 ThisItem.sender_id 投稿者の内部ID番号です。

こんな感じ。
コメント 2018-12-08 181043.jpg

5.ラベル(最終イメージのLabel1)

処理の繰り返しが入ると終了までに時間がかかるので、ラベルで状態を表示しています。設定はTextプロパティひとつです。

プロパティ 設定値 コメント
Text If(pageCount>0,"抽出しています..." & totalMessage,If(pageCount=0,"抽出が終わりました..." & totalMessage & "メッセージ","グループを選んでボタンを押してください"))

動かしてみよう

最後に動作確認しましょう。
20メッセージより少ないグループを選んでボタンを押すと数秒で終了します。20メッセージ以上あるグループでは、20メッセージの表示とともにタイマーが動き始め、5秒後に処理が繰り返されることがわかります。
追加のサンプル投稿は**こちらの記事**から引用しました。ありがとうございます。
timer.jpg
コメント 2018-12-08 193921.jpg

最後に

わかってみれば簡単なTimerを使った繰り返しワザ、如何でしたでしょうか。私のニーズにはバッチリでした。
最後にいくつか見た目の改善をしましょう。

投稿者を名前で表示したい!

Title2コントロールのTextプロパティを以下のように変更します。

変更前 変更後
ThisItem.sender_id Yammer.GetUserDetailsById(ThisItem.sender_id).full_name

投稿日時を日本時間にしたい!

SubTitle2コントロールのTextプロパティを以下のように変更します。

変更前 変更後
ThisItem.created_at DateTimeValue(ThisItem.created_at)

メッセージを古い順にしたい!

ギャラリーのItemsプロパティを以下のように変更します。

変更前 変更後
MessagesInGroup SortByColumns(MessagesInGroup,"created_at",Ascending)

ところで「いいね!」のカウントどうするの?

説明しているとまだまだ長くなってしまいますので、関数だけ。

ClearCollect(MessagesByUser,GroupBy(MessagesInGroup,"sender_id","OtherColumns"));
ClearCollect(LikesByUser,SortByColumns(AddColumns(MessagesByUser,"MessageCount",Count(OtherColumns.id),"LikeCount",Sum(OtherColumns,liked_by.count)),"LikeCount",Descending))

それでは、良いお年をお迎えください。

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?