Documentation
¶
Overview ¶
Package gapi is a thin raw REST client for the Google Docs and Drive APIs. Requests are built by hand so Developer Preview fields that the generated client lacks can be sent; responses decode into the generated types where they exist. No MCP imports live here.
Index ¶
- Constants
- Variables
- func Class(err error) string
- func Classes() []string
- func QuoteDriveValue(s string) string
- func ShortID(id string) string
- type APIError
- type About
- type AuthError
- type BatchUpdateRequest
- type BatchUpdateResponse
- type Client
- func (c *Client) About(ctx context.Context) (*User, error)
- func (c *Client) BatchUpdate(ctx context.Context, id string, req *BatchUpdateRequest) (*BatchUpdateResponse, error)
- func (c *Client) CreateComment(ctx context.Context, fileID, content, quote string) (*DriveComment, error)
- func (c *Client) CreateDocument(ctx context.Context, title string) (*gdocs.Document, error)
- func (c *Client) CreateReply(ctx context.Context, fileID, commentID, content, action string) (*DriveReply, error)
- func (c *Client) DeleteComment(ctx context.Context, fileID, commentID string) error
- func (c *Client) DeleteReply(ctx context.Context, fileID, commentID, replyID string) error
- func (c *Client) Export(ctx context.Context, id, mimeType string) ([]byte, error)
- func (c *Client) ExportRevision(ctx context.Context, fileID, revisionID, mimeType string) ([]byte, error)
- func (c *Client) GetComment(ctx context.Context, fileID, commentID string) (*DriveComment, error)
- func (c *Client) GetDocument(ctx context.Context, id string, o GetOptions) (*DocumentResult, error)
- func (c *Client) GetFile(ctx context.Context, id string) (*File, error)
- func (c *Client) ListComments(ctx context.Context, fileID string, includeDeleted bool) ([]*DriveComment, error)
- func (c *Client) ListRevisions(ctx context.Context, fileID string) ([]*Revision, error)
- func (c *Client) SearchFiles(ctx context.Context, q string, limit int, pageToken string) (*FileList, error)
- func (c *Client) UpdateComment(ctx context.Context, fileID, commentID, content string) (*DriveComment, error)
- func (c *Client) UpdateReply(ctx context.Context, fileID, commentID, replyID, content string) (*DriveReply, error)
- type DocumentResult
- type DriveComment
- type DriveReply
- type File
- type FileCapabilities
- type FileList
- type GetOptions
- type NoCredentials
- type Options
- type QuotedText
- type RetryPolicy
- type Revision
- type User
- type WriteControl
Constants ¶
const ( DefaultDocsBaseURL = "https://docs.googleapis.com" DefaultDriveBaseURL = "https://www.googleapis.com/drive/v3" )
Default endpoints.
const ( SuggestionsInline = "SUGGESTIONS_INLINE" SuggestionsPreviewAccepted = "PREVIEW_SUGGESTIONS_ACCEPTED" CommentsIncluded = "COMMENTS_VIEW_MODE_INCLUDED" // Developer Preview )
View modes for documents.get.
const CommentFields = "id,content,htmlContent,author(displayName,emailAddress),createdTime,modifiedTime,resolved,deleted,anchor,quotedFileContent,replies(" + ReplyFields + ")"
CommentFields is what the comment calls ask for.
const DocumentMimeType = "application/vnd.google-apps.document"
DocumentMimeType is the Drive MIME type of a Google Doc.
const FileFields = "" /* 188-byte string literal not displayed */
FileFields is what GetFile asks Drive for.
const ReplyFields = "id,content,author(displayName,emailAddress),createdTime,action,deleted"
ReplyFields is what reply calls ask for.
const RevisionFields = "id,mimeType,modifiedTime,keepForever,lastModifyingUser(displayName,emailAddress)"
RevisionFields is what ListRevisions asks for per revision.
const SearchFields = "" /* 151-byte string literal not displayed */
SearchFields is what SearchFiles asks for per file.
Variables ¶
var ( ErrMissingScope = errors.New("missing scope") ErrForbidden = errors.New("forbidden") ErrNotFound = errors.New("not found") ErrRateLimited = errors.New("rate limited") ErrServer = errors.New("server error") ErrInvalid = errors.New("invalid request") ErrConflict = errors.New("revision conflict") ErrNetwork = errors.New("network error") ErrAmbiguous = errors.New("ambiguous outcome") ErrUnexpected = errors.New("unexpected response") // ErrNoCredentials is the token-source error when no login exists. ErrNoCredentials = errors.New("no credentials stored; run `google-docs-mcp login`") )
Sentinel error classes. Every error returned by the client wraps exactly one of them so callers can branch with errors.Is.
var ExportMimeTypes = map[string]string{
"pdf": "application/pdf",
"docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"odt": "application/vnd.oasis.opendocument.text",
"rtf": "application/rtf",
"txt": "text/plain",
"html": "text/html",
"md": "text/markdown",
"epub": "application/epub+zip",
}
ExportMimeTypes maps short format names to Drive export MIME types.
Functions ¶
func Class ¶
Class returns a short lower-case class name for an error, for LLM-facing messages. Every value it returns is in Classes, and service.Classes is the whole vocabulary this server speaks.
func Classes ¶ added in v0.9.3
func Classes() []string
Classes lists every class Class can return, so a test can check this half of the vocabulary against the service's list rather than trusting two comments to agree.
func QuoteDriveValue ¶
QuoteDriveValue escapes a string for use inside single quotes in a Drive query.
func ShortID ¶
ShortID shortens a document or file id. It is for a filename a person has to recognise, never for a log: §12 promises a log carries nothing about the document, and six characters of an id is still six characters of an id.
It used to end a shortened id with U+2026, which reads well in prose and badly in a filename: an outside user reported it, and they were right. A character outside ASCII in a name a person has to type, tab complete, quote in a shell or move between filesystems buys nothing here — the id fragment is there to tell two exports of the same title apart, and it does that without announcing that it is short.
Types ¶
type APIError ¶
type APIError struct {
Status int
RPC string // e.g. NOT_FOUND, PERMISSION_DENIED
Reason string // e.g. ACCESS_TOKEN_SCOPE_INSUFFICIENT
Message string
Method string
Path string
}
APIError is a non-2xx response from Google, decoded from the standard error envelope.
type About ¶
type About struct {
User *User `json:"user,omitempty"`
}
About is the about.get response subset we read.
type AuthError ¶
AuthError is a failure to obtain an access token (revoked or expired refresh token, bad client secret).
type BatchUpdateRequest ¶
type BatchUpdateRequest struct {
Requests []json.RawMessage `json:"requests"`
WriteControl *WriteControl `json:"writeControl,omitempty"`
}
BatchUpdateRequest is the body of documents.batchUpdate. Requests are pre-marshalled so GA and preview request types share one path.
type BatchUpdateResponse ¶
type BatchUpdateResponse struct {
DocumentID string `json:"documentId"`
Replies []json.RawMessage `json:"replies"`
WriteControl *WriteControl `json:"writeControl"`
Raw json.RawMessage `json:"-"`
}
BatchUpdateResponse is the decoded reply.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client talks to Google with one user's credentials.
func New ¶
func New(ts oauth2.TokenSource, o Options) *Client
New builds a client whose requests carry tokens from ts.
func (*Client) BatchUpdate ¶
func (c *Client) BatchUpdate(ctx context.Context, id string, req *BatchUpdateRequest) (*BatchUpdateResponse, error)
BatchUpdate applies requests atomically. A network failure after the request was sent is reported as ErrAmbiguous, never retried blindly.
func (*Client) CreateComment ¶
func (c *Client) CreateComment(ctx context.Context, fileID, content, quote string) (*DriveComment, error)
CreateComment adds a Drive comment quoting text. The Docs UI shows it unanchored (with the quote) because Drive anchors are opaque to Docs.
func (*Client) CreateDocument ¶
CreateDocument creates an empty document with the title and returns it.
func (*Client) CreateReply ¶ added in v0.2.0
func (c *Client) CreateReply(ctx context.Context, fileID, commentID, content, action string) (*DriveReply, error)
CreateReply posts a reply on a comment thread. action is "" for a plain reply, "resolve" to resolve the thread or "reopen" to reopen it.
func (*Client) DeleteComment ¶ added in v0.2.0
DeleteComment deletes a comment thread. Drive keeps it listable with includeDeleted=true.
func (*Client) DeleteReply ¶ added in v0.2.0
DeleteReply deletes one reply of a thread.
func (*Client) Export ¶
Export downloads the document converted to the MIME type. Google caps exports at 10 MB.
func (*Client) ExportRevision ¶ added in v0.2.0
func (c *Client) ExportRevision(ctx context.Context, fileID, revisionID, mimeType string) ([]byte, error)
ExportRevision exports one revision of a document through files.download, the only Drive method that takes a revisionId for Docs files. It starts a long-running operation, polls it, then fetches the content it names. The content URL must stay on Google's hosts.
The POST that starts it is a read: it creates nothing in the person's Drive, so repeating it costs an export, not a duplicate. That is what kindRead now means — retryable on any transient failure — so a POST that does change something must not borrow it.
func (*Client) GetComment ¶ added in v0.2.0
GetComment returns one comment thread with its replies.
func (*Client) GetDocument ¶
func (c *Client) GetDocument(ctx context.Context, id string, o GetOptions) (*DocumentResult, error)
GetDocument fetches a document with tabs content.
func (*Client) ListComments ¶
func (c *Client) ListComments(ctx context.Context, fileID string, includeDeleted bool) ([]*DriveComment, error)
ListComments returns every comment thread on the file.
func (*Client) ListRevisions ¶ added in v0.2.0
ListRevisions returns every revision of the file, oldest first as Drive orders them.
func (*Client) SearchFiles ¶
func (c *Client) SearchFiles(ctx context.Context, q string, limit int, pageToken string) (*FileList, error)
SearchFiles runs a Drive query (the caller builds and escapes q) across My Drive and shared drives, newest first.
func (*Client) UpdateComment ¶ added in v0.4.0
func (c *Client) UpdateComment(ctx context.Context, fileID, commentID, content string) (*DriveComment, error)
UpdateComment rewrites a comment's own text. Only its author may; Drive answers 403 otherwise.
func (*Client) UpdateReply ¶ added in v0.4.0
func (c *Client) UpdateReply(ctx context.Context, fileID, commentID, replyID, content string) (*DriveReply, error)
UpdateReply rewrites one reply's text, with the same author rule.
type DocumentResult ¶
DocumentResult is a decoded documents.get response. Comment and suggestion threads (Developer Preview) are on the document itself.
type DriveComment ¶
type DriveComment struct {
ID string `json:"id,omitempty"`
Content string `json:"content,omitempty"`
HTMLContent string `json:"htmlContent,omitempty"`
Author *User `json:"author,omitempty"`
CreatedTime string `json:"createdTime,omitempty"`
ModifiedTime string `json:"modifiedTime,omitempty"`
Resolved bool `json:"resolved,omitempty"`
Deleted bool `json:"deleted,omitempty"`
Anchor string `json:"anchor,omitempty"`
QuotedFileContent *QuotedText `json:"quotedFileContent,omitempty"`
Replies []*DriveReply `json:"replies,omitempty"`
}
DriveComment is a Drive API comment thread on a file.
type DriveReply ¶
type DriveReply struct {
ID string `json:"id,omitempty"`
Content string `json:"content,omitempty"`
Author *User `json:"author,omitempty"`
CreatedTime string `json:"createdTime,omitempty"`
Action string `json:"action,omitempty"`
Deleted bool `json:"deleted,omitempty"`
}
DriveReply is one reply in a thread.
type File ¶
type File struct {
ID string `json:"id,omitempty"`
Name string `json:"name,omitempty"`
MimeType string `json:"mimeType,omitempty"`
CreatedTime string `json:"createdTime,omitempty"`
ModifiedTime string `json:"modifiedTime,omitempty"`
Owners []*User `json:"owners,omitempty"`
LastModifyingUser *User `json:"lastModifyingUser,omitempty"`
WebViewLink string `json:"webViewLink,omitempty"`
Version string `json:"version,omitempty"`
Trashed bool `json:"trashed,omitempty"`
Capabilities *FileCapabilities `json:"capabilities,omitempty"`
}
File is the files.get response subset we read.
type FileCapabilities ¶
type FileCapabilities struct {
CanEdit bool `json:"canEdit,omitempty"`
CanComment bool `json:"canComment,omitempty"`
}
FileCapabilities are the caller's rights on a file.
type FileList ¶
type FileList struct {
Files []*File `json:"files"`
NextPageToken string `json:"nextPageToken,omitempty"`
}
FileList is a page of files.list results.
type GetOptions ¶
GetOptions select what documents.get returns. Tabs content is always requested because every other choice loses information.
type NoCredentials ¶
type NoCredentials struct{ Reason error }
NoCredentials is a token source that always fails with ErrNoCredentials so a server without a login still starts and answers every call with an actionable auth error.
type Options ¶
type Options struct {
// BaseTransport sits under the OAuth transport. nil uses http.DefaultTransport.
BaseTransport http.RoundTripper
DocsBaseURL string
DriveBaseURL string
Logger *slog.Logger
// Timeout applies per attempt.
Timeout time.Duration
Retry RetryPolicy
// Limiters stay under the per-user quotas (300 reads and 60 writes per minute).
ReadLimiter *rate.Limiter
WriteLimiter *rate.Limiter
UserAgent string
// Sleep is replaced in tests.
Sleep func(context.Context, time.Duration) error
// AllowURL decides which URLs receive credentials; nil means HTTPS to
// Google's API and content hosts only. Tests point it at their server.
AllowURL func(u *url.URL) bool
}
Options configure a Client. Zero values are production defaults.
type QuotedText ¶
type QuotedText struct {
MimeType string `json:"mimeType,omitempty"`
Value string `json:"value,omitempty"`
}
QuotedText is the text a comment refers to.
type RetryPolicy ¶
RetryPolicy bounds retries for transient failures.
func DefaultRetry ¶
func DefaultRetry() RetryPolicy
DefaultRetry is exponential backoff with jitter, capped at 30 seconds.
type Revision ¶ added in v0.2.0
type Revision struct {
ID string `json:"id,omitempty"`
MimeType string `json:"mimeType,omitempty"`
ModifiedTime string `json:"modifiedTime,omitempty"`
KeepForever bool `json:"keepForever,omitempty"`
LastModifyingUser *User `json:"lastModifyingUser,omitempty"`
}
Revision is a Drive revision (version history entry) of a document.
type User ¶
type User struct {
DisplayName string `json:"displayName,omitempty"`
EmailAddress string `json:"emailAddress,omitempty"`
}
User is a Drive user reference.
type WriteControl ¶
type WriteControl struct {
RequiredRevisionID string `json:"requiredRevisionId,omitempty"`
TargetRevisionID string `json:"targetRevisionId,omitempty"`
WriteMode string `json:"writeMode,omitempty"` // "SUGGEST" (preview)
}
WriteControl guards a batchUpdate against concurrent edits and, in Developer Preview, selects suggestion mode.