Sharepoint Onlineのサイトでカスタムスクリプトが有効になっていると、共有ドキュメントエリアにおいたaspxファイルをjavascriptが有効なウェブフォームページとして利用でき、 デフォルトで用意されているListをデータベース代わりに扱ってシングルページアプリを作れます。
正統ではないのかもしれませんが、こういった形でReact-Appのプロジェクトをホストして動作させることができます。
簡単なアプリを作るため、axiosを使ってAPIを叩きましたが、ドキュメントに例が載っていることもなく、ばらばらに散っていた情報を集めてList操作を実施したのでそのメモに残します。
Sharepoint OnlineのListをAPI操作する
前提となる変数等
const YOUR_SUBDOMAIN="あなたのSharepoint Onlineサイトのサブドメイン";
const SITE_NAME="Sharepointサイト名";
const LIST_NAME="DB代わりに使いたいリスト名";
// ListItemEntityTypeFullName
// 下記で取得できる。APIコール数削減のため直接確認して定数化しておいたほうが吉。
// https://${YOUR_SUBDOMAIN}.sharepoint.com/_api/web/lists/GetByTitle('${LIST_NAME}')?$select=ListItemEntityTypeFullName
const ListItemEntityTypeFullName="上記で取得したEntityFullName";
const EndPoint=`https://${YOUR_SUBDOMAIN}.sharepoint.com/sites/${SITE_NAME}/_api/web/lists/getByTitle('${LIST_NAME}')/items`;
const ContextInfo=`https://${YOUR_SUBDOMAIN}.sharepoint.com/sites/${SITE_NAME}/_api/contextinfo`;
ListからItemをすべて取得
公式ドキュメント通りに動作し、GETで苦労なく取得できました。 前置きの共有ドキュメントにホストする形態をとる場合、ログイン済みの状態でaspxにアクセスしておりヘッダーのAuthorizationは省略できます。以降の別の操作も同じです。 取得あたりの上限件数があった気がしますが、pager型のアクセスで工夫してください。
axios.get(EndPoint)
.then(response =>{
// Listの一覧はresponse.data.valueに配列で入っている
// response.data.valueに含まれるitemのIdがUpdate等の個別操作に必要
console.log(response.data.value);
});
ListからIDを指定してItemを個別に取得
一覧取得と同様に公式ドキュメント通りで苦労がないです。
const ItemId=0; // 取得したいItemのId
axios.get(`${EndPoint}(${ItemId})`)
.then(response =>{
// response.data直下にリストの情報
console.log(response.data);
});
Listに新規アイテムを作成
アイテムの作成・編集にはform_digest_valueが必要で、これは上で定義したContextInfo
で取得ができます。
const data={
Title: "my first post via API"
}
axios.post(ContextInfo, {})
.then(response =>{
return axios.post(
EndPoint,
data,
{
headers: {
"Content-Type": "application/json;odata=verbose",
"X-RequestDigest": response.data.FormDigestValue
}
}
);
}).then(response =>{
// response.data直下に新規作成したリストアイテムの情報
console.log(response.data);
});
List Itemの編集
公式ドキュメントに若干の誤記があり、PR中。Content-Type
を新規アイテム同様にする必要があります。
const data={
Title: "my first edited post via API"
}
const itemId=0
axios.post(ContextInfo, {})
.then(response =>{
return axios.post(
`${EndPoint}(${ItemId})`,
data,
{
headers: {
"Content-Type": "application/json;odata=verbose",
"X-RequestDigest": response.data.FormDigestValue,
"If-Match": "*",
"X-HTTP-Method": "MERGE"
}
}
);
}).then(response =>{
// response.data直下に編集したリストアイテムの情報
console.log(response.data);
});
さらに詳しく
SharePointリスト列に応じてデータのフォーマットが決まっているものがある。
列の型 | 値の渡し方 |
---|---|
Yes/No | true/false |
選択肢 | 文字列だが、選択肢で定義されいてる文字列 |
日付と時刻 | ISO String (.toISOString() ) |
ユーザーまたはグループ | 内部で定義されているInt型のID (後述) |
[ユーザーとグループ]列
リストの操作に[ユーザーとグループ]列を含める場合は少し特殊な準備が必要になる。ちなみにAuthorやEditorという予約済フィールドも同様の構造である。[ユーザーとグループ]はフィールド名ではなく、フィールド名 + Idを操作する。注意として、リストにユーザーがauthorまたはeditorというフィールドを定義した場合、author0Idやeditor0Idを操作する。
ややこしいがドメインでIdは固定されておらず、サイトごとで固有のIdが割り当てられる。
UserIdを知りたい
サイトにおける自分のId
axios.get(`https://${YOUR_SUBDOMAIN}.sharepoint.com/sites/${SITE_NAME}/_api/SP.UserProfiles.PeopleManager/GetMyProperties`)
.then(response =>{
console.log(response.data.Id);
);
他のユーザーのIdをメールアドレスから調べる
const UserEmail = "hogehoge@fugafuga.com";
axios.get(`https://${YOUR_SUBDOMAIN}.sharepoint.com/sites/${SITE_NAME}/_api/SiteUsers/getByEmail('${UserEmail}')`)
.then(response =>{
console.log(response.data.Id);
);
ユーザー情報のリストを得たい
サイトにぶら下がっているユーザー情報一覧で取得する場合
const UserEmail = "hogehoge@fugafuga.com";
axios.get(`https://${YOUR_SUBDOMAIN}.sharepoint.com/sites/${SITE_NAME}/_api/SiteUsers`)
.then(response =>{
console.log(response.data);
);
ユーザー情報を展開して取得する
リストアイテムを取得する際にはサーバー側にId->ユーザー情報展開の処理を指示し、その状態でデータを受け取れる。
const ItemId=0; // 取得したいItemのId
const query="?$select=Title,Author/Title,Author/EMail$expand=Author"
axios.get(`${EndPoint}(${ItemId})${query}`)
.then(response =>{
// ユーザー表示名
console.log(response.data.Author.Title);
// ユーザーEmail
console.log(response.data.Author.Email);
// リストアイテムのタイトル
console.log(response.data.Title);
});
[ユーザーとグループ]列にログインユーザーを入れてPostする
以下、フィールド名をPersonField
、フィールドに格納されているユーザーのIdがPersonFieldId
で参照できるとして、
const data={
Title: "my first post via API"
};
const options={
headers: {
"Content-Type": "application/json;odata=verbose",
}
};
Promise.all([
axios.post(ContextInfo, {})
.then(response =>{
options.headers["X-RequestDigest"] = response.data.FormDigestValue;
}),
axios.get(`https://${YOUR_SUBDOMAIN}.sharepoint.com/sites/${SITE_NAME}/_api/SP.UserProfiles.PeopleManager/GetMyProperties`)
.then(response =>{
data["PersonFieldId"] = response.data.Id;
})
]).then(() =>{
return axios.post(
EndPoint,
data,
options
);
}).then(response =>{
// response.data直下に新規作成したリストアイテムの情報
console.log(response.data);
});
No comments:
Post a Comment