From 32f20dda222eec551f4967bc1bd16299f408a6c9 Mon Sep 17 00:00:00 2001 From: nasa9084 Date: Tue, 30 Jun 2020 01:23:13 +0900 Subject: [PATCH] add: support apply filter to existing emails --- commands/apply.go | 10 +++++++++- commands/util.go | 1 + gmail/filter.go | 49 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 1 deletion(-) diff --git a/commands/apply.go b/commands/apply.go index fdde775..a1c7457 100644 --- a/commands/apply.go +++ b/commands/apply.go @@ -21,7 +21,8 @@ func init() { } type ApplyCommand struct { - Target string `short:"f" long:"filename" required:"yes"` + Target string `short:"f" long:"filename" required:"yes"` + ApplyToExistingEmails bool `short:"e" long:"apply-to-existing"` } func (cmd *ApplyCommand) Execute([]string) error { @@ -95,6 +96,13 @@ func (cmd *ApplyCommand) applyFilter(data []byte) error { if err := c.CreateFilter(ctx, filter); err != nil { return err } + + if cmd.ApplyToExistingEmails { + log.Printf("Apply filter %s to existing emails", filter.String()) + if err := c.ApplyLabelToExistingEmail(ctx, filter); err != nil { + return err + } + } } return nil diff --git a/commands/util.go b/commands/util.go index d2f3457..5f82212 100644 --- a/commands/util.go +++ b/commands/util.go @@ -20,6 +20,7 @@ import ( var oauthScope = []string{ gmail.GmailLabelsScope, + gmail.GmailModifyScope, gmail.GmailSettingsBasicScope, } diff --git a/gmail/filter.go b/gmail/filter.go index e4f225d..a78f9a1 100644 --- a/gmail/filter.go +++ b/gmail/filter.go @@ -109,6 +109,55 @@ func (c *Client) DeleteFilterByID(ctx context.Context, id string) error { return nil } +func (c *Client) ApplyLabelToExistingEmail(ctx context.Context, filter Filter) error { + if filter.Action.AddLabel == "" { + return nil + } + + gf, err := c.convertFilterToGmail(filter) + if err != nil { + return err + } + + if err := c.svc.Users.Messages.List("me").Q(filter.Criteria.String()).MaxResults(999).Pages( + ctx, + func(msgsResp *gmail.ListMessagesResponse) error { + if len(msgsResp.Messages) == 0 { + return nil + } + + messageIDs := make([]string, 0, len(msgsResp.Messages)) + + for _, msg := range msgsResp.Messages { + messageIDs = append(messageIDs, msg.Id) + } + + var begin int + for begin < len(messageIDs) { + end := begin + 1000 + if len(messageIDs) < end { + end = len(messageIDs) + } + batchModifyMessagesRequest := &gmail.BatchModifyMessagesRequest{ + AddLabelIds: gf.Action.AddLabelIds, + RemoveLabelIds: gf.Action.RemoveLabelIds, + Ids: messageIDs[begin:end], + } + + if err := c.svc.Users.Messages.BatchModify("me", batchModifyMessagesRequest).Context(ctx).Do(); err != nil { + return err + } + begin = end + } + return nil + }, + ); err != nil { + return err + } + + return nil +} + func (c *Client) convertFilterFromGmail(gf *gmail.Filter) Filter { var f Filter f.id = gf.Id