prasadchinwal / microsoft-graph
Package for working with Microsoft Graph API
Installs: 4 983
Dependents: 0
Suggesters: 0
Security: 0
Stars: 1
Watchers: 1
Forks: 1
Open Issues: 0
pkg:composer/prasadchinwal/microsoft-graph
Requires
- php: ^8.2|^8.3
- illuminate/support: ^10.0|^11.0|^12.0
- spatie/laravel-data: ^4.11
Requires (Dev)
- laravel/pint: ^1.10
- pestphp/pest: ^2.13
README
A comprehensive Laravel wrapper for Microsoft Graph API that provides an elegant, fluent interface for interacting with Microsoft 365 services including users, calendars, events, mail, and more.
Features
- 🚀 Easy Integration - Simple, Laravel-style fluent API
- ⚡ Performance - Automatic OAuth token caching with expiry handling
- 🔒 Type Safe - Full support for PHP 8.2+ with strict types and return type declarations
- 🎯 Data Objects - Strongly-typed responses using Spatie Laravel Data
- 🛡️ Error Handling - Custom exceptions with clear, actionable error messages
- 📧 Email & Calendar - Full support for Outlook, calendars, events, and mail
- 👥 User Management - Complete user CRUD operations with license management
- 🖼️ Profile Photos - Upload, download, and delete user profile photos
- 📎 Attachment Management - Upload, download, and manage file, item, and reference attachments
- 📝 Query Filters - OData query filtering for events and calendars
- 🔧 Laravel 10-12 - Supports Laravel 10.x, 11.x, and 12.x
Requirements
- PHP 8.2 or higher
- Laravel 10.0, 11.0, or 12.0
- Microsoft Azure App Registration with appropriate permissions
Installation
Install the package via Composer:
composer require prasadchinwal/microsoft-graph
Publish the configuration file:
php artisan vendor:publish --tag=microsoft-graph-config
This will create a config/microsoft-graph.php file in your application.
Configuration
1. Azure App Registration
Before using this package, you need to register an application in the Azure Portal:
- Navigate to Azure Active Directory > App registrations
- Click New registration
- Give your app a name and select supported account types
- Click Register
- Note down the Application (client) ID and Directory (tenant) ID
- Go to Certificates & secrets > New client secret
- Create a new secret and note down its value
- Go to API permissions and add the required Microsoft Graph permissions:
User.Read.AllUser.ReadWrite.AllCalendars.ReadCalendars.ReadWriteMail.ReadMail.Send- Grant admin consent for your organization
2. Environment Configuration
Add the following to your .env file:
MICROSOFT_GRAPH_TENANT_ID=your-tenant-id MICROSOFT_GRAPH_CLIENT_ID=your-client-id MICROSOFT_GRAPH_CLIENT_SECRET=your-client-secret
3. Configuration File
The config/microsoft-graph.php file contains:
return [ 'tenant_id' => env('MICROSOFT_GRAPH_TENANT_ID', null), 'client_id' => env('MICROSOFT_GRAPH_CLIENT_ID', null), 'client_secret' => env('MICROSOFT_GRAPH_CLIENT_SECRET', null), 'timezone' => env('APP_TIMEZONE', 'UTC'), ];
Note: The package will validate configuration on boot and throw a ConfigurationException if required values are missing.
Usage
Initialization
The package can be used via the Facade or by instantiating the class:
use PrasadChinwal\MicrosoftGraph\Facades\MicrosoftGraph; // Via Facade $graph = app('graph'); // Or direct instantiation $graph = new \PrasadChinwal\MicrosoftGraph\MicrosoftGraph();
User Management
Get All Users
Retrieve all users in your organization.
API Reference: List Users
use PrasadChinwal\MicrosoftGraph\Facades\MicrosoftGraph; $users = MicrosoftGraph::users()->get(); foreach ($users as $user) { echo $user->displayName . ' - ' . $user->mail; }
Get a Specific User
Retrieve a user by their email address (User Principal Name).
API Reference: Get User
$user = MicrosoftGraph::users()->find('john.doe@company.com'); echo $user->displayName; // John Doe echo $user->jobTitle; // Software Engineer echo $user->department; // Engineering echo $user->mobilePhone; // +1 234 567 8900
Update a User
Update user properties using the User builder.
API Reference: Update User
use PrasadChinwal\MicrosoftGraph\Builder\User\User; $userUpdate = new User(); $userUpdate->displayName = 'Jane Smith'; $userUpdate->jobTitle = 'Senior Software Engineer'; $userUpdate->department = 'Engineering'; $userUpdate->mobilePhone = '+1 234 567 8901'; MicrosoftGraph::users()->update('jane.smith@company.com', $userUpdate);
Get User Licenses
Retrieve license details for a user.
API Reference: List License Details
$licenses = MicrosoftGraph::users() ->withEmail('john.doe@company.com') ->getLicenses(); foreach ($licenses as $license) { echo $license->skuPartNumber; foreach ($license->servicePlans as $plan) { echo $plan->servicePlanName; } }
Assign License to User
Assign one or more licenses to a user.
API Reference: Assign License
use PrasadChinwal\MicrosoftGraph\Builder\License\AssignLicenseBuilder; use PrasadChinwal\MicrosoftGraph\Builder\License\NewLicense; use PrasadChinwal\MicrosoftGraph\Builder\License\NewLicenseCollection; $license = new NewLicense(); $license->skuId = 'sku-guid-here'; $licenseCollection = new NewLicenseCollection([$license]); $builder = new AssignLicenseBuilder( addLicenses: $licenseCollection, removeLicenses: [] ); $updatedUser = MicrosoftGraph::users() ->withEmail('john.doe@company.com') ->assignLicense($builder);
Profile Photos
Get User Profile Photo
Download a user's profile photo.
API Reference: Get Photo
$response = MicrosoftGraph::users() ->withEmail('john.doe@company.com') ->getPhoto(); // Save to file file_put_contents('profile.jpg', $response->body()); // Or return as response return response($response->body()) ->header('Content-Type', 'image/jpeg');
Update User Profile Photo
Upload a new profile photo for a user.
API Reference: Update Photo
$imageData = file_get_contents('/path/to/photo.jpg'); MicrosoftGraph::users() ->withEmail('john.doe@company.com') ->updatePhoto($imageData);
Delete User Profile Photo
Remove a user's profile photo.
API Reference: Delete Photo
MicrosoftGraph::users() ->withEmail('john.doe@company.com') ->deletePhoto();
Calendar Management
Get User Calendars
Retrieve all calendars for a user.
API Reference: List Calendars
$calendars = MicrosoftGraph::calendar() ->for('john.doe@company.com') ->get(); foreach ($calendars as $calendar) { echo $calendar->name; }
Get User Schedule
Get free/busy schedule information for one or more users.
API Reference: Get Schedule
use Carbon\Carbon; $users = ['john.doe@company.com', 'jane.smith@company.com']; $schedule = MicrosoftGraph::calendar() ->for('requester@company.com') ->schedule( users: $users, from: Carbon::now(), to: Carbon::now()->addDays(7), timezone: 'America/Chicago', interval: 60 );
Get Calendar View
Get calendar events within a specific time range.
API Reference: List Calendar View
use Carbon\Carbon; $events = MicrosoftGraph::calendar() ->for('john.doe@company.com') ->view( start: Carbon::now()->toIso8601String(), end: Carbon::now()->addMonth()->toIso8601String() );
Event Management
Get User Events
Retrieve calendar events for a user.
API Reference: List Events
$events = MicrosoftGraph::event() ->for('john.doe@company.com') ->get(); foreach ($events as $event) { echo $event->subject; echo $event->start->dateTime; echo $event->end->dateTime; }
Filter Events
Use OData filters to query specific events.
API Reference: Filter Query Parameter
// Get events within a date range $events = MicrosoftGraph::event() ->for('john.doe@company.com') ->where('start/dateTime', 'ge', '2024-01-01') ->where('end/dateTime', 'le', '2024-12-31') ->get(); // Use OR conditions $events = MicrosoftGraph::event() ->for('john.doe@company.com') ->where('subject', 'eq', 'Team Meeting') ->orWhere('subject', 'eq', 'All Hands') ->get();
Create an Event
Create a new calendar event using a CalendarEvent class.
API Reference: Create Event
Step 1: Generate an event class:
php artisan make:graph-event TeamMeetingEvent
Step 2: Configure the event class:
<?php namespace App\Mail; use PrasadChinwal\MicrosoftGraph\Calendar\Event\CalendarEvent; use PrasadChinwal\MicrosoftGraph\Calendar\Event\Eventable\Envelope; use PrasadChinwal\MicrosoftGraph\Calendar\Event\Eventable\Attendee; use PrasadChinwal\MicrosoftGraph\Calendar\Event\Eventable\Enums\CalendarEventImportance; use Illuminate\Mail\Mailables\Content; use Carbon\Carbon; class TeamMeetingEvent extends CalendarEvent { public function envelope(): Envelope { return new Envelope( from: 'organizer@company.com', subject: 'Weekly Team Sync', attendees: [ new Attendee('john.doe@company.com', 'John Doe', required: true), new Attendee('jane.smith@company.com', 'Jane Smith', required: false), ], start: Carbon::parse('2024-12-20 10:00:00'), end: Carbon::parse('2024-12-20 11:00:00'), location: 'Conference Room A', importance: CalendarEventImportance::HIGH->value, isOnlineMeeting: true, reminder: true ); } public function content(): Content { return new Content( markdown: 'emails.team-meeting', with: ['agenda' => 'Sprint planning and retrospective'] ); } }
Step 3: Create the event:
use App\Mail\TeamMeetingEvent; $response = MicrosoftGraph::event()->create(new TeamMeetingEvent());
Update an Event
Update an existing calendar event.
API Reference: Update Event
$response = MicrosoftGraph::event()->update( eventId: 'AAMkAGI2...', mailable: new TeamMeetingEvent() );
Accept an Event
Accept a meeting invitation.
API Reference: Accept Event
MicrosoftGraph::event() ->for('john.doe@company.com') ->accept( eventId: 'AAMkAGI2...', message: 'Looking forward to it!' );
Decline an Event
Decline a meeting invitation.
API Reference: Decline Event
MicrosoftGraph::event() ->for('john.doe@company.com') ->decline( eventId: 'AAMkAGI2...', message: 'Unable to attend due to conflict.' );
Cancel an Event
Cancel a meeting (organizer only).
API Reference: Cancel Event
MicrosoftGraph::event() ->for('organizer@company.com') ->cancel( eventId: 'AAMkAGI2...', message: 'Meeting cancelled due to unforeseen circumstances.' );
Mail Management
Get User Messages
Retrieve email messages for a user.
API Reference: List Messages
$messages = MicrosoftGraph::mail() ->for('john.doe@company.com') ->top(50) ->get();
Filter Messages
Apply OData filters to retrieve specific messages.
// Get unread messages $messages = MicrosoftGraph::mail() ->for('john.doe@company.com') ->where('isRead', '!=', 'true') ->top(25) ->get(); // Get messages from a specific sender $messages = MicrosoftGraph::mail() ->for('john.doe@company.com') ->where('from/emailAddress/address', '=', 'sender@example.com') ->get(); // Filter by received date $messages = MicrosoftGraph::mail() ->for('john.doe@company.com') ->where('receivedDateTime', '>=', '2024-01-01T00:00:00Z') ->top(100) ->get();
Sending Email
Send Email via Outlook
Send an email on behalf of a user.
API Reference: Send Mail
// Send to a single recipient MicrosoftGraph::outlook() ->for('sender@company.com') ->sendEmail( subject: 'Project Update', message: 'The project is progressing well...', to: 'recipient@company.com' ); // Send to multiple recipients MicrosoftGraph::outlook() ->for('sender@company.com') ->sendEmail( subject: 'Team Announcement', message: 'Please review the attached document...', to: [ 'john.doe@company.com', 'jane.smith@company.com', 'team@company.com' ] );
Attachment Management
Microsoft Graph API supports three types of attachments:
- File Attachments - Binary files (up to 3MB)
- Item Attachments - Embedded contacts, events, or messages
- Reference Attachments - Links to files on OneDrive, Dropbox, etc.
List Attachments
Get all attachments for a message or event.
API Reference: List Attachments
// List message attachments $attachments = MicrosoftGraph::attachments() ->forMessage('john.doe@company.com', 'messageId') ->list(); foreach ($attachments as $attachment) { echo $attachment->name; echo $attachment->contentType; echo $attachment->size; } // List event attachments $attachments = MicrosoftGraph::attachments() ->forEvent('john.doe@company.com', 'eventId') ->list();
Get Attachment Metadata
Retrieve metadata for a specific attachment.
API Reference: Get Attachment
$attachment = MicrosoftGraph::attachments() ->forMessage('john.doe@company.com', 'messageId') ->get('attachmentId'); echo $attachment->id; echo $attachment->name; echo $attachment->contentType; echo $attachment->size; echo $attachment->lastModifiedDateTime;
Download Attachment Content
Download the raw binary content of a file attachment.
$response = MicrosoftGraph::attachments() ->forMessage('john.doe@company.com', 'messageId') ->getRaw('attachmentId'); // Save to file file_put_contents('downloaded_file.pdf', $response->body()); // Or return as HTTP response return response($response->body()) ->header('Content-Type', $response->header('Content-Type'));
Add File Attachment
Upload a file attachment (up to 3MB).
API Reference: Add Attachment
From File Path:
use PrasadChinwal\MicrosoftGraph\Builder\Attachment\FileAttachmentBuilder; // Create attachment from file $builder = FileAttachmentBuilder::fromFile('/path/to/document.pdf'); $attachment = MicrosoftGraph::attachments() ->forMessage('john.doe@company.com', 'messageId') ->addFile($builder); echo $attachment->id; // Use this ID for future operations
From Binary Data:
use PrasadChinwal\MicrosoftGraph\Builder\Attachment\FileAttachmentBuilder; $imageData = file_get_contents('/path/to/image.jpg'); $builder = FileAttachmentBuilder::fromData( data: $imageData, name: 'profile-photo.jpg', contentType: 'image/jpeg' ); $attachment = MicrosoftGraph::attachments() ->forEvent('john.doe@company.com', 'eventId') ->addFile($builder);
Inline Attachment (for emails):
use PrasadChinwal\MicrosoftGraph\Builder\Attachment\FileAttachmentBuilder; $builder = FileAttachmentBuilder::fromFile('/path/to/logo.png') ->asInline('logo-cid'); $attachment = MicrosoftGraph::attachments() ->forMessage('john.doe@company.com', 'draftMessageId') ->addFile($builder); // Reference in HTML body as: <img src="cid:logo-cid">
Add Reference Attachment
Add a link to a file stored on OneDrive, Dropbox, or other cloud storage.
use PrasadChinwal\MicrosoftGraph\Builder\Attachment\ReferenceAttachmentBuilder; $builder = ReferenceAttachmentBuilder::fromUrl( url: 'https://contoso.sharepoint.com/documents/report.xlsx', name: 'Q4 Financial Report' ) ->setProvider('oneDriveBusiness') ->setPermission('edit') ->setThumbnail('https://contoso.sharepoint.com/thumbnails/report_thumb.png'); $attachment = MicrosoftGraph::attachments() ->forMessage('john.doe@company.com', 'messageId') ->addReference($builder);
Available Providers:
oneDriveBusinessoneDriveConsumerdropbox
Available Permissions:
view- Read-only accessedit- Read and write accessanonymousView- Public read-onlyanonymousEdit- Public read and writeorganizationView- Organization read-onlyorganizationEdit- Organization read and write
Add Custom Attachment
Add an attachment using custom array data for advanced scenarios.
$attachmentData = [ '@odata.type' => '#microsoft.graph.fileAttachment', 'name' => 'custom-document.txt', 'contentBytes' => base64_encode('Hello, World!'), 'contentType' => 'text/plain', ]; $attachment = MicrosoftGraph::attachments() ->forMessage('john.doe@company.com', 'messageId') ->create($attachmentData);
Delete Attachment
Remove an attachment from a message or event.
API Reference: Delete Attachment
MicrosoftGraph::attachments() ->forMessage('john.doe@company.com', 'messageId') ->delete('attachmentId'); // Or for events MicrosoftGraph::attachments() ->forEvent('john.doe@company.com', 'eventId') ->delete('attachmentId');
Complete Example: Sending Email with Attachments
use PrasadChinwal\MicrosoftGraph\Builder\Attachment\FileAttachmentBuilder; // 1. Create a draft message $message = MicrosoftGraph::mail()->createDraft([ 'subject' => 'Project Report', 'body' => [ 'contentType' => 'HTML', 'content' => '<p>Please find attached the project report.</p>' ], 'toRecipients' => [ ['emailAddress' => ['address' => 'manager@company.com']] ] ]); // 2. Add attachments $pdfBuilder = FileAttachmentBuilder::fromFile('/reports/project-report.pdf'); $excelBuilder = FileAttachmentBuilder::fromFile('/reports/data.xlsx'); MicrosoftGraph::attachments() ->forMessage('sender@company.com', $message['id']) ->addFile($pdfBuilder); MicrosoftGraph::attachments() ->forMessage('sender@company.com', $message['id']) ->addFile($excelBuilder); // 3. Send the message MicrosoftGraph::mail()->send($message['id']);
Size Limitations
Important: The direct attachment API supports files up to 3MB. For larger files (3-150MB), use the upload session method:
// Files larger than 3MB throw an exception try { $builder = FileAttachmentBuilder::fromFile('/large-file.zip'); } catch (\InvalidArgumentException $e) { // Handle large file - use upload session instead // (Upload session not yet implemented in this package) }
Attachment Types Reference
| Type | Use Case | Max Size | Properties |
|---|---|---|---|
| fileAttachment | Documents, images, files | 3 MB | contentBytes, contentType, name |
| itemAttachment | Embedded contacts, events, messages | 3 MB | item (nested object) |
| referenceAttachment | OneDrive, SharePoint, Dropbox links | N/A | sourceUrl, providerType, permission |
Error Handling
The package includes custom exceptions for better error handling:
Exception Classes
MicrosoftGraphException- Base exception classAuthenticationException- OAuth/token errorsInvalidEmailException- Invalid email formatConfigurationException- Missing or invalid configuration
Example Usage
use PrasadChinwal\MicrosoftGraph\Exceptions\InvalidEmailException; use PrasadChinwal\MicrosoftGraph\Exceptions\ConfigurationException; use Illuminate\Http\Client\RequestException; try { $user = MicrosoftGraph::users()->find('invalid-email'); } catch (InvalidEmailException $e) { // Handle invalid email format return response()->json(['error' => $e->getMessage()], 400); } catch (ConfigurationException $e) { // Handle configuration issues Log::error('Microsoft Graph configuration error: ' . $e->getMessage()); return response()->json(['error' => 'Service unavailable'], 503); } catch (RequestException $e) { // Handle API request failures Log::error('Microsoft Graph API error: ' . $e->getMessage()); return response()->json(['error' => 'External service error'], 502); }
Configuration Validation
The package automatically validates configuration on boot:
// If configuration is missing or invalid, a ConfigurationException will be thrown // Example error messages: // "Microsoft Graph configuration 'TENANT_ID' is not set. Please ensure MICROSOFT_GRAPH_TENANT_ID is set in your .env file." // "Microsoft Graph configuration 'timezone' is invalid: Invalid timezone identifier"
Advanced Features
Token Caching
Access tokens are automatically cached with a 5-minute buffer before expiry. This significantly improves performance by preventing redundant OAuth requests.
To manually clear the token cache (useful for testing):
$graph = new MicrosoftGraph(); $graph->clearTokenCache();
Custom Timezone
Set a custom timezone for calendar operations in your .env:
APP_TIMEZONE=America/New_York
Or directly in the config file:
'timezone' => 'Europe/London',
Data Transfer Objects
All responses are returned as strongly-typed Spatie Data objects:
$user = MicrosoftGraph::users()->find('john.doe@company.com'); // Full IDE autocomplete support $user->displayName; // string $user->accountEnabled; // bool $user->businessPhones; // array $user->interests; // array|null
Testing
The package includes factories and helpers for testing. You can mock the Microsoft Graph API in your tests:
use Illuminate\Support\Facades\Http; public function test_user_retrieval() { Http::fake([ 'graph.microsoft.com/*' => Http::response([ 'value' => [ [ 'displayName' => 'Test User', 'mail' => 'test@example.com', // ... other fields ] ] ], 200) ]); $users = MicrosoftGraph::users()->get(); $this->assertCount(1, $users); $this->assertEquals('Test User', $users->first()->displayName); }
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Security
If you discover any security-related issues, please email the package author instead of using the issue tracker.
Credits
License
The MIT License (MIT). Please see License File for more information.
Support
For support, please open an issue on GitHub or contact the maintainer.
Links
- Microsoft Graph API Documentation: https://learn.microsoft.com/en-us/graph/
- Azure Portal: https://portal.azure.com
- Package Repository: https://github.com/prasadchinwal/microsoft-graph