From d943dbfdd796e6c689239f9b0c3c139fb7451f48 Mon Sep 17 00:00:00 2001 From: Robert Sesek Date: Sun, 28 Dec 2025 17:11:22 -0500 Subject: [PATCH] Implement the gmailDestination --- cmd/mailbox-shuffler/dest.go | 47 ++++++++++++++++++++++-- cmd/mailbox-shuffler/mailbox-shuffler.go | 23 +++--------- cmd/mailbox-shuffler/oauth.go | 5 +++ 3 files changed, 54 insertions(+), 21 deletions(-) diff --git a/cmd/mailbox-shuffler/dest.go b/cmd/mailbox-shuffler/dest.go index 6398481..e82647d 100644 --- a/cmd/mailbox-shuffler/dest.go +++ b/cmd/mailbox-shuffler/dest.go @@ -6,9 +6,21 @@ package main -import "go.uber.org/zap" +import ( + "context" + "encoding/base64" + + "go.uber.org/zap" + "google.golang.org/api/gmail/v1" + "google.golang.org/api/option" +) type Destination interface { + // Connect attempts to dial the Destination and return a stateful connection. + Connect(context.Context) (DestinationConnection, error) +} + +type DestinationConnection interface { // AddMessage stores the raw RFC 2822 message body in the destination mail // server. AddMessage([]byte) error @@ -16,7 +28,7 @@ type Destination interface { Close() error } -func NewDestination(config ServerConfig, auth *OAuthServer, log *zap.Logger) Destination { +func NewDestination(config ServerConfig, auth OAuthServer, log *zap.Logger) Destination { switch config.Type { case ServerTypeGmail: return &gmailDestination{ @@ -31,12 +43,39 @@ func NewDestination(config ServerConfig, auth *OAuthServer, log *zap.Logger) Des type gmailDestination struct { c ServerConfig - auth *OAuthServer + auth OAuthServer log *zap.Logger + + ctx context.Context + svc *gmail.Service +} + +func (d *gmailDestination) Connect(ctx context.Context) (DestinationConnection, error) { + tokenQ := <-d.auth.GetTokenForUser(ctx, d.c.Email) + if tokenQ.Error != nil { + return nil, tokenQ.Error + } + + auth := option.WithHTTPClient(d.auth.MakeClient(ctx, tokenQ.Token)) + svc, err := gmail.NewService(ctx, auth, option.WithUserAgent("mailbox-shuffler")) + if err != nil { + return nil, err + } + d2 := *d + d2.ctx = ctx + d2.svc = svc + return &d2, nil } func (d *gmailDestination) AddMessage(msg []byte) error { - return nil + enc := base64.RawURLEncoding.EncodeToString(msg) + call := d.svc.Users.Messages.Insert("me", &gmail.Message{ + LabelIds: []string{"INBOX", "UNREAD"}, + Raw: enc, + }) + result, err := call.Do() + d.log.Info("Result", zap.Any("result", result), zap.Error(err)) + return err } func (d *gmailDestination) Close() error { diff --git a/cmd/mailbox-shuffler/mailbox-shuffler.go b/cmd/mailbox-shuffler/mailbox-shuffler.go index ddaa324..5c8c319 100644 --- a/cmd/mailbox-shuffler/mailbox-shuffler.go +++ b/cmd/mailbox-shuffler/mailbox-shuffler.go @@ -8,7 +8,6 @@ package main import ( "context" - "encoding/base64" "encoding/json" "fmt" "os" @@ -18,7 +17,6 @@ import ( "go.uber.org/zap" "golang.org/x/oauth2/google" "google.golang.org/api/gmail/v1" - "google.golang.org/api/option" ) func main() { @@ -74,23 +72,14 @@ func main() { oauthServer := RunOAuthServer(ctx, config.OAuthServer, oauthConfig, log) - resp := <-oauthServer.GetTokenForUser(ctx, config.Monitor[0].Destination.Email) - if resp.Error != nil { - log.Fatal("Failed to get OAuth token", zap.Error(resp.Error)) + dest := NewDestination(config.Monitor[0].Destination, oauthServer, log) + destConn, err := dest.Connect(ctx) + if err != nil { + log.Fatal("Failed to connect to destination", zap.Error(err)) } - auth := option.WithHTTPClient(oauthConfig.Client(ctx, resp.Token)) - client, err := gmail.NewService(ctx, auth, option.WithUserAgent("mailbox-shuffler")) + err = destConn.AddMessage(rawMsg) if err != nil { - log.Fatal("Failed to create GMail client", zap.Error(err)) + log.Fatal("Failed to insert message", zap.Error(err)) } - - rawEnc := base64.RawURLEncoding.EncodeToString(rawMsg) - - call := client.Users.Messages.Insert("me", &gmail.Message{ - LabelIds: []string{"INBOX", "UNREAD"}, - Raw: rawEnc, - }) - result, err := call.Do() - log.Info("Result", zap.Any("result", result), zap.Error(err)) } diff --git a/cmd/mailbox-shuffler/oauth.go b/cmd/mailbox-shuffler/oauth.go index 14de28a..a9314d6 100644 --- a/cmd/mailbox-shuffler/oauth.go +++ b/cmd/mailbox-shuffler/oauth.go @@ -26,6 +26,7 @@ type GetTokenForUserResult struct { type OAuthServer interface { GetTokenForUser(ctx context.Context, id string) <-chan GetTokenForUserResult + MakeClient(context.Context, *oauth2.Token) *http.Client } type oauthServer struct { @@ -186,3 +187,7 @@ func (s *oauthServer) handleRequest(rw http.ResponseWriter, req *http.Request) { log.Error("Invalid request - missing code", zap.String("id", id)) http.Error(rw, "Invalid Code", http.StatusBadRequest) } + +func (s *oauthServer) MakeClient(ctx context.Context, token *oauth2.Token) *http.Client { + return s.o2c.Client(ctx, token) +} -- 2.43.5