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 := '[email protected]';
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.
This library is MIT licensed and free to use. For companies that depend on it commercially we offer support and maintenance agreements with guaranteed response times, and sponsored development of features you need. Contact us at gdksoftware.com/contact-us or open an issue to get in touch.
Microsoft365-4D is developed by GDK Software, a Delphi-focused software company building developer tools, MCP integrations, and enterprise applications.