Pure Delphi library for Microsoft Graph API integration. Provides OAuth2 authentication with PKCE and typed clients for Mail, Calendar, Contacts, and SharePoint. No external dependencies beyond the Delphi RTL.
- Features
- Requirements
- Installation
- Quick Start
- Project Structure
- API Reference
- Demo Application
- Azure AD App Registration
- Token Storage
- License
- About GDK Software
- OAuth2 + PKCE authentication flow for Microsoft identity platform
- Mail -search, read, draft, send, delete, move messages, list folders, attachments
- Calendar -list, create, update, delete events, check schedule availability
- Contacts -search, create, update, delete contacts
- SharePoint -browse sites, list/search drive items, get file content
- Zero dependencies -uses only
System.Net.HttpClient(Delphi RTL) - Pluggable logging -
TLogProccallback, no global logger - Shared HTTP client -all Graph clients can share a single
TGraphHttpClient - Shared mailbox support -access shared/delegated mailboxes via
MailboxAddressproperty - Typed responses -all API calls return strongly-typed records (
TMailMessage,TCalendarEvent, etc.) - Interface-based -all clients implement interfaces (
IMailClient,ICalendarClient, etc.) for dependency injection
- Delphi 11 Alexandria or later (RAD Studio 11.x+)
- Azure AD App Registration with appropriate API permissions
Add the Source/OAuth2 and Source/Graph directories to your project's search path:
Source\OAuth2;Source\Graph
Then add the units you need to your uses clause:
uses
MSGraph.OAuth2.Types,
MSGraph.OAuth2.PKCE,
MSGraph.OAuth2.Client,
MSGraph.OAuth2.TokenStore,
MSGraph.Graph.Http,
MSGraph.Graph.Mail.Interfaces,
MSGraph.Graph.Mail,
MSGraph.Graph.Calendar.Interfaces,
MSGraph.Graph.Calendar,
MSGraph.Graph.Contacts.Interfaces,
MSGraph.Graph.Contacts,
MSGraph.Graph.SharePoint.Interfaces,
MSGraph.Graph.SharePoint;var Config: TOAuth2Config;
Config.ClientId := 'your-client-id';
Config.ClientSecret := 'your-client-secret';
Config.TenantId := 'your-tenant-id';
Config.RedirectUri := 'http://localhost:8080/oauth/callback';
Config.Scopes := TArray<string>.Create(
'openid', 'offline_access',
'Mail.Read', 'Mail.ReadWrite', 'Mail.Send',
'Calendars.ReadWrite', 'Contacts.ReadWrite',
'Sites.Read.All', 'User.Read'
);var PKCESession := TOAuth2PKCE.Generate;
var OAuthClient := TOAuth2Client.Create(Config);
var AuthUrl := OAuthClient.GenerateAuthorizationUrl(PKCESession);
// Open AuthUrl in browser, handle callback to receive authorization code
var Tokens := OAuthClient.ExchangeCodeForToken(Code, PKCESession.CodeVerifier);var Mail: IMailClient := TMailClient.Create(Tokens.AccessToken);
var SearchResult := Mail.SearchMessages('*', '', 10, 0);
for var Msg in SearchResult.Messages do
WriteLn(Msg.Subject, ' - ', Msg.From.Address);if Tokens.IsExpiringSoon(300) then
begin
var NewTokens := OAuthClient.RefreshAccessToken(Tokens.RefreshToken);
if NewTokens.RefreshToken.IsEmpty then
NewTokens.RefreshToken := Tokens.RefreshToken;
end;All Graph clients accept an existing TGraphHttpClient, allowing you to share one connection across multiple services:
var Http := TGraphHttpClient.Create(Tokens.AccessToken);
var Mail: IMailClient := TMailClient.Create(Http);
var Calendar: ICalendarClient := TCalendarClient.Create(Http);Set MailboxAddress on TGraphHttpClient to target a shared or delegated mailbox. When empty (default), endpoints use /me. When set, endpoints use /users/{address}:
var Http := TGraphHttpClient.Create(Tokens.AccessToken);
Http.MailboxAddress := 'projects@company.com';
var Mail: IMailClient := TMailClient.Create(Http);
var Messages := Mail.SearchMessages('*', '', 10, 0);This requires the Mail.Read.Shared and/or Mail.Send.Shared delegated permissions in your Azure AD app registration.
Source/
OAuth2/
MSGraph.OAuth2.Types.pas -Config records, token response, PKCE session, exceptions
MSGraph.OAuth2.PKCE.pas -PKCE code_verifier + code_challenge generation
MSGraph.OAuth2.Client.pas -OAuth2 flow: auth URL, token exchange, refresh
MSGraph.OAuth2.TokenStore.pas -Thread-safe in-memory token + PKCE storage
Graph/
MSGraph.Graph.Http.pas -Graph API HTTP client with error handling
MSGraph.Graph.JsonHelper.pas -JSON parsing utilities (TGraphJson)
MSGraph.Graph.Mail.Types.pas -Mail record types (TMailMessage, TMailFolder, etc.)
MSGraph.Graph.Mail.Interfaces.pas -IMailClient interface
MSGraph.Graph.Mail.pas -TMailClient implementation
MSGraph.Graph.Calendar.Types.pas -Calendar record types (TCalendarEvent, TAttendee, etc.)
MSGraph.Graph.Calendar.Interfaces.pas -ICalendarClient interface
MSGraph.Graph.Calendar.pas -TCalendarClient implementation
MSGraph.Graph.Contacts.Types.pas -Contact record types (TContact, TPostalAddress, etc.)
MSGraph.Graph.Contacts.Interfaces.pas -IContactsClient interface
MSGraph.Graph.Contacts.pas -TContactsClient implementation
MSGraph.Graph.SharePoint.Types.pas -SharePoint record types (TSite, TDriveItem)
MSGraph.Graph.SharePoint.Interfaces.pas -ISharePointClient interface
MSGraph.Graph.SharePoint.pas -TSharePointClient implementation
Examples/
Microsoft365Demo.dpr -Console demo with interactive menu
Microsoft365Demo.App.pas -Demo application logic
Microsoft365Demo.CallbackServer.pas -Indy HTTP server for OAuth callback
All library exceptions inherit from EMSGraphException:
| Exception | Raised by |
|---|---|
EMSGraphException |
Base exception for all Microsoft365-4D errors |
EOAuth2Exception |
Token exchange failures, invalid responses |
EGraphApiException |
Graph API HTTP errors, missing access token |
ETokenStoreException |
Missing tokens, expired PKCE sessions |
| Method | Description |
|---|---|
SearchMessages(Query, FolderId, Top, Skip) |
Search or list messages |
GetMessage(MessageId) |
Get full message by ID |
GetMessageAttachments(MessageId) |
List attachments |
GetAttachmentContent(MessageId, AttachmentId) |
Get attachment content |
CreateDraft(Subject, Body, To, Cc, IsHtml) |
Create draft |
UpdateDraft(MessageId, Subject, Body, To, Cc, IsHtml) |
Update existing draft |
SendDraft(MessageId) |
Send a draft message |
DeleteDraft(MessageId) |
Delete a draft |
MoveMessage(MessageId, FolderId) |
Move message to folder |
ListMailFolders(ParentFolderId) |
List mail folders |
GetMailboxSignature |
Get HTML signature |
| Method | Description |
|---|---|
ListEvents(Start, End, Top, Timezone) |
List calendar events in range |
GetEvent(EventId) |
Get event details |
CreateEvent(Subject, Start, End, Location, Body, Attendees, IsAllDay) |
Create event |
UpdateEvent(EventId, Subject, Start, End, Location, Body, Attendees, IsAllDay) |
Update event |
DeleteEvent(EventId) |
Delete event |
GetScheduleAvailability(Schedules, Start, End, Timezone) |
Check availability |
| Method | Description |
|---|---|
SearchContacts(Query, Top) |
Search or list contacts |
GetContact(ContactId) |
Get contact details |
CreateContact(GivenName, Surname, Email, Phone, Company, JobTitle) |
Create contact |
UpdateContact(ContactId, GivenName, Surname, Email, Phone, Company, JobTitle) |
Update contact |
DeleteContact(ContactId) |
Delete contact |
| Method | Description |
|---|---|
ListSites(Query, Top) |
Search SharePoint sites |
GetSite(SiteId) |
Get site details |
ListDriveItems(SiteId, FolderId, Top) |
List items in drive/folder |
SearchDriveItems(SiteId, Query, Top) |
Search drive items |
GetDriveItemContent(SiteId, ItemId) |
Get item details + download URL |
The Examples/ folder contains a console application demonstrating the full OAuth2 flow and all Graph API operations.
Microsoft365Demo.exe --client-id "your-id" --client-secret "your-secret" --tenant-id "your-tenant" --redirect-uri "http://localhost:8080/oauth/callback"All parameters can also be provided interactively when omitted. Available options:
| Parameter | Description | Default |
|---|---|---|
--client-id |
Azure AD application ID | (prompted) |
--client-secret |
Azure AD client secret | (prompted) |
--tenant-id |
Azure AD tenant ID | (prompted) |
--redirect-uri |
OAuth2 redirect URI | http://localhost:8080/oauth/callback |
--port |
Local callback server port | 8080 |
The demo provides an interactive menu with the following options:
- Authenticate (opens browser for Microsoft login)
- List messages
- Read message by ID
- Send email (create draft + send)
- List mail folders
- List calendar events
- Create calendar event
- Search contacts
- List SharePoint sites
- Refresh token manually
- Go to Azure Portal > Microsoft Entra ID > App registrations > New registration
- Set Redirect URI to your callback URL (Web platform), e.g.
http://localhost:8080/oauth/callback - Create a Client secret under Certificates & secrets
- Add API permissions (Microsoft Graph, Delegated):
| Permission | Description |
|---|---|
openid |
Sign-in |
profile |
User profile |
offline_access |
Refresh tokens |
Mail.Read |
Read mail |
Mail.ReadWrite |
Create/edit drafts |
Mail.Send |
Send mail |
MailboxSettings.Read |
Read mailbox signature |
Calendars.ReadWrite |
Calendar access |
Contacts.ReadWrite |
Contacts access |
Sites.Read.All |
SharePoint read access |
User.Read |
User info |
Mail.Read.Shared |
Read shared/delegated mailboxes |
Mail.Send.Shared |
Send from shared/delegated mailboxes |
- Click Grant admin consent if you have admin rights
The included TTokenStore stores tokens in-memory only and is intended for demo/development use. For production:
- Persist tokens to a database, file, or OS-level credential store
- Encrypt refresh tokens and access tokens before storage
- Implement your own storage by subclassing or replacing
TTokenStore
MIT License. See LICENSE for details.
Microsoft365-4D is developed by GDK Software, a Delphi-focused software company building developer tools, MCP integrations, and enterprise applications.