LoginSignup
3
3

Microsoft Graph API for SharePoint Pagesが一般公開されたので、Power Automateで試してみる

Posted at

はじめに

先日Twitterで、こちらの投稿を見かけました。

Microsoft Graph API for SharePoint Pagesが一般公開!とのことで、
SharePointの投稿作成が捗るのでは!と思い、さっそくPower Automateで試してみました。

今回試したこと

  1. サイトのページの取得
  2. ページの投稿
  3. 特定のページの取得
  4. ページの削除
  5. ページの編集

上記のシナリオを試しています。
Micorosoft learnの基本的なシナリオの検証結果です。

手っ取り早く試したい方はGraph Explorerがおススメです。

検証に当たり

Graph APIは自分自身チャレンジした経験が浅く、
また経験上、Microsoft Entra IDでアプリの登録をして…といった準備は実装までに、
かなり時間がかかる印象を抱きました。

そこで!今回はSharePointコネクタの既存のアクションでできないかトライしました。

今回の記事ではSharePoint に HTTP 要求を送信アクションをメインで使用しています。

SharePoint に HTTP 要求を送信アクションでGraph API

SharePoint に HTTP 要求を送信アクションでGraph APIを使う上で、下記のサイトを参考にさせていただきました🙇

いつも大変お世話になっております。
Graph APIを実行するためのアクションは、URIを下記のように設定すると実行できるようです。

Graph APIをSharePointコネクタで呼び出すときの指定
_api/v2.1/sites

と記載することで実行できました。
なぜv2.1🧐という部分は、下記の記事を紹介します。

紹介した記事に下記の記載があります。

The use of Microsoft Graph http requests in Power Automate is currently less documented since it is relatively newer.

Method 2.0 or 2.1 HTTP Request for Site Collection and Site Id Information - Sharepoint Site Collection Id and Site Web Id Information using HTTP Request Uri _api/Site _api/Web or _api/v2.1

本件の操作に関するドキュメントは少ないです。
運用で実装される際は、その点を鑑みてご活用ください。

Graph APIの記法で実施するメリットは、非常に記載がシンプルになります。
検証結果で内容をご確認ください。

1. サイトのページの取得

指定したSharePointサイトの全ページを取得します。

image.png

Method - GET

URI
_api/v2.1/sites/{Host名}/pages

戻り値のサンプル
{
    "@odata.context": "https://hogehoge.sharepoint.com/sites/SharePointSiteName/_api/v2.1/$metadata#sites('hogehoge.sharepoint.com')/pages",
    "value": [
      {
        "@odata.type": "#oneDrive.page",
        "@odata.etag": "\"{D10007AD-ACE4-4144-A13A-E601789BCE94},3\"",
        "createdDateTime": "2024-04-26T14:58:47Z",
        "eTag": "\"{D10007AD-ACE4-4144-A13A-E601789BCE94},3\"",
        "id": "d10007ad-ace4-4144-a13a-e601789bce94",
        "lastModifiedDateTime": "2024-04-26T14:58:47Z",
        "name": "20240426145845.aspx",
        "webUrl": "https://hogehoge.sharepoint.com/sites/SharePointSiteName/SitePages/20240426145845.aspx",
        "title": "test",
        "pageLayout": "article",
        "thumbnailWebUrl": "https://media.akamai.odsp.cdn.office.net/hogehoge.sharepoint.com/_layouts/15/images/sitepagethumbnail.png",
        "promotionKind": "page",
        "showComments": true,
        "showRecommendedPages": false,
        "createdBy": {
          "user": {
            "displayName": "出戻り ガツオ",
            "email": "Mail.onmicrosoft.com"
          }
        },
        "lastModifiedBy": {
          "user": {
            "displayName": "出戻り ガツオ",
            "email": "Mail.onmicrosoft.com"
          }
        },
        "parentReference": {
          "listId": "fccd0142-da92-407f-b8ac-f42356cb2b9e",
          "siteId": "3789813c-5048-4aa0-b130-cfa78b57b219"
        },
        "contentType": {
          "id": "0x0101009D1CB255DA76424F860D91F20E6C41180060E80DAACC226D47992993F04DAFA7E4",
          "name": "サイト ページ"
        },
        "publishingState": {
          "level": "checkout",
          "versionId": "0.1",
          "checkedOutBy": {
            "user": {
              "displayName": "出戻り ガツオ",
              "email": "Mail.onmicrosoft.com"
            }
          }
        },
        "reactions": {},
        "titleArea": {
          "enableGradientEffect": true,
          "imageWebUrl": "https://cdn.hubblecontent.osi.office.net/m365content/publish/005292d6-9dcc-4fc5-b50b-b2d0383a411b/image.jpg",
          "layout": "colorBlock",
          "showAuthor": true,
          "showPublishedDate": false,
          "showTextBlockAboveTitle": false,
          "textAboveTitle": "TEXT ABOVE TITLE",
          "textAlignment": "left",
          "title": "sample1",
          "authorByline@odata.type": "#Collection(String)",
          "authorByline": [
            "i:0#.f|membership|Mail.onmicrosoft.com"
          ],
          "imageSourceType": 2,
          "serverProcessedContent": {
            "imageSources": [
              {
                "key": "imageSource",
                "value": "https://cdn.hubblecontent.osi.office.net/m365content/publish/005292d6-9dcc-4fc5-b50b-b2d0383a411b/image.jpg"
              }
            ]
          },
          "authors@odata.type": "#Collection(graph.Json)",
          "authors": [
            {
              "email": "Mail.onmicrosoft.com",
              "upn": "Mail.onmicrosoft.com",
              "id": "i:0#.f|membership|Mail.onmicrosoft.com",
              "name": "出戻り ガツオ"
            }
          ]
        }
      }
    ]
  }

上記は一部割愛していますが、投稿者やページのデザイン、ファイル名などが列挙されますね。
これだけの操作でページと付随する情報が取得できることは驚きです。

Host名は、hoge.sharepoint.comの部分です。
検証したところ、rootという文字列に置き換えても動作しました👍

2. ページの投稿

指定したSharePointサイトに新しいページを投稿します。
URIは、1. サイトのページの取得と一緒、メソッドをPOSTに変えてヘッダー、ボディを加えます。

image.png

Method - POST

ヘッダー
{
  "Content-Type": "application/json"
}
URI
_api/v2.1/sites/{Host名}/pages

ボディはMicrosoft learnのサンプルを使っています。

ボディ
{
  "@odata.type": "#microsoft.graph.sitePage",
  "name": "@{outputs('SitePage_Name')}",
  "title": "test",
  "pageLayout": "article",
  "showComments": true,
  "showRecommendedPages": false,
  "titleArea": {
    "enableGradientEffect": true,
    "imageWebUrl": "https://cdn.hubblecontent.osi.office.net/m365content/publish/005292d6-9dcc-4fc5-b50b-b2d0383a411b/image.jpg",
    "layout": "colorBlock",
    "showAuthor": true,
    "showPublishedDate": false,
    "showTextBlockAboveTitle": false,
    "textAboveTitle": "TEXT ABOVE TITLE",
    "textAlignment": "left",
    "imageSourceType": 2,
    "title": "sample1"
  },
  "canvasLayout": {
    "horizontalSections": [
      {
        "layout": "oneThirdRightColumn",
        "id": "1",
        "emphasis": "none",
        "columns": [
          {
            "id": "1",
            "width": 8,
            "webparts": [
              {
                "id": "6f9230af-2a98-4952-b205-9ede4f9ef548",
                "innerHtml": "<p><b>Hello!</b></p>"
              }
            ]
          },
          {
            "id": "2",
            "width": 4,
            "webparts": [
              {
                "id": "73d07dde-3474-4545-badb-f28ba239e0e1",
                "webPartType": "d1d91016-032f-456d-98a4-721247c305e8",
                "data": {
                  "dataVersion": "1.9",
                  "description": "Show an image on your page",
                  "title": "Image",
                  "properties": {
                    "imageSourceType": 2,
                    "altText": "",
                    "overlayText": "",
                    "siteid": "0264cabe-6b92-450a-b162-b0c3d54fe5e8",
                    "webid": "f3989670-cd37-4514-8ccb-0f7c2cbe5314",
                    "listid": "bdb41041-eb06-474e-ac29-87093386bb14",
                    "uniqueid": "d9f94b40-78ba-48d0-a39f-3cb23c2fe7eb",
                    "imgWidth": 4288,
                    "imgHeight": 2848,
                    "fixAspectRatio": false,
                    "captionText": "",
                    "alignment": "Center"
                  },
                  "serverProcessedContent": {
                    "imageSources": [
                      {
                        "key": "imageSource",
                        "value": "/_LAYOUTS/IMAGES/VISUALTEMPLATEIMAGE1.JPG"
                      }
                    ],
                    "customMetadata": [
                      {
                        "key": "imageSource",
                        "value": {
                          "siteid": "0264cabe-6b92-450a-b162-b0c3d54fe5e8",
                          "webid": "f3989670-cd37-4514-8ccb-0f7c2cbe5314",
                          "listid": "bdb41041-eb06-474e-ac29-87093386bb14",
                          "uniqueid": "d9f94b40-78ba-48d0-a39f-3cb23c2fe7eb",
                          "width": "4288",
                          "height": "2848"
                        }
                      }
                    ]
                  }
                }
              }
            ]
          }
        ]
      }
    ]
  }
}

なにが良いか、というと個人的に_api/sitepages/pages('ItemId')/savepageasdraftで実施するボディより、感覚的に見やすい印象。
savepageasdraftだと、このようになるので…。

savepageasdraftのボディ
{
    "__metadata": {
        "type": "SP.Publishing.SitePage"
    },
    "CanvasContent1": "[{\"emphasis\":{\"zoneEmphasis\":0},\"position\":{\"layoutIndex\":1,\"sectionFactor\":8,\"zoneIndex\":1,\"sectionIndex\":1,\"controlIndex\":1},\"addedFromPersistedData\":true,\"displayMode\":2,\"id\":\"6f9230af-2a98-4952-b205-9ede4f9ef548\",\"controlType\":4,\"editorType\":\"CKEditor\",\"modifiedByGraph\":{\"apiVersion\":\"Vroom\",\"lastModified\":1714143526},\"innerHTML\":\"<p><strong>Hello!</strong></p>\"},{\"emphasis\":{\"zoneEmphasis\":0},\"position\":{\"layoutIndex\":1,\"sectionFactor\":4,\"zoneIndex\":1,\"sectionIndex\":2,\"controlIndex\":1},\"addedFromPersistedData\":true,\"displayMode\":2,\"id\":\"73d07dde-3474-4545-badb-f28ba239e0e1\",\"controlType\":3,\"webPartId\":\"d1d91016-032f-456d-98a4-721247c305e8\",\"webPartData\":{\"id\":\"d1d91016-032f-456d-98a4-721247c305e8\",\"instanceId\":\"73d07dde-3474-4545-badb-f28ba239e0e1\",\"title\":\"Image\",\"description\":\"Show an image on your page\",\"audiences\":[],\"serverProcessedContent\":{\"htmlStrings\":{},\"searchablePlainTexts\":{},\"imageSources\":{\"imageSource\":\"/_LAYOUTS/IMAGES/VISUALTEMPLATEIMAGE1.JPG\"},\"links\":{},\"customMetadata\":{\"imageSource\":{\"width\":4288,\"height\":2848}}},\"dataVersion\":\"1.11\",\"properties\":{\"imageSourceType\":2,\"altText\":\"\",\"overlayText\":\"\",\"siteid\":\"0264cabe-6b92-450a-b162-b0c3d54fe5e8\",\"webid\":\"f3989670-cd37-4514-8ccb-0f7c2cbe5314\",\"listid\":\"bdb41041-eb06-474e-ac29-87093386bb14\",\"uniqueid\":\"d9f94b40-78ba-48d0-a39f-3cb23c2fe7eb\",\"imgWidth\":4288,\"imgHeight\":2848,\"fixAspectRatio\":false,\"captionText\":\"\",\"alignment\":\"Center\",\"overlayTextStyles\":{\"textColor\":\"light\",\"isBold\":false,\"isItalic\":false,\"textBoxColor\":\"dark\",\"textBoxOpacity\":0.54,\"overlayColor\":\"light\",\"overlayTransparency\":0},\"isOverlayTextVisible\":true},\"containsDynamicDataSource\":false},\"reservedHeight\":266,\"reservedWidth\":364},{\"controlType\":0,\"pageSettingsSlice\":{\"isDefaultDescription\":true,\"isDefaultThumbnail\":true,\"isSpellCheckEnabled\":true,\"globalRichTextStylingVersion\":0,\"rtePageSettings\":{\"contentVersion\":5},\"isEmailReady\":false}}]",
    "PageRenderingState": {
        "canvasState": {}
    },
    "LayoutWebpartsContent": "[{\"id\":\"cbe7b0a9-3504-44dd-a3a3-0e5cacd07788\",\"instanceId\":\"cbe7b0a9-3504-44dd-a3a3-0e5cacd07788\",\"title\":\"Title area\",\"description\":\"Title Region Description\",\"audiences\":[],\"serverProcessedContent\":{\"htmlStrings\":{},\"searchablePlainTexts\":{},\"imageSources\":{\"imageSource\":\"https://cdn.hubblecontent.osi.office.net/m365content/publish/005292d6-9dcc-4fc5-b50b-b2d0383a411b/image.jpg\"},\"links\":{},\"customMetadata\":{\"imageSource\":{}}},\"dataVersion\":\"1.4\",\"properties\":{\"title\":\"test\",\"topicHeader\":\"TEXT ABOVE TITLE\",\"textAlignment\":\"Left\",\"showTopicHeader\":false,\"showPublishDate\":false,\"layoutType\":\"ColorBlock\",\"enableGradientEffect\":true,\"authors\":[{\"email\":\"Mail@onmicrosoft.com\",\"upn\":\"Mail@onmicrosoft.com\",\"id\":\"i:0#.f|membership|Mail@onmicrosoft.com\",\"name\":\"出戻り ガツオ\"}],\"authorByline\":[\"i:0#.f|membership|Mail@onmicrosoft.com\"],\"imageSourceType\":2,\"isDecorative\":true},\"containsDynamicDataSource\":false,\"reservedHeight\":450}]",
    "AuthorByline": [
        "i:0#.f|membership|Mail@onmicrosoft.com"
    ],
    "TopicHeader": "TEXT ABOVE TITLE",
    "BannerImageUrl": "https://cdn.hubblecontent.osi.office.net/m365content/publish/005292d6-9dcc-4fc5-b50b-b2d0383a411b/image.jpg",
    "Title": "test"
}

ページ作成の自動化は、過去に挑戦したことがありました。

苦戦するポイントは/エスケープ文字の多さ。
とにかく見づらい💦
Graph APIでやると、縦型で書式が整ってみられることが大きいな、と見比べて感じますね。

3. 特定のページの取得

指定したSharePointサイトのページIDから、特定のページの詳細を取得します。
ページID1. サイトのページの取得2. ページの投稿の戻り値のid属性から取得できます。

image.png

Method - GET

URI
_api/v2.1/sites/{Host名}/pages/{page_id}
戻り値のサンプル
{
    "@odata.context": "https://hogehoge.sharepoint.com/sites/SharePointSite/_api/v2.1/$metadata#sites('hogehoge.sharepoint.com')/pages/oneDrive.page/$entity",
    "@odata.type": "#oneDrive.page",
    "@odata.etag": "\"{7F0875B7-250D-434B-8BE5-410C2EF9030D},11\"",
    "createdDateTime": "2024-04-26T15:31:43Z",
    "eTag": "\"{7F0875B7-250D-434B-8BE5-410C2EF9030D},11\"",
    "id": "7f0875b7-250d-434b-8be5-410c2ef9030d",
    "lastModifiedDateTime": "2024-04-29T12:40:40Z",
    "name": "20240426153141.aspx",
    "webUrl": "https://hogehoge.sharepoint.com/sites/SharePointSite/SitePages/20240426153141.aspx",
    "title": "sample",
    "pageLayout": "article",
    "thumbnailWebUrl": "https://media.akamai.odsp.cdn.office.net/hogehoge.sharepoint.com/_layouts/15/images/sitepagethumbnail.png",
    "promotionKind": "page",
    "showComments": true,
    "showRecommendedPages": false,
    "createdBy": {
      "user": {
        "displayName": "出戻り ガツオ",
        "email": "Mail@onmicrosoft.com"
      }
    },
    "lastModifiedBy": {
      "user": {
        "displayName": "SharePoint アプリ"
      }
    },
    "parentReference": {
      "listId": "fccd0142-da92-407f-b8ac-f42356cb2b9e",
      "siteId": "3789813c-5048-4aa0-b130-cfa78b57b219"
    },
    "contentType": {
      "id": "0x0101009D1CB255DA76424F860D91F20E6C41180060E80DAACC226D47992993F04DAFA7E4",
      "name": "サイト ページ"
    },
    "publishingState": {
      "level": "draft",
      "versionId": "0.7"
    },
    "reactions": {},
    "titleArea": {
      "enableGradientEffect": true,
      "imageWebUrl": "https://cdn.hubblecontent.osi.office.net/m365content/publish/005292d6-9dcc-4fc5-b50b-b2d0383a411b/image.jpg",
      "layout": "colorBlock",
      "showAuthor": true,
      "showPublishedDate": false,
      "showTextBlockAboveTitle": false,
      "textAboveTitle": "TEXT ABOVE TITLE",
      "textAlignment": "left",
      "title": "sample1",
      "authorByline@odata.type": "#Collection(String)",
      "authorByline": [
        "i:0#.f|membership|Mail@onmicrosoft.com"
      ],
      "imageSourceType": 2,
      "serverProcessedContent": {
        "imageSources": [
          {
            "key": "imageSource",
            "value": "https://cdn.hubblecontent.osi.office.net/m365content/publish/005292d6-9dcc-4fc5-b50b-b2d0383a411b/image.jpg"
          }
        ]
      },
      "authors@odata.type": "#Collection(graph.Json)",
      "authors": [
        {
          "email": "Mail@onmicrosoft.com",
          "upn": "Mail@onmicrosoft.com",
          "id": "i:0#.f|membership|Mail@onmicrosoft.com",
          "name": "出戻り ガツオ"
        }
      ]
    }
  }

あらかた取得できますね。
このままPower AutomateのSharePointコネクタのアクションにつなげる場合は、ItemIdが欲しいところです。
パスによるファイル メタデータの取得を使って、戻り値のwebUrl属性を引数に使うと、取得できます。

image.png

こちらから既存とMixしてもいいかもしれませんね。

今回の紹介した方法は、下書き・発行前の状態でページが作成されるので、投稿されるときは
SharePoint に HTTP 要求を送信アクションで、下記にPOSTメソッドで実行すると公開することができます。

_api/sitepages/pages('ItemId')/Publish

4. ページの削除

指定したSharePointサイトのページIDから、特定のページを削除します。
3. 特定のページの取得のメソッドをDELETEに変えるだけです。

image.png

Method - DELETE

URI
_api/v2.1/sites/{Host名}/pages/{page_id}

5. ページの編集

こちらの操作は、自分の知識の力不足で、SharePointコネクタを用いて、実現できませんでした💦
やむなしでHTTPコネクタで実装しています。

HTTPコネクタの認証周りの知識が特に疎いので参考になるリンクを、ひたすら載せておきます💦

セキュリティガバガバ思想で実装したものがコチラ。

image.png

Method - POST

ヘッダー
{
  "Content-Type": "application/json"
}
URI
https://graph.microsoft.com/v1.0/sites/{site-id}/pages/{page-id}/microsoft.graph.sitePage
ボディ
{
  "title": "sample",
  "showComments": true,
  "showRecommendedPages": false
}

文字通りページの編集を実現できます。
一番需要ありそうだけど、これがハードル高い💦
数日格闘しました…、がSharePointコネクタでは実現ができていない状態です。

認証周りは、リンクを参考にしてください🙇

おわりに

ページの更新が自由にできれば、所定のサイトから勝手に情報見てくれ!という運用もできそうですが、
現段階では活路が見えないです。

また未知の部分に入ると知識不足を痛感しますね💦

現状に満足なぞ到底できないので自己研鑽に励みたいと思います!!

3
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
3
3