はじめに
先日Twitterで、こちらの投稿を見かけました。
Microsoft Graph API for SharePoint Pagesが一般公開!とのことで、
SharePointの投稿作成が捗るのでは!と思い、さっそくPower Automateで試してみました。
今回試したこと
- サイトのページの取得
- ページの投稿
- 特定のページの取得
- ページの削除
- ページの編集
上記のシナリオを試しています。
Micorosoft learnの基本的なシナリオの検証結果です。
手っ取り早く試したい方はGraph Explorerがおススメです。
検証に当たり
Graph APIは自分自身チャレンジした経験が浅く、
また経験上、Microsoft Entra IDでアプリの登録をして…
といった準備は実装までに、
かなり時間がかかる印象を抱きました。
そこで!今回はSharePointコネクタの既存のアクションでできないかトライしました。
今回の記事ではSharePoint に HTTP 要求を送信アクションをメインで使用しています。
SharePoint に HTTP 要求を送信アクションでGraph API
SharePoint に HTTP 要求を送信アクションでGraph APIを使う上で、下記のサイトを参考にさせていただきました🙇
- Microsoft learn Microsoft Graphの概要
- Microsoft learn SharePoint REST v2 (Microsoft Graph)エンドポイント を使用した操作
- コルネさんのブログ
いつも大変お世話になっております。
Graph APIを実行するためのアクションは、URIを下記のように設定すると実行できるようです。
_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.
本件の操作に関するドキュメントは少ないです。
運用で実装される際は、その点を鑑みてご活用ください。
Graph APIの記法で実施するメリットは、非常に記載がシンプルになります。
検証結果で内容をご確認ください。
1. サイトのページの取得
指定したSharePointサイトの全ページを取得します。
Method - GET
_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
に変えてヘッダー、ボディを加えます。
Method - POST
{
"Content-Type": "application/json"
}
_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
から、特定のページの詳細を取得します。
ページID
は1. サイトのページの取得
や2. ページの投稿
の戻り値のid
属性から取得できます。
Method - GET
_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
属性を引数に使うと、取得できます。
こちらから既存とMixしてもいいかもしれませんね。
今回の紹介した方法は、下書き・発行前の状態でページが作成されるので、投稿されるときは
SharePoint に HTTP 要求を送信アクションで、下記にPOST
メソッドで実行すると公開することができます。
_api/sitepages/pages('ItemId')/Publish
4. ページの削除
指定したSharePointサイトのページID
から、特定のページを削除します。
3. 特定のページの取得
のメソッドをDELETE
に変えるだけです。
Method - DELETE
_api/v2.1/sites/{Host名}/pages/{page_id}
5. ページの編集
こちらの操作は、自分の知識の力不足で、SharePointコネクタを用いて、実現できませんでした💦
やむなしでHTTPコネクタ
で実装しています。
HTTPコネクタの認証周りの知識が特に疎いので参考になるリンクを、ひたすら載せておきます💦
セキュリティガバガバ思想で実装したものがコチラ。
Method - POST
{
"Content-Type": "application/json"
}
https://graph.microsoft.com/v1.0/sites/{site-id}/pages/{page-id}/microsoft.graph.sitePage
{
"title": "sample",
"showComments": true,
"showRecommendedPages": false
}
文字通りページの編集
を実現できます。
一番需要ありそうだけど、これがハードル高い💦
数日格闘しました…、がSharePointコネクタでは実現ができていない状態です。
認証周りは、リンクを参考にしてください🙇
おわりに
ページの更新が自由にできれば、所定のサイトから勝手に情報見てくれ!という運用もできそうですが、
現段階では活路が見えないです。
また未知の部分に入ると知識不足を痛感しますね💦
現状に満足なぞ到底できないので自己研鑽に励みたいと思います!!