[Angular] 與 O365 跳舞系列 - MAIL

一旦登入成功後,接下來的工作就比較簡單了,因為查詢的 endpoint 都是一樣的,所以只需要在意後面所傳項目的變化即可,而這篇筆記包含了取得信件資料夾,信件清單,寄信等動作

取得郵件資料夾

權限需求:需要 Mail.Read

呼叫URL

1
2
GET /me/mailFolders
GET /users/{{id | userPrincipalName}}/mailFolders

回傳資料結構

1
2
3
4
5
6
7
8
9
10
11
12
{
"value": [
{
"displayName": "displayName-value",
"parentFolderId": "parentFolderId-value",
"childFolderCount": 99,
"unreadItemCount": 99,
"totalItemCount": 99,
"id": "id-value"
}
]
}
  • id 是查詢該資料夾下信件時所需要的資訊

取得郵件列表

權限需求:需要 Mail.Read

呼叫URL

1
2
GET /me/mailFolders/{id}/messages
GET /users/{userId | userPrincipalName}/mailFolders/{id}/messages
  • id 為資料夾 ID

回傳資料結構

回傳為 Message 的資料集

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
{
"value": [
{
"bccRecipients": [{"@odata.type": "microsoft.graph.recipient"}],
"body": {"@odata.type": "microsoft.graph.itemBody"},
"bodyPreview": "string",
"categories": ["string"],
"ccRecipients": [{"@odata.type": "microsoft.graph.recipient"}],
"changeKey": "string",
"conversationId": "string",
"createdDateTime": "String (timestamp)",
"flag": {"@odata.type": "microsoft.graph.followupFlag"},
"from": {"@odata.type": "microsoft.graph.recipient"},
"hasAttachments": true,
"id": "string (identifier)",
"importance": "String",
"inferenceClassification": "String",
"internetMessageHeaders": [{"@odata.type": "microsoft.graph.internetMessageHeader"}],
"internetMessageId": "String",
"isDeliveryReceiptRequested": true,
"isDraft": true,
"isRead": true,
"isReadReceiptRequested": true,
"lastModifiedDateTime": "String (timestamp)",
"parentFolderId": "string",
"receivedDateTime": "String (timestamp)",
"replyTo": [{"@odata.type": "microsoft.graph.recipient"}],
"sender": {"@odata.type": "microsoft.graph.recipient"},
"sentDateTime": "String (timestamp)",
"subject": "string",
"toRecipients": [{"@odata.type": "microsoft.graph.recipient"}],
"uniqueBody": {"@odata.type": "microsoft.graph.itemBody"},
"webLink": "string",

"attachments": [{"@odata.type": "microsoft.graph.attachment"}],
"extensions": [{"@odata.type": "microsoft.graph.extension"}],
"multiValueExtendedProperties": [{"@odata.type": "microsoft.graph.multiValueLegacyExtendedProperty"}],
"singleValueExtendedProperties": [{"@odata.type": "microsoft.graph.singleValueLegacyExtendedProperty"}]
}
]
}

上下頁

由於每次取回來的資料只有 10 筆(預設值),所以必須透過 skip 的方式來取得之後頁數的信件清單

呼叫URL

1
2
GET /me/mailFolders/{id}/messages?$skip=<number>
GET /users/{userId | userPrincipalName}/mailFolders/{id}/messages?$skip=<number>
  • id 為資料夾 ID
  • number:以 10 為單位

這是我寫的範例程式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
mailQuery$ = new BehaviorSubject<{ mailFolderId: string; skip: number }>({
mailFolderId: '',
skip: 0
});

mails$ = this.mailQuery$.pipe(
filter(({ mailFolderId, skip }) => !!mailFolderId),
switchMap(({ mailFolderId, skip }) =>
this.graphHelper.query(
`mailfolders/${mailFolderId}/messages?$skip=${skip}`
)
),
map((data: any) => data.value)
);


getMail(id: string) {
this.mailQuery$.next({
...this.mailQuery$.value,
mailFolderId: id,
skip: 0
});
}

nextPage() {
this.mailQuery$.next({
...this.mailQuery$.value,
skip: this.mailQuery$.value.skip + 10
});
}
prevPage() {
if (this.mailQuery$.value.skip >= 10) {
this.mailQuery$.next({
...this.mailQuery$.value,
skip: this.mailQuery$.value.skip - 10
});
}
}

OData

在上下頁功能時,我們看到有 $skip 的參數出現,在細看文件後,發現 Graph API 其實也有支援 OData 的查詢語法,這表示我們可以透過 OData 的查詢語法來改變 API 的回傳結果。

例如,我想要一次取回 25 封信件內容,因為預設是一次取 10 筆,這時就需要搭配 $top 的設定來改變。或是說取回來資料欄位太多,我只需要特定的幾個欄位就可以,就可以使用 $select 的方式來做設定,更多的資訊可以看文件 (列在參考文件中)

寄信

權限需求:需要 Mail.Send

呼叫URL

1
2
POST /me/sendMail
POST /users/{id | userPrincipalName}/sendMail

送出資料結構:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
"message": {
"subject": "Meet for lunch?",
"body": {
"contentType": "Text", // 'Text' | 'HTML'
"content": "The new cafeteria is open."
},
"toRecipients": [
{
"emailAddress": {
"address": "[email protected]"
}
}
],
"ccRecipients": [
{
"emailAddress": {
"address": "[email protected]"
}
}
]
},
"saveToSentItems": "false"
}
  • messageMessage 型別
  • saveToSentItems 設定是否要存儲至寄件備份

回傳結果

1
HTTP/1.1 202 Accepted

心得

至於其他的相關操作,基本上與上述的大同小異,大家可以自己試試看

參考文件