gmail

package
v0.0.0-...-628cd94 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 1, 2024 License: GPL-3.0 Imports: 18 Imported by: 13

README

gmail

gmail is a wrapper Go library for working with the Google gmail API.

It is in active development and makes no guarantees about API stability. The long-term goal is to create a standard mail interface we can use across all email clients, like Gmail and Outlook.

SelfDoc

Auto-generated code documentation to make the repository easier to navigate and contribute to.

Last Updated: 2023-05-15

The gmail directory is for working with the Google Gmail API through a Go library. It includes functions for forwarding and fetching messages, managing labels, and handling errors. The directory also contains subdirectories for managing Gmail labels and retrieving information from Gmail messages.

Files
clone.go

This file contains the CloneMessage function, which is used to clone a message from one inbox to another. Cloning preserves the original message sender, recipient, and all other headers. The function also supports recipient anonymization.

errors.go

This file contains functions and default values for handling various types of errors that may be encountered when interacting with Gmail through the Google API, including OAuth2 errors, Google API errors, rate limit errors, and not found errors. Additionally, it provides a function for executing a function with retries using an exponential backoff if a rate limit error is encountered.

errors_test.go

This file contains multiple test functions for different error identification functions in the gmail package. The tests check if errors are correctly identified as OAuth2, Google API, rate limit, or googleapi.Error with a http.StatusNotFound code. Additionally, there is a test function that iterates through a list of test cases and checks if the number of calls matches the expected value and if the error matches the expected error.

fwd.go

This file contains structs and functions for forwarding messages in Gmail. It includes methods for retrieving headers and message content, as well as functions for creating raw forwarded messages and sendable Gmail messages.

gmail.go

This file implements a Go library for working with the Google Gmail API. It includes convenience methods for interacting with Gmail, such as retrieving user profile, listing and creating labels, and forwarding and fetching messages. It also includes functions for managing labels, allowing or blocking senders, and fetching or creating labels managed by SRC.

Directories
label

The label directory is for defining and managing Gmail labels used by SRC for organizing and filtering emails. It includes candidate-specific labels for managing job opportunities and blocked emails, as well as labels for recruiters, such as Recruiting and RecruitingOutbound.

message

The message directory is for retrieving and sorting information from Gmail messages, including sender and recipient email addresses, message subject and body, message ID, and label ID. It also includes functions for checking if a message was sent by the current user and returning the time the message was created. Additionally, it contains unit tests for various functions in the message package to ensure they return the expected output.

Documentation

Index

Constants

View Source
const (
	DefaultInitialInterval     = 1 * time.Second
	DefaultRandomizationFactor = 0.5
	DefaultMultiplier          = 3
	DefaultMaxInterval         = 2 * time.Minute
	DefaultMaxElapsedTime      = 20 * time.Minute
)

Default values for ExponentialBackOff. The defaults should be optimized for - Google usage quota periods and limits - Cloud Functions execution time limits

View Source
const (
	// FwdMsgDelimiter is the delimiter used to separate the forwarded message from the original message.
	FwdMsgDelimiter = "---------- Forwarded message ---------"
)

Variables

This section is empty.

Functions

func CloneMessage

func CloneMessage(src *Service, dst *Service, messageID string, dstLabelIds []string) (*gmail.Message, error)

CloneMessage is a convenience function to cloning a message from one inbox to another. On success, it will return the new destination message. Cloning differs from forwarding because it preserves the original message sender, recipient, and all other headers. TODO: Support recipient anonymization (i.e. randomize 'To' header, strings.Replace first and last name).

func ExecuteWithRetries

func ExecuteWithRetries[T any](f func() (T, error)) (T, error)

ExecuteWithRetries executes a function and automatically retries with an exponential back-off if the function rate turns a googleapi rate limit error (IsRateLimitError).

func IsGoogleAPIError

func IsGoogleAPIError(err error) bool

IsGoogleAPIError checks if the error is a googleapi.Error

https://developers.google.com/gmail/api/guides/handle-errors

func IsNotFound

func IsNotFound(err error) bool

IsNotFound checks for a status not found (404) response from a Google API

func IsOAuth2Error

func IsOAuth2Error(err error) bool

IsOAuth2Error checks if the error is an oauth2.RetrieveError. This is useful for detecting expired or revoked access tokens.

func IsRateLimitError

func IsRateLimitError(err error) bool

IsRateLimitError checks for - a status too many requests (429) - a usage limit (403) response - or a temporary 500 response from the Google API

https://developers.google.com/gmail/api/guides/handle-errors#resolve_a_403_error_user_rate_limit_exceeded

func NewExponentialBackOff

func NewExponentialBackOff() *backoff.ExponentialBackOff

NewExponentialBackOff creates an instance of ExponentialBackOff using default values.

Types

type ForwardMessage

type ForwardMessage struct {
	Sender string
	To     string
	Parent *gmail.Message
}

ForwardMessage represents a message to be forwarded.

func (ForwardMessage) Create

func (m ForwardMessage) Create() *gmail.Message

Create a send-able gmail message from a forwarded message

func (ForwardMessage) GetParentHeader

func (m ForwardMessage) GetParentHeader(name string) string

GetParentHeader returns the value of the header with the given name from the parent message. It ignores casing when looking at headers.

func (ForwardMessage) InReplyTo

func (m ForwardMessage) InReplyTo() string

InReplyTo returns the contents of the "In-Reply-To:" field of the message to which this one is a reply (the "parent message"). It follows the spec described in https://tools.ietf.org/html/rfc2822#section-3.6.4

The "In-Reply-To:" field will contain the contents of the "Message-ID:" field of the message to which this one is a reply (the "parent message"). If there is more than one parent message, then the "In-Reply-To:" field will contain the contents of all of the parents' "Message-ID:" fields. If there is no "Message-ID:" field in any of the parent messages, then the new message will have no "In-Reply-To:" field.

func (ForwardMessage) ParentBody

func (m ForwardMessage) ParentBody() string

ParentBody returns the body of the parent message. Note: We always convert to text/plain. It's simpler to do deal with and is sufficient for our purposes.

func (ForwardMessage) Raw

func (m ForwardMessage) Raw() string

Raw returns the raw RFC-822 compliant forwarded message.

func (ForwardMessage) References

func (m ForwardMessage) References() string

References returns the contents of the "References:" field of the message to which this one is a reply (the "parent message"). It follows the spec described in https://tools.ietf.org/html/rfc2822#section-3.6.4

The "References:" field will contain the contents of the parent's "References:" field (if any) followed by the contents of the parent's "Message-ID:" field (if any). If the parent message does not contain a "References:" field but does have an "In-Reply-To:" field containing a single message identifier, then the "References:" field will contain the contents of the parent's "In-Reply-To:" field followed by the contents of the parent's "Message-ID:" field (if any). If the parent has none of the "References:", "In-Reply-To:", or "Message-ID:" fields, then the new message will have no "References:" field.

type Service

type Service struct {
	*gmail.Service
	UserID string
	// contains filtered or unexported fields
}

Service is a wrapper around the gmail service that adds some convenience methods.

func NewDefaultService

func NewDefaultService(ctx context.Context, auth []byte) (*Service, error)

func NewService

func NewService(ctx context.Context, creds []byte, auth []byte) (*Service, error)

func (*Service) BlockMessage

func (s *Service) BlockMessage(id string, labels *srclabel.CandidateLabels) error

BlockMessage blocks a message by moving moving out of the users inbox and into the block graveyard

func (*Service) CreateLabel

func (s *Service) CreateLabel(l *gmail.Label) (*gmail.Label, error)

func (*Service) ForwardEmail

func (s *Service) ForwardEmail(messageID, to string) (*gmail.Message, error)

ForwardEmail is a good enough implementation of forwarding an email in the same format as the gmail client. It is good enough because it doesn't naively handle HTML mime-type content or when there are multiple parent messages. This is sufficient for our purposes.

func (*Service) GetMessage

func (s *Service) GetMessage(id string) (*gmail.Message, error)

GetMessage() fetches a message by ID It is a convenience method that wraps the gmail API call. It opens opportunities for caching and rate-limiting handling

func (*Service) GetOrCreateCandidateLabels

func (s *Service) GetOrCreateCandidateLabels() (*srclabel.CandidateLabels, error)

GetOrCreateCandidateLabels fetches or creates all of the labels managed by SRC Label IDs are unique to each gmail account, so we need to list all labels and match based off names.

func (*Service) GetOrCreateLabel

func (s *Service) GetOrCreateLabel(l *gmail.Label) (*gmail.Label, error)

func (*Service) GetOrCreateRecruiterLabels

func (s *Service) GetOrCreateRecruiterLabels() (*srclabel.RecruiterLabels, error)

GetOrCreateRecruiterLabels fetches or creates all of the labels managed by SRC Label IDs are unique to each gmail account, so we need to list all labels and match based off names.

func (*Service) GetThread

func (s *Service) GetThread(id, format string) (*gmail.Thread, error)

GetThread() fetches a thread by ID with messages in the given format See https://developers.google.com/gmail/api/reference/rest/v1/users.threads/get#Format for format values

It is a convenience method that wraps the gmail API call It opens opportunities for caching and rate-limiting handling

func (*Service) IsSenderAllowed

func (s *Service) IsSenderAllowed(sender string) (bool, error)

IsSenderAllowed checks if message is on the user's allow list

func (*Service) IsSenderBlocked

func (s *Service) IsSenderBlocked(sender string) (bool, error)

IsSenderBlocked checks if message is on the user's block list

func (*Service) ListLabels

func (s *Service) ListLabels() (*gmail.ListLabelsResponse, error)

func (*Service) Profile

func (s *Service) Profile() (*gmail.Profile, error)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL