2022年12月22日 (木)

Microsoft Graph Pages API: Power Apps (+Power Automate) から SharePoint ページを作成しよう

この記事は Microsoft Power Automate Advent Calendar 2022 に参加しています。2022/12/22 の分です。

🎄❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️❄️🎅

今回は開発者寄りの記事です。難易度は高めですが、年末年始の時間のある時に是非チャレンジしてみてくださいね。

これまでも Microsoft Graph API には SharePoint ページを操作するための API (beta バージョンのみ) がありましたが、 2022年11月末に新しいペーター版がリリースされました。これによりこれまでできなかった、SharePoint モダンページおよびニュース投稿の取得、作成、管理ができます。既存の pages beta API は新しい API に置き換わることになります。

私にとっては待望の API で、これが正式にリリースされて充実してくると色々とできることが増えます。

2023年4月末までにGAが予定されています。公式情報は下記を参照してください。

🔗Announcing the new SharePoint Pages API in Microsoft Graph - Microsoft 365 Developer Blog

さて、今回はこの Graph API (Pages API) を使って、以前から試してみたかった Power Apps から SharePoint ページを作成して発行してみることにします。

ただし、細かいパラメータオプションや JSON などは1つのブログに収まりきる量ではないので、今回は「読者の方が頑張って自分でちょっと試してみることができる」よう情報を簡素化にしています。ヒントとなる情報はちりばめておきますので、詳細はご自身で頑張って学習を進めてみてください。

あとは弊社のオフィスアイ ラーニング ポータル(有料サービス) には、情報を整理して公開しています。ご興味があればこちらもどうぞ。

これができると定型的なページ作成が Power Apps や Power Automate で対応できるなぁという話です。

今回のベータ版リリースの範囲

このリリースでは次の機能が提供されます。

  • ページおよびニュースコンテンツの取得
  • ページおよびニュース投稿の作成
  • ページおよびニュース投稿の削除
  • ページの一覧の取得
  • ページおよびニュースの投稿の発行

今回のスコープ外は次の通りとなっているので注意しましょう。

  • 既存ページの編集
  • ニュースリンクの生成

上記ビデオでは想定されるシナリオ例としては次のような内容を取り上げていました。

想定される利用シナリオ

シナリオ1

組織の CDN や Microsoft ストック画像、パブリックリソースにある画像とともにUX 内でページを作成して(要はどこからでも参照できる画像を使うこと)、ページの JSON を取得して、それをもとに異なるサイト間やテナント間で同じページを作成する

シナリオ2

すべてのページの一覧を取得し、特定のプロパティでフィルターしたあとでそれらのページを一括削除する

Graph エクスプローラーを使ってサイトIDを取得する

Graph API を使うにはページを作成する先のサイトのIDを取得する必要があります。Graph エクスプローラーの基本的な使い方は下記のリンク先を参照してください。

🔗 Graph エクスプローラーを使用して Microsoft Graph API を試す - Microsoft Graph | Microsoft Learn

まず Graphエクスプローラーにアクセスします。

🔗 Graph Explorer | Try Microsoft Graph APIs - Microsoft Graph

右側の顔写真のところをクリックして、Microsoft 365 アカウントでサインインします。 

20221222_165906

始めてアクセスするときには Permissins requested のウィンドウが表示されますが、Accept ボタンをクリックします。

20221222_170127

クエリを実行するために、次の操作をします。

  1. GET アクセスになっていることを確認する
  2. beta を指定する
  3. エンドポイントを指定する
  4. Run query ボタンをクリックする

3 のエンドポイントですが、サイトのIDを取得するには次のように指定します。

[ルートのサイトコレクションの場合]

https://graph.microsoft.com/beta/sites/root

[ルートのサイトコレクション以外]

https://graph.microsoft.com/beta/sites/root:<サイトの相対パス>

サイトの相対パスは /sites や /teams から始まるパスです。私の使っているサイトは相対パスが /sites/Labo-GraphAPI であるため、これを指定します。

20221222_170406

クエリを実行した結果取得できる id をメモしておきます。後で Power Automate のフローから利用します。私のサイトの ID だと「

officeilearning.sharepoint.com,5de63e83-091f-42b2-90a2-2aeefe4ab9d7,342f6370-e776-4677-bf1e-dcc2d94985ed

」だということがわかります。

Power Apps のアプリを用意する

記事を投稿するためのアプリを用意します。この例ではキャンバスアプリでタブレットレイアウトで作成しています。

20221222_171539

類似したアプリを作ってみてください。必要な項目は次の通りです。

  • ページのタイトル
  • ページのファイル名

あとは、ページ内に書き込みたい内容をこの例では次の項目をリッチテキストのコントロールで用意しています。

  • 本文
  • 備考

作りたいページのイメージを確認しよう

作りたいページのイメージは次の通りです。今回はタイトル領域の設定やクイックリンク Webパーツ、画像Webパーツは固定で、そのほかを適宜差し替えてページを新規に作り発行します。利用する画像はストック画像であるため、どのテナントでも共通して利用できます。

20221222_171949

Power Automate フローを作る 

では Power Apps 側からフローを作成しましょう。この記事ではある程度 フローも作れることを想定しているので、手順はさほど丁寧には説明しませんのであしからず。。。(ちなみに、弊社でも Power Automate のフローの研修もやってますので、もしよければそういったものもご利用ください)。

ということで、[フローを新規作成する]をクリックします。

20221222_172208

トリガーを PowerApps (V2) に差し替え、次のように指定します。フロー名も任意に指定しておきましょう。

20221222_172706

次のステップでは変数を用意します。この変数には後ほど作成したページのIDを格納します。

20221222_172846

次のアクションに Office 365 Group コネクターの HTTP要求の送信アクションを追加します。これで Graph API を呼び出します。

URI には先ほど取得したサイトのIDを使って次のように指定します。

https://graph.microsoft.com/beta/sites/<サイトのID>/pages

メソッドは POST を指定しましょう。

20221222_173005

さて、問題が本文です。ここに指定するJSONがページ情報を決めることになります。詳しい話は色々と盛りだくさんにあるのですが、今回は、私が用意したソースを写経してみてください。下記の通りです。


     {
        "name": ".aspx",
        "title": "",
        "pageLayout": "article",
        "thumbnailWebUrl": "https://cdn.hubblecontent.osi.office.net/m365content/publish/4785e3b9-c5d0-4fac-813b-8cbc5e744eb4/thumbnails/large.jpg?file=dv735012.jpg",
        "promotionKind": "page",
        "showComments": true,
        "showRecommendedPages": true,
        "titleArea": {
            "enableGradientEffect": true,
            "imageWebUrl": "https://cdn.hubblecontent.osi.office.net/m365content/publish/4785e3b9-c5d0-4fac-813b-8cbc5e744eb4/dv735012.jpg",
            "layout": "colorBlock",
            "showAuthor": false,
            "showPublishedDate": true,
            "showTextBlockAboveTitle": true,
            "textAboveTitle": "Advent Calendar 2022",
            "textAlignment": "left",
            "imageSourceType": 2,
            "title": "Colone Page - 1",
            "imgHeight": 1360,
            "imgWidth": 2048,
            "translateX": 49.26108374384236,
            "translateY": 37.77777777777778,
            "hasTitleBeenCommitted": true,
            "serverProcessedContent": {
                "htmlStrings": [],
                "searchablePlainTexts": [],
                "links": [],
                "imageSources": [
                    {
                        "key": "imageSource",
                        "value": "https://cdn.hubblecontent.osi.office.net/m365content/publish/4785e3b9-c5d0-4fac-813b-8cbc5e744eb4/dv735012.jpg"
                    }
                ],
                "customMetadata": [
                    {
                        "key": "imageSource",
                        "value": {
                            "width": 2048,
                            "height": 1360
                        }
                    }
                ]
            }
        },
        "canvasLayout": {
            "horizontalSections": [
                {
                    "layout": "oneThirdRightColumn",
                    "id": "1",
                    "emphasis": "none",
                    "columns": [
                        {
                            "id": "1",
                            "width": 8,
                            "webparts": [
                                {
                                    "@odata.type": "#microsoft.graph.textWebPart",
                                    "innerHtml": "Body"
                                }
                            ]
                        },
                        {
                            "id": "2",
                            "width": 4,
                            "webparts": [
                                {
                                    "@odata.type": "#microsoft.graph.standardWebPart",
                                    "webPartType": "c70391ea-0b10-4ee9-b2b4-006d3fcad0cd",
                                    "data": {
                                        "audiences": [],
                                        "dataVersion": "2.2",
                                        "description": "アイコン、画像、対象ユーザーのターゲット設定のオプションを使用して、ドキュメント、画像、ビデオなどのコンテンツへのリンクのコレクションをさまざまなレイアウトで表示します。",
                                        "title": "クイック リンク",
                                        "properties": {
                                            "isMigrated": true,
                                            "layoutId": "CompactCard",
                                            "shouldShowThumbnail": true,
                                            "imageWidth": 100,
                                            "hideWebPartWhenEmpty": true,
                                            "dataProviderId": "QuickLinks",                                         
                                            "items@odata.type": "#Collection(graph.Json)",
                                            "items": [
                                                {
                                                    "thumbnailType": 3,
                                                    "id": 1,
                                                    "description": "",
                                                    "altText": "",
                                                    "rawPreviewImageMinCanvasWidth": 32767,
                                                    "sourceItem": {
                                                        "@odata.type": "#graph.Json",
                                                        "itemType": 2,
                                                        "fileExtension": "",
                                                        "progId": ""
                                                    }
                                                }
                                            ],
                                            "listLayoutOptions": {
                                                "@odata.type": "#graph.Json",
                                                "showDescription": false,
                                                "showIcon": true
                                            },
                                            "buttonLayoutOptions": {
                                                "@odata.type": "#graph.Json",
                                                "showDescription": false,
                                                "buttonTreatment": 2,
                                                "iconPositionType": 2,
                                                "textAlignmentVertical": 2,
                                                "textAlignmentHorizontal": 2,
                                                "linesOfText": 2
                                            },
                                            "waffleLayoutOptions": {
                                                "@odata.type": "#graph.Json",
                                                "iconSize": 1,
                                                "onlyShowThumbnail": false
                                            }
                                        },
                                        "serverProcessedContent": {
                                            "htmlStrings": [],
                                            "searchablePlainTexts": [
                                                {
                                                    "key": "title",
                                                    "value": "参考"
                                                },
                                                {
                                                    "key": "items[0].title",
                                                    "value": "ペンギン - Wikipedia"
                                                }
                                            ],
                                            "links": [
                                                {
                                                    "key": "baseUrl",
                                                    "value": "/sites/Labo-GraphAPI"
                                                },
                                                {
                                                    "key": "items[0].sourceItem.url",
                                                    "value": "https://ja.wikipedia.org/wiki/%e3%83%9a%e3%83%b3%e3%82%ae%e3%83%b3"
                                                }
                                            ],
                                            "imageSources": [
                                                {
                                                    "key": "items[0].rawPreviewImageUrl",
                                                    "value": "https://upload.wikimedia.org/wikipedia/commons/thumb/b/b1/African_Penguin_at_Boulders_Beach_1.jpg/1200px-African_Penguin_at_Boulders_Beach_1.jpg"
                                                }
                                            ],
                                            "componentDependencies": [
                                                {
                                                    "key": "layoutComponentId",
                                                    "value": "706e33c8-af37-4e7b-9d22-6e5694d92a6f"
                                                }
                                            ],
                                            "customMetadata": [
                                                {
                                                    "key": "items[0].rawPreviewImageUrl",
                                                    "value": {
                                                        "fixedwidth": "100",
                                                        "mincanvaswidth": "32767"
                                                    }
                                                }
                                            ]
                                        }
                                    }
                                },
                                {
                                    "@odata.type": "#microsoft.graph.standardWebPart",
                                    "webPartType": "d1d91016-032f-456d-98a4-721247c305e8",
                                    "data": {
                                        "audiences": [],
                                        "dataVersion": "1.11",
                                        "description": "画像、ピクチャ、または写真をテキストを重ねたページに追加し、画像のトリミングやサイズ変更を行うことができます。",
                                        "title": "画像",
                                        "properties": {
                                            "imageSourceType": 2,
                                            "captionText": "",
                                            "altText": "",
                                            "linkUrl": "",
                                            "overlayText": "",
                                            "fileName": "崩落する氷山.jpg",
                                            "imgWidth": 3015,
                                            "imgHeight": 2410,
                                            "alignment": "Center",
                                            "fixAspectRatio": false,
                                            "overlayTextStyles": {
                                                "@odata.type": "#graph.Json",
                                                "textColor": "light",
                                                "isBold": false,
                                                "isItalic": false,
                                                "textBoxColor": "dark",
                                                "textBoxOpacity": 0.54,
                                                "overlayColor": "light",
                                                "overlayTransparency": 0
                                            }
                                        },
                                        "serverProcessedContent": {
                                            "htmlStrings": [],
                                            "searchablePlainTexts": [],
                                            "links": [],
                                            "imageSources": [
                                                {
                                                    "key": "imageSource",
                                                    "value": "https://cdn.hubblecontent.osi.office.net/m365content/publish/e452fe45-b705-4a5a-aebd-e92f74c2553f/1152450154.jpg"
                                                }
                                            ],
                                            "customMetadata": [
                                                {
                                                    "key": "imageSource",
                                                    "value": {
                                                        "width": "3015",
                                                        "height": "2410"
                                                    }
                                                }
                                            ]
                                        }
                                    }
                                }
                            ]
                        }
                    ]
                },
                {
                    "layout": "oneColumn",
                    "id": "2",
                    "emphasis": "neutral",
                    "columns": [
                        {
                            "id": "1",
                            "width": 12, 
                            "webparts":[
                                {
                                    "@odata.type": "#microsoft.graph.textWebPart",
                                    "innerHtml": "Notes"
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    }

name と title プロパティに動的なコンテンツを指定します。

20221222_180124

次の図に示す"innerHtml"の値を Body から動的コンテンツ置き換えます。

20221222_174733_3

クイックリンク Webパーツの部分のサイトの相対パスを自身のサイトのものに書き換えます。

20221222_174554_3

下の方にある "innerHtml" のプロパティの値を Notes から動的コンテンツに書き換えます。

20221222_174923_2

次のステップとして JSON の解析アクションを追加します。コンテンツに指定する「本文」はひとつ前のステップの出力結果です。20221222_175035

スキーマは下記の内容をコピーして貼り付けましょう。


{
    "type": "object",
    "properties": {
        "@@odata.context": {
            "type": "string"
        },
        "@@odata.etag": {
            "type": "string"
        },
        "eTag": {
            "type": "string"
        },
        "id": {
            "type": "string"
        },
        "lastModifiedDateTime": {
            "type": "string"
        },
        "name": {
            "type": "string"
        },
        "webUrl": {
            "type": "string"
        },
        "title": {
            "type": "string"
        },
        "pageLayout": {
            "type": "string"
        },
        "thumbnailWebUrl": {
            "type": "string"
        },
        "promotionKind": {
            "type": "string"
        },
        "showComments": {
            "type": "boolean"
        },
        "showRecommendedPages": {
            "type": "boolean"
        },
        "createdBy": {
            "type": "object",
            "properties": {
                "user": {
                    "type": "object",
                    "properties": {
                        "displayName": {
                            "type": "string"
                        },
                        "email": {
                            "type": "string"
                        }
                    }
                }
            }
        },
        "lastModifiedBy": {
            "type": "object",
            "properties": {
                "user": {
                    "type": "object",
                    "properties": {
                        "displayName": {
                            "type": "string"
                        },
                        "email": {
                            "type": "string"
                        }
                    }
                }
            }
        },
        "parentReference": {
            "type": "object",
            "properties": {
                "siteId": {
                    "type": "string"
                }
            }
        },
        "contentType": {
            "type": "object",
            "properties": {
                "id": {
                    "type": "string"
                },
                "name": {
                    "type": "string"
                }
            }
        },
        "publishingState": {
            "type": "object",
            "properties": {
                "level": {
                    "type": "string"
                },
                "versionId": {
                    "type": "string"
                }
            }
        },
        "reactions": {
            "type": "object",
            "properties": {}
        },
        "titleArea": {
            "type": "object",
            "properties": {
                "enableGradientEffect": {
                    "type": "boolean"
                },
                "imageWebUrl": {
                    "type": "string"
                },
                "layout": {
                    "type": "string"
                },
                "showAuthor": {
                    "type": "boolean"
                },
                "showPublishedDate": {
                    "type": "boolean"
                },
                "showTextBlockAboveTitle": {
                    "type": "boolean"
                },
                "textAboveTitle": {
                    "type": "string"
                },
                "textAlignment": {
                    "type": "string"
                },
                "title": {
                    "type": "string"
                },
                "authors@odata.type": {
                    "type": "string"
                },
                "authors": {
                    "type": "array"
                },
                "authorByline@odata.type": {
                    "type": "string"
                },
                "authorByline": {
                    "type": "array"
                },
                "imageSourceType": {
                    "type": "integer"
                },
                "imgHeight": {
                    "type": "integer"
                },
                "imgWidth": {
                    "type": "integer"
                },
                "translateX": {
                    "type": "number"
                },
                "translateY": {
                    "type": "number"
                },
                "hasTitleBeenCommitted": {
                    "type": "boolean"
                },
                "serverProcessedContent": {
                    "type": "object",
                    "properties": {
                        "htmlStrings": {
                            "type": "array"
                        },
                        "searchablePlainTexts": {
                            "type": "array"
                        },
                        "links": {
                            "type": "array"
                        },
                        "imageSources": {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "properties": {
                                    "key": {
                                        "type": "string"
                                    },
                                    "value": {
                                        "type": "string"
                                    }
                                },
                                "required": [
                                    "key",
                                    "value"
                                ]
                            }
                        },
                        "customMetadata": {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "properties": {
                                    "key": {
                                        "type": "string"
                                    },
                                    "value": {
                                        "type": "object",
                                        "properties": {
                                            "width": {
                                                "type": "integer"
                                            },
                                            "height": {
                                                "type": "integer"
                                            }
                                        }
                                    }
                                },
                                "required": [
                                    "key",
                                    "value"
                                ]
                            }
                        }
                    }
                }
            }
        }
    }
}

次のステップで pageId 変数に JSON解析の出力から id を設定します。20221222_175224_2

次のステップで再び Office 365 Group コネクターの HTTP要求アクションを追加します。これでページを発行します。URIは次の通りです。

https://graph.microsoft.com/beta/sites/<サイトのID>/pages/<ページのID>/publish

20221222_175329_2

最後に Power Apps コネクターの応答アクションを追加しておきます。20221222_175555_2

Power Apps からフローを呼び出す

Power Apps アプリ内に用意しておいたボタンコントロールからフローを呼び出します。OnSelect プロパティには例えば次のように指定します。

UpdateContext({Result:'ページ作成(PagesAPIprev)'.Run(TextInput_Page_Title.Text,TextInput_Page_Name.Text,
RichTextEditor_Body.HtmlText,RichTextEditor_Notes.HtmlText).response});
Notify(Result,NotificationType.Success)

20221222_182032

動作を確認する

アプリをプレビュー実行して動作を確認しましょう。

それでは、Happy Holidays !!

コメント