gsheet

package module
v0.0.0-...-8254718 Latest Latest
Warning

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

Go to latest
Published: Feb 8, 2025 License: MIT Imports: 16 Imported by: 0

README

gsheet: Access and manipulate Google Sheets Spreadsheets, and Gmail emails using Googles official Sheets API and Gmail API

A package for the go programming language

gsheet features:

  • Access

    • Connect/Authenticate with sheets and/or gmail api using your credentials and recieve a refresh token
    • Auto refresh the token every 23 hours by default (can be adjusted)
  • Sheets

    • Append row to spread sheet in google Sheets
    • Read data from spread sheet
  • Gmail

    • Send emails
    • Mark emails (read/unread/important/etc)
    • Get labels used in inbox
    • Get emails by query (eg "in:sent after:2025/01/01 before:2025/01/30")
    • Get email metadata
    • Get email main body ("text/plain", "text/html")
    • Get the number of unread messages
    • Convert email dates to human readable format

Validating credentials and connecting to the API:

It's important to note that for this module to work properly, you need to enable the sheets and Gmail API(s) in Google Cloud Services, and download the credentials.json file provided in the APIs and Services section of the Google Cloud console.

If you're unsure how to do any of that or have never used a Google Service API such as the SheetsAPI or GmailAPI, please see the following link:

https://developers.google.com/sheets/api/quickstart/go

That link will walk you through enabling the sheets API through the Google Cloud console, and creating and downloading your credentials.json file.

Once you have enabled the API, download the credentials.json file and store somewhere safe. You can connect to the Gmail and Sheets APIs using the following:

var access *gsheet.Access = gsheet.NewAccess(
        // Location of credentials.json NOTE: ***Get this from Google***
        os.Getenv("HOME")+"/credentials/credentials.json",

        // Location of token.json, or where/what it should be saved /as.
        // NOTE: ***This will automatically download if you don't have it***
        os.Getenv("HOME")+"/credentials/token.json",

        // Provided here are the scopes. Scopes are used by the API to 
        // determine your privilege level. 
        []string{
                gmail.GmailComposeScope,
                sheets.SpreadsheetsScope,
        })

// NOTE: Token will be refreshed every 23 hours by default, as long as this app
// remains running.

// connect to gmail
access.Gmail()
// connect to sheets
access.Sheets()

Example Usage

Getting *Access

Setting up credentials/tokens and refreshing them
package main

import (
        "fmt"
        "log"

        "github.com/sigma-firma/gsheet"
)

// Instantiate a new *Access struct with essential values
var access *gsheet.Access = gsheet.NewAccess(
        os.Getenv("HOME")+"/credentials/credentials.json",
        os.Getenv("HOME")+"/credentials/quickstart.json",
        []string{gmail.GmailComposeScope, sheets.SpreadsheetsScope},
)

// Connect to the Gmail API
var gm *gsheet.Gmailer = access.Gmail()

// Connect to the Sheets API
var sh *gsheet.Sheeter = access.Gmail()

// This example will error. The rest should be okay.

Sheets

Reading values from a spreadsheet:
package main

import (
        "fmt"
        "log"
        "os"

        "github.com/sigma-firma/gsheet"
        "google.golang.org/api/gmail/v1"
        "google.golang.org/api/sheets/v4"
)
// Instantiate a new *Access struct with essential values
var access *gsheet.Access = gsheet.NewAccess(
        os.Getenv("HOME")+"/credentials/credentials.json",
        os.Getenv("HOME")+"/credentials/token.json",
        []string{
                sheets.SpreadsheetsScope,
        })

func main() {

        sh := access.Sheets()

        // Prints the names and majors of students in a sample spreadsheet:
        // https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit
        sh.Readables = make(map[string]*gsheet.SpreadSheet)
        sh.Readables["testsheet"] = &gsheet.SpreadSheet{
        // The spreadsheet ID can be found in the URL of the spreadsheet. A
        // bunch a random bs.
                ID:        "SPEADSHEET_ID_GOES_HERE",
                ReadRange: "Class Data!A2:E",
        }

        resp, err := sh.Read(sh.Readables["testsheet"])
        if err != nil {
                log.Fatalf("Unable to retrieve data from sheet: %v", err)
        }

        if len(resp.Values) == 0 {
                fmt.Println("No data found.")
        } else {
                fmt.Println("Name, Major:")
                for _, row := range resp.Values {
                        // Print columns A and E, which correspond to indices 0 and 4.
                        fmt.Printf("%s, %s\n", row[0], row[4])
                }
        }
}
Writing values to a spreadsheet:
package main

import (
        "log"
        "os"

        "github.com/sigma-firma/gsheet"
        "google.golang.org/api/gmail/v1"
        "google.golang.org/api/sheets/v4"
)


// Instantiate a new *Access struct with essential values
var access *gsheet.Access = gsheet.NewAccess(
        os.Getenv("HOME")+"/credentials/credentials.json",
        os.Getenv("HOME")+"/credentials/token.json",
        []string{
                sheets.SpreadsheetsScope,
        })

func main() {
        // Connect to the API
        sh := access.Sheets()

        var row []interface{} = []interface{}{"hello A1", "world B1"}

        var req *gsheet.SpreadSheet = &gsheet.SpreadSheet{
                // The ID can be found in the URL of the spreadsheet when you open it
                // in a web browser
                ID: "SPEADSHEET_ID_GOES_HERE",
                // Docs indicate this should write to the first blank row after this
                // cell.
                WriteRange: "A1",
                Vals:       row,
                // Not sure what it does but I always set it to RAW.
                ValueInputOption: "RAW",
        }
    
        // You know the rest, killer :^)
        _, err := sh.AppendRow(req)
        if err != nil {
                log.Println(err)
        }
}

GMAIL

Check for new unread messages

// Instantiate a new *Access struct with essential values
var access *gsheet.Access = gsheet.NewAccess(
        os.Getenv("HOME")+"/credentials/credentials.json",
        os.Getenv("HOME")+"/credentials/token.json",
        []string{
                gmail.GmailLabelsScope,
                gmail.GmailModifyScope,
        })


func main() {
        gm := access.Gmail()
        // Check if you have any unread messages
        count, err := gm.CheckForUnread()
        if err != nil {
                fmt.Println(err)
        }
        if count >0 {
                fmt.Println("You've got mail.")
        }
}

Query
package main

import (
        "context"
        "fmt"

        "github.com/sigma-firma/gmailAPI"
        "github.com/sigma-firma/gm"
        gmail "google.golang.org/api/gmail/v1"
)

// Instantiate a new *Access struct with essential values
var access *gsheet.Access = gsheet.NewAccess(
        os.Getenv("HOME")+"/credentials/credentials.json",
        os.Getenv("HOME")+"/credentials/token.json",
        []string{
                gmail.GmailComposeScope,
                gmail.GmailLabelsScope,
                gmail.GmailModifyScope,
        })


func main() {
        gm := access.Gmail()
        msgs, err := gm.Query("category:forums after:2025/01/01 before:2025/01/30")
        if err != nil {
                fmt.Println(err)
        }

        // Range over the messages
        for _, msg := range msgs {
                fmt.Println("========================================================")
                time, err := gm.ReceivedTime(msg.InternalDate)
                if err != nil {
                        fmt.Println(err)
                }
                fmt.Println("Date: ", time)
                md := gm.GetPartialMetadata(msg)
                fmt.Println("From: ", md.From)
                fmt.Println("Sender: ", md.Sender)
                fmt.Println("Subject: ", md.Subject)
                fmt.Println("Delivered To: ", md.DeliveredTo)
                fmt.Println("To: ", md.To)
                fmt.Println("CC: ", md.CC)
                fmt.Println("Mailing List: ", md.MailingList)
                fmt.Println("Thread-Topic: ", md.ThreadTopic)
                fmt.Println("Snippet: ", msg.Snippet)
                body, err := gm.GetBody(msg, "text/plain")
                if err != nil {
                        fmt.Println(err)
                }
                fmt.Println(body)
        }
}

Sending mail
package main

import (
        "context"
        "log"

        "github.com/sigma-firma/gmailAPI"
        "github.com/sigma-firma/gm"
        gmail "google.golang.org/api/gmail/v1"
)

// Instantiate a new *Access struct with essential values
var access *gsheet.Access = gsheet.NewAccess(
        os.Getenv("HOME")+"/credentials/credentials.json",
        os.Getenv("HOME")+"/credentials/token.json",
        []string{
                gmail.GmailComposeScope,
                gmail.GmailLabelsScope,
                gmail.GmailSendScope,
                gmail.GmailModifyScope,
        })


func main() {
        // Create a message
        var msg *gsheet.Msg = &gsheet.Msg{
                From:    "me",  // the authenticated user
                To:      "leadership@firma.com",
                Subject: "testing",
                Body:    "testing gmail api. lmk if you get this scott",
        }

        // send the email with the message
        err := msg.Send()
        if err != nil {
                log.Println(err)
        }
}
Marking emails

// Instantiate a new *Access struct with essential values
var access *gsheet.Access = gsheet.NewAccess(
        os.Getenv("HOME")+"/credentials/credentials.json",
        os.Getenv("HOME")+"/credentials/token.json",
        []string{
                gmail.GmailLabelsScope,
                gmail.GmailModifyScope,
        })


func main() {
        // Connect to the gmail API service.
        gm := access.Gmail()

        msgs, err := gm.Query("category:forums after:2025/01/01 before:2025/01/30")
        if err != nil {
                fmt.Println(err)
        }

        req := &gmail.ModifyMessageRequest{
                RemoveLabelIds: []string{"UNREAD"},
                AddLabelIds: []string{"OLD"}
        }

        // Range over the messages
        for _, msg := range msgs {
                msg, err := gm.MarkAs(msg, req)
        }
}

Mark all "unread" emails as "read"

// Instantiate a new *Access struct with essential values
var access *gsheet.Access = gsheet.NewAccess(
        os.Getenv("HOME")+"/credentials/credentials.json",
        os.Getenv("HOME")+"/credentials/token.json",
        []string{
                gmail.GmailComposeScope,
                gmail.GmailLabelsScope,
                gmail.GmailModifyScope,
        })


func main() {
        // Connect to the gmail API service.
        gm := access.Gmail()
        gm.MarkAllAsRead()
}
Getting labels

// Instantiate a new *Access struct with essential values
var access *gsheet.Access = gsheet.NewAccess(
        os.Getenv("HOME")+"/credentials/credentials.json",
        os.Getenv("HOME")+"/credentials/token.json",
        []string{
                gmail.GmailLabelsScope,
        })


func main() {
        // Connect to the gmail API service.
        gm := access.Gmail()
        labels, err := gm.GetLabels()
        if err != nil {
                fmt.Println(err)
        }
        for _, label := range labels {
                fmt.Println(label)
        }
}

Metadata

// Instantiate a new *Access struct with essential values
var access *gsheet.Access = gsheet.NewAccess(
        os.Getenv("HOME")+"/credentials/credentials.json",
        os.Getenv("HOME")+"/credentials/token.json",
        []string{
                gmail.GmailComposeScope,
                gmail.GmailLabelsScope,
                gmail.GmailModifyScope,
        })


func main() {
        // Connect to the gmail API service.
        gm := access.Gmail()

        msgs, err := gm.Query("category:forums after:2025/01/01 before:2025/01/30")
        if err != nil {
                fmt.Println(err)
        }

        // Range over the messages
        for _, msg := range msgs {
                fmt.Println("========================================================")
                md := gm.GetPartialMetadata(msg)
                fmt.Println("From: ", md.From)
                fmt.Println("Sender: ", md.Sender)
                fmt.Println("Subject: ", md.Subject)
                fmt.Println("Delivered To: ", md.DeliveredTo)
                fmt.Println("To: ", md.To)
                fmt.Println("CC: ", md.CC)
                fmt.Println("Mailing List: ", md.MailingList)
                fmt.Println("Thread-Topic: ", md.ThreadTopic)
        }
}

Getting the email body

// Instantiate a new *Access struct with essential values
var access *gsheet.Access = gsheet.NewAccess(
        os.Getenv("HOME")+"/credentials/credentials.json",
        os.Getenv("HOME")+"/credentials/token.json",
        []string{
                gmail.GmailComposeScope,
                gmail.GmailLabelsScope,
                gmail.GmailModifyScope,
        })


func main() {
        // Connect to the gmail API service.
        gm := access.Gmail()
        msgs, err := gm.Query("category:forums after:2025/01/01 before:2025/01/30")
        if err != nil {
                fmt.Println(err)
        }

        // Range over the messages
        for _, msg := range msgs {
                body, err := gm.GetBody(msg, "text/plain")
                if err != nil {
                        fmt.Println(err)
                }
                fmt.Println(body)
        }
}

Getting the number of unread messages

// Instantiate a new *Access struct with essential values
var access *gsheet.Access = gsheet.NewAccess(
        os.Getenv("HOME")+"/credentials/credentials.json",
        os.Getenv("HOME")+"/credentials/token.json",
        []string{
                gmail.GmailLabelsScope,
        })


// NOTE: to actually view the email text use gm.Query and query for unread
// emails.
func main() {
        // Connect to the gmail API service.
        gm := access.Gmail()
        // num will be -1 on err
        num, err :=        gm.CheckForUnread()
        if err != nil {
                fmt.Println(err)
        }
        fmt.Printf("You have %s unread emails.", num)
}


Converting dates

// Instantiate a new *Access struct with essential values
var access *gsheet.Access = gsheet.NewAccess(
        os.Getenv("HOME")+"/credentials/credentials.json",
        os.Getenv("HOME")+"/credentials/token.json",
        []string{
                gmail.GmailComposeScope,
                gmail.GmailLabelsScope,
                gmail.GmailModifyScope,
        })


// Convert UNIX time stamps to human readable format
func main() {
        // Connect to the gmail API service.
        gm := access.Gmail()

        msgs, err := gm.Query("category:forums after:2025/01/01 before:2025/01/30")
        if err != nil {
                fmt.Println(err)
        }

        // Range over the messages
        for _, msg := range msgs {
                // Convert the date
                time, err := gm.ReceivedTime(msg.InternalDate)
                if err != nil {
                        fmt.Println(err)
                }
                fmt.Println("Date: ", time)
        }
}

Snippet

// Instantiate a new *Access struct with essential values
var access *gsheet.Access = gsheet.NewAccess(
        os.Getenv("HOME")+"/credentials/credentials.json",
        os.Getenv("HOME")+"/credentials/token.json",
        []string{
                gmail.GmailLabelsScope,
        })


// Snippets are not really part of the package but I'm including them in the doc
// because they'll likely be useful to anyone working with this package.
func main() {
        // Connect to the gmail API service.
        gm := access.Gmail()

        msgs, err := gm.Query("category:forums after:2025/01/01 before:2025/01/30")
        if err != nil {
                fmt.Println(err)
        }

        // Range over the messages
        for _, msg := range msgs {
                // this one is part of the api
                fmt.Println(msg.Snippet)
        }
}

More on credentials:

For gsheet to work you must have a gmail account and a file containing your authorization info in the directory you will specify when setting up gsheet. To obtain credentials please see step one of this guide:

https://developers.google.com/gmail/api/quickstart/go

Turning on the gmail API (should be similar for the Sheets API)

  • Use this wizard (https://console.developers.google.com/start/api?id=gmail) to create or select a project in the Google Developers Console and automatically turn on the API. Click Continue, then Go to credentials.

  • On the Add credentials to your project page, click the Cancel button.

  • At the top of the page, select the OAuth consent screen tab. Select an Email address, enter a Product name if not already set, and click the Save button.

  • Select the Credentials tab, click the Create credentials button and select OAuth client ID.

  • Select the application type Other, enter the name "Gmail API Quickstart", and click the Create button.

  • Click OK to dismiss the resulting dialog.

  • Click the file_download (Download JSON) button to the right of the client ID.

  • Move this file to your working directory and rename it client_secret.json.

Documentation

Overview

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Access

type Access struct {
	Context context.Context
	// TokenPath is the path to your token.json file. If you're having trouble
	// authenticating, try deleting this file and running the program
	// again. This should renew your token. If you've never run this
	// program, you may not have a token. This program will generate a
	// token for you. Also see: Access.CredentialsPath
	TokenPath string
	// CredentialsPath is the path to your credentials.json file. This file can
	// be obtained from the API Keys section of Google Cloud Platform. You
	// may need to generate the file and enable the API you're interfacing with
	// from within Google Cloud Platform.
	CredentialsPath string
	// Scopes define what level(s) of access we'll have to the API service.
	// If modifying these scopes, delete your previously saved token.json.
	Scopes []string
	// Config is mostly generated and used by the API.
	Config *oauth2.Config
	// The token is the token used to authenticate with the API, and will need
	// to be refreshed using *Access.Cycle()
	Token *oauth2.Token
	// GmailAPI is used as an alternative access point to the Gmail API
	// service, if you don't wish to use the Gmailer struct. see: gmail.go
	GmailAPI *gmail.Service
	// SheetsAPI is used as an alternative access point to the Sheets API
	// service, if you don't wish to use the Sheeter struct. see: sheets.go
	SheetsAPI *sheets.Service
	// RefreshRate
	RefreshRate *time.Ticker
	// LastRefreshed
	LastRefreshed time.Time
	Client        *http.Client
}

Access contains values used for accessing Googles API services, including access token, API credentials, and scopes

func NewAccess

func NewAccess(credentialsPath, tokenPath string, scopes []string) *Access

NewAccess() instantiates a new *Access struct, initializing it with default values most people will probably need, and authenticated the user, taking them through the manual authentication process as necessary (see READEME.md)

func (*Access) Connect

func (a *Access) Connect(service any)

*Access.Connect(any) connects us to a service. At this time gsheet only supports the Gmail API, the Google Sheets API, or both. Pass either of the following empty (as empty structs):

*gmail.Sevice{} *sheets.Service{}

func (*Access) Cycle

func (a *Access) Cycle(rate time.Duration)

*Access.Cycle(time.Duration) is used to cycle (refresh) the token, if ran with rate = 0 it'll refresh every 23 hours as default.

func (*Access) GetClient

func (a *Access) GetClient() *http.Client

Retrieve a token, saves the token, then returns the generated client.

func (*Access) Gmail

func (a *Access) Gmail() *Gmailer

*Access.Gmail() gives usaccess to the Google Gmail API via *Gmailer.Service

func (*Access) ReadCredentials

func (a *Access) ReadCredentials()

func (*Access) SaveToken

func (a *Access) SaveToken() error

Saves a token to a file path.

func (*Access) Sheets

func (a *Access) Sheets() *Sheeter

*Access.Sheets() gives access to the Google Sheets API via *Sheeter.Service

func (*Access) TokenFromFile

func (a *Access) TokenFromFile() error

Retrieves a token from a local file.

func (*Access) TokenFromWeb

func (a *Access) TokenFromWeb()

Request a token from the web, then returns the retrieved token.

type Gmailer

type Gmailer struct {
	Service *gmail.Service
	Msgs    []*Msg
}

Gmailer is a wrapper around the *gmail.Service type, giving us access to the Google Gmail API service.

func (*Gmailer) CheckByLabel

func (g *Gmailer) CheckByLabel(label string) (int64, error)

*Gmailer.CheckFByLabel() checks for mail matching the specified label.

func (*Gmailer) CheckForUnread

func (g *Gmailer) CheckForUnread() (int64, error)

*Gmailer.CheckForUnread() checks for mail labeled "UNREAD". NOTE: When checking your inbox for unread messages, it's not uncommon for it to return thousands of unread messages that you don't know about. To see them in gmail, query your mail for "label:unread". For CheckForUnread to work properly you need to mark all mail as read either through gmail or through the MarkAllAsRead() function found in this library.

func (*Gmailer) DecodeEmailBody

func (g *Gmailer) DecodeEmailBody(data string) (string, error)

*Gmailer.DecodeEmailBody() is used to decode the email body by converting from URLEncoded base64 to a string.

func (*Gmailer) GetBody

func (g *Gmailer) GetBody(msg *gmail.Message, mimeType string) (string, error)

*Gmailer.GetBody() gets, decodes, and returns the body of the email. It returns an error if decoding goes wrong. mimeType is used to indicate whether you want the plain text or html encoding ("text/html", "text/plain").

func (*Gmailer) GetByID

func (g *Gmailer) GetByID(msgs *gmail.ListMessagesResponse) ([]*gmail.Message, error)

*Gmailer.GetByID() gets emails individually by ID. This is necessary because this is how the gmail API is set [0][1] up apparently (but why?). [0] https://developers.google.com/gmail/api/v1/reference/users/messages/get [1] https://stackoverflow.com/questions/36365172/message-payload-is-always-null-for-all-messages-how-do-i-get-this-data

func (*Gmailer) GetLabels

func (g *Gmailer) GetLabels() (*gmail.ListLabelsResponse, error)

*Gmailer.GetLabels() gets a list of the labels used in the users inbox.

func (*Gmailer) GetMessages

func (g *Gmailer) GetMessages(howMany uint) ([]*gmail.Message, error)

*Gmailer.GetMessages() gets and returns gmail messages

func (*Gmailer) GetPartialMetadata

func (g *Gmailer) GetPartialMetadata(msg *gmail.Message) *PartialMetadata

*Gmailer.GetPartialMetadata() gets some of the useful metadata from the headers.

func (*Gmailer) MarkAllAsRead

func (g *Gmailer) MarkAllAsRead() error

*Gmailer.MarkAllAsRead() removes the UNREAD label from all emails.

func (*Gmailer) MarkAs

func (g *Gmailer) MarkAs(msg *gmail.Message, req *gmail.ModifyMessageRequest) (*gmail.Message, error)

*Gmailer.MarkAs() allows you to mark an email with a specific label using the gmail.ModifyMessageRequest struct.

func (*Gmailer) Query

func (g *Gmailer) Query(query string) ([]*gmail.Message, error)

*Gmailer.Query() queries the inbox for a string following the search style of the gmail online mailbox. example: "in:sent after:2017/01/01 before:2017/01/30"

func (*Gmailer) ReceivedTime

func (g *Gmailer) ReceivedTime(datetime int64) (time.Time, error)

*Gmailer.ReceivedTime() parses and converts a Unix time stamp into a human readable format ().

func (*Gmailer) Send

func (g *Gmailer) Send(m *Msg) error

*Msg.Send() allows us to send mail

type Msg

type Msg struct {
	From      string
	To        string
	Subject   string
	Body      string
	ImagePath string
	MimeType  string
	Markup    string
	Bytes     []byte
	Formed    *gmail.Message
	PartialMetadata
}

Gmailer.Msg is an email message, self explanatory

func (*Msg) Form

func (m *Msg) Form() *gmail.Message

*Msg.Form() forms the message into a proper *gmail.Message type.

type PartialMetadata

type PartialMetadata struct {
	// Sender is the entity that originally created and sent the message
	Sender string
	// From is the entity that sent the message to you (e.g. googlegroups). Most
	// of the time this information is only relevant to mailing lists.
	From string
	// Subject is the email subject
	Subject string
	// Mailing list contains the name of the mailing list that the email was
	// posted to, if any.
	MailingList string
	// CC is the "carbon copy" list of addresses
	CC []string
	// To is the recipient of the email.
	To []string
	// ThreadTopic contains the topic of the thread (e.g. google groups threads)
	ThreadTopic []string
	// DeliveredTo is who the email was sent to. This can contain multiple
	// addresses if the email was forwarded.
	DeliveredTo []string
}

PartialMetadata stores email metadata. Some fields may sound redundant, but in fact have different contexts. Some are slices of string because the ones that have multiple values are still being sorted from those that don't.

type Sheeter

type Sheeter struct {
	Service      *sheets.Service
	DefaultSheet *SpreadSheet
	// just guess what these could be used for
	Writables      map[string]*SpreadSheet
	Readables      map[string]*SpreadSheet
	ReadWriteables map[string]*SpreadSheet
}

gsheet.Sheeter is a wrapper around the *sheets.Service type, giving us access to the Google Sheets API service.

func (*Sheeter) AppendRow

func (s *Sheeter) AppendRow(sht *SpreadSheet) (*sheets.AppendValuesResponse, error)

*Sheeter.AppendRow() is used to append a row to a spreadsheet

func (*Sheeter) Read

func (s *Sheeter) Read(sht *SpreadSheet) (*sheets.ValueRange, error)

*Sheeter.Read() is used to read from a spreadsheet

type SpreadSheet

type SpreadSheet struct {
	ID               string
	WriteRange       string
	Vals             []interface{}
	ReadRange        string
	ValueInputOption string
}

SpreadSheet is passed as the argument to the sheets related functions found herein.

Jump to

Keyboard shortcuts

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