2020年5月22日 星期五

用程式讀取 exchange server 信箱

1. 安裝套件: Microsoft.Exchange.WebServices
2. 讀取信箱
var es = new Microsoft.Exchange.WebServices.Data.ExchangeService(ExchangeVersion.Exchange2010_SP1);
es.Credentials = new Microsoft.Exchange.WebServices.Data.WebCredentials(帳號, 密碼, 網域);
es.Url = new Uri("https://.../ews/Exchange.asmx"); // Server路徑
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }; // 確保登入信箱不會失敗
SearchFilter.SearchFilterCollection searchFilterCollection = new SearchFilter.SearchFilterCollection(LogicalOperator.And); // 設定條件類型為全部還是任一
                                            searchFilterCollection.Add(new SearchFilter.IsGreaterThan(EmailMessageSchema.DateTimeReceived, 上次資料時間)); // 加入條件
PropertySet itempropertyset = new PropertySet(BasePropertySet.FirstClassProperties); // 為了讀取內文
itempropertyset.RequestedBodyType = BodyType.Text;
ItemView itemview = new ItemView(1000);
itemview.PropertySet = itempropertyset;
var elements = es.FindItems(WellKnownFolderName.Inbox, searchFilterCollection, itemview).Where(a => a is EmailMessage).ToList(); // 尋找收件匣信件 (WellKnownFolderName.SentItems : 寄件備份)
foreach (EmailMessage email in elements ) // 轉型為 EmailMessage
{
email.Load(itempropertyset); // 為了讀取內文
email.From.Address : 寄件者
email.ToRecipients、email.DisplayTo : 收件者
email.Body.Text : 內文
email.InternetMessageId : 透過此欄位可找出回信
email.InReplyTo : 若為寄件備份且是回信,等於來源信件 InternetMessageId
email.Id.UniqueId : id
                 
依據id 找出單一信件:
EmailMessage.Bind(es, new ItemId(id));                      

取得附件檔案
public static IEnumerable<(string 檔名, byte[] 檔案內容)> 取得附加檔案(this Microsoft.Exchange.WebServices.Data.EmailMessage email)
        {
            foreach (var attachment in email.Attachments.OrderByDescending(a => a.Size))
            {
                if (attachment is Microsoft.Exchange.WebServices.Data.FileAttachment && !attachment.IsInline)
                {
                    Microsoft.Exchange.WebServices.Data.FileAttachment 附件檔案 = attachment as Microsoft.Exchange.WebServices.Data.FileAttachment;
                    using (var mem = new System.IO.MemoryStream())
                    {
                        附件檔案.Load(mem);
                        yield return (附件檔案.Name, mem.ToArray());
                    }
                }
            }
            yield return default;
        }


若要存取 Exchange Online 雲端信箱 ,認證方式較為複雜
1. 參考此網址,於 server 註冊應用程式提供授權
2. 設定證書及信箱語法如下
var cca = Microsoft.Identity.Client.ConfidentialClientApplicationBuilder
.Create(應用程式識別碼)
.WithClientSecret(用戶端密碼) // 最多可設兩年後到期
.WithTenantId(目錄識別碼)
.Build();
// The permission scope required for EWS access
var ewsScopes = new string[] { "https://outlook.office365.com/.default" };
//Make the token request
var authResult = await cca.AcquireTokenForClient(ewsScopes).ExecuteAsync();
var ews = new ExchangeService();
ews.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");
ews.Credentials = new OAuthCredentials(authResult.AccessToken);
//Impersonate the mailbox you'd like to access.
ews.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, "xxx@www.xxx");

使用 ews 寄信 (exchange online 不支援 smtpclient)

var mms = new EmailMessage(ews);
mms.ToRecipients.Add(new EmailAddress("xxx@www.xxx"));
mms.CcRecipients.Add(new EmailAddress("xxx@www.xxx"));
mms.BccRecipients.Add(new EmailAddress("xxx@www.xxx"));
mms.Subject = "xxx";    
mms.Body = new MessageBody(BodyType.HTML, "xxx");
mms.Attachments.AddFileAttachment("xxx.xxx",stream);
mms.Send(); // 不會留信件在寄件備份

沒有留言:

自訂權限驗證機制

// 使用 filter [Route("api/[controller]")] [ApiController] [Authorize] [TypeFilter(typeof(CustomAsyncAuthorizationFilter))] public c...