Repository navigation
feat: Gmail integration - #124
Open
claude-for-timatic[bot] wants to merge 10 commits into
Open
claude-for-timatic[bot] wants to merge 10 commits into
claude-for-timatic[bot] wants to merge 10 commits into
Conversation
Users connect their Gmail themselves. Every sent mail and saved draft becomes an event without duration, booked on the customer whose email domain is among the recipients. Only headers are read, never content.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
New
integrations/gmailpackage (Saloon, OAuth likegoogle-calendar). It turns the emails users send and the drafts they save into events without a duration (email_sent,email_draft_saved). The customer comes from the recipients' email domains (#51), and the budget from the existing previous-booking logic.Closes #52
Stacked on #101 (#51). Merge that first; GitHub then retargets this PR to
main.Decisions
gmail.metadatascope: headers only, never bodies. Only To, Cc, Bcc and Subject are requested (metadataHeaders). The subject is stored as the event title, and recipients are only used to resolve the customer.history_id, so nothing is lost.external_id= Gmail thread id. Replies in one thread form one sequence and learn the customer and budget from earlier bookings (Looking up previous bookings of recurring events breaks after event pruning #35).ended_at), becauseeventshas no column for a message id. Two mails in one thread within the same second collapse into one event, which is harmless for 15-minute estimates.email_sent.App\Integrations\Suggestions\CustomerEmailDomainResolver. The resolver moved there in feat: email domains on customers #101, so no architecture exemption is needed. Mail sent only to own-organisation domains gets no customer.WithoutOverlappingper connection (dontRelease, 600s expiry), so two runs can't race onhistory_id.GOOGLE_CLIENT_ID/GOOGLE_CLIENT_SECRET). There is a newGMAIL_REDIRECT_URI.Setup (see
integrations/gmail/README.md)gmail.metadatascope under Data Access. It is a restricted scope: use an Internal audience, or external users see an unverified-app warning until Google verifies the app.https://<api-domain>/gmail/callbackas a redirect URI.GMAIL_REDIRECT_URI=to.env.example. My permissions don't allow touching.env*files.Review
A code-review agent and a UX-review agent reviewed this PR. Applied:
metadataHeaders.WithoutOverlapping.Left out: skipping message ids deleted later in the same history. It only saves a request per stale draft save.
Docs to update after #96
suggestions/events.md:Verification
Full Pest suite green (659), PHPStan 0 errors, Pint applied.