dcblogdev/laravel-microsoft-graph
A Laravel package for integrating the Microsoft Graph API, simplifying OAuth authentication and giving your app easy access to Microsoft 365 data such as users, mail, calendars, and files.
The package (dcblogdev/laravel-microsoft-graph) is a thin, opinionated wrapper around Microsoft Graph: token storage + OAuth routes + a fluent HTTP client. Auto-discovery registers the service provider and the MsGraph facade, so the setup is mostly credentials and consent.
composer require dcblogdev/laravel-microsoft-graphphp artisan vendor:publish --tag=msgraph (fall back to --provider="Dcblogdev\MsGraph\MsGraphServiceProvider"). Populate the client ID, client secret, tenant ID and redirect URI — the env key names in the shipped config differ from the config keys (e.g. client_secret is fed by MSGRAPH_SECRET_ID), so read the published file rather than guessing.database or cache). For database, publish and run the migrations — you get an msgraph_tokens table keyed to the authenticated user.First use case: redirect the user to /msgraph/oauth, let /msgraph/oauth/callback land, then hit the API:
use Dcblogdev\MsGraph\Facades\MsGraph;
if (! MsGraph::isConnected()) {
return redirect()->route('msgraph.oauth');
}
$me = MsGraph::get('me');
Protect your app routes with the package's MsGraphAuthenticated middleware (alias it in bootstrap/app.php on Laravel 11+/13). First places to look: config/msgraph.php, the MsGraph facade, the token model, and the v4 documentation added in 4.0.9 (PR #113).
MsGraph is static-ish and hard to fake. Put a GraphService/MicrosoftGraph class behind an interface, inject the facade, and expose domain methods (sendWelcomeMail, listDriveItems). Controllers stay clean and tests can swap a fake.MsGraph::isConnected() → redirect to msgraph.oauth — keeps re-auth flows out of every action. On the way back, the callback only needs to redirect to your intended destination.MsGraph::get/post/... instead of pulling a raw token. Call refreshToken() explicitly in long-running jobs, and logout() on user disconnect (this also clears the cached/DB token — don't leave a stale cache key behind).$select, $filter, $top, $orderby, $expand as array keys on get(). Graph rejects unencoded $/spaces; keep filters in a builder helper rather than string-concatenating in controllers.@odata.nextLink. Loop on it (passing the full URL back into get()) inside a queued job, not a web request. Persist @odata.deltaLink if you need incremental sync.$batch with up to 20 sub-requests — one round trip, much lower 429 risk than N sequential calls.msgraph mail transport; set MAIL_MAILER=msgraph and grant Mail.Send. This is the escape hatch for environments where SMTP is blocked, and it gives you the Graph send-and-save-to-Sent-Items behaviour for free.root, /Inbox, nested paths). This is the area touched by the 4.0.9 variable rename — pass names directly instead of pre-resolving IDs.Authenticatable typing is the real breaking-ish change in 4.0.9. The user type was refactored from User/TestUser to Illuminate\Contracts\Auth\Authenticatable (PR #111). If you extended the token store, overrode a method, or type-hinted the concrete class, update your signatures. Normal facade usage is unaffected.$folderIdOrName rename (PR #110) is a bug fix — folder lookups now correctly honour name-or-ID. If you'd worked around it by resolving folder IDs manually before calling, simplify the code but re-verify against shared mailboxes, where folder paths differ from personal ones.composer update actually pulls 4.0.9+ rather than resolving an older tag against L13.common vs a specific tenant ID changes consent and guest-account behaviour..default scope, and no user in context — mixing the two produces opaque 401s.logout() and re-auth, or an admin must pre-consent in the portal. Plan the full scope list up front.Retry-After; in queued jobs ->release($seconds) instead of retrying immediately. Retrying blindly is how you get throttled into a multi-hour lockout.error.code plus the request-id response header — Microsoft support will ask for it.beta endpoints (MsGraph::setApiVersion('beta')) are the only path to some newer features, but they change without notice. Isolate beta calls so a breaking change is one file, not fifty.token_store between database and cache; bind a custom token store implementation; override the package routes/middleware in your own route file if the built-in OAuth endpoints don't match your UX. The v4 docs added in 4.0.9 (PR #113) are the current reference — older blog posts and v2/v3 snippets frequently reference renamed variables and config keys.How can I help you explore Laravel packages today?