Search code examples
gogmailimap

How to fetch all conversations in one subject gmail


I using emersion/go-imap to get data in gmail have one problem. I can't take all message (reply in subject) like this

enter image description here

I can get only last message of sender message. Have any solution to get all reply message?

My code pattern have round to feed mail data about 5 min/round and this problem if sender send reply in one subject more that 1 reply. I can't get first message. I can get only last message of sender

that some code:

// List mailboxes ลิสต์ mailbox ของแต่ละ channel
mailboxes := make(chan *imap.MailboxInfo, 10)
done := make(chan error, 1)
go func() {
    done <- c.List("", "*", mailboxes)
}()

log.Println("Mailboxes:")
for m := range mailboxes {
    log.Println("* " + m.Name)
}

if err := <-done; err != nil {
    log.Fatal(err)
}

listBox := "INBOX"

// Select INBOX
mbox, err := c.Select(listBox, false)
if err != nil {
    log.Fatal(err)
}

// set range for feed
seqSet := new(imap.SeqSet)
// is for testing get lastone only
seqSet.AddRange(mbox.Messages, mbox.Messages)

log.Println("message lens : ", (mbox.Messages))

// Get the whole message body
var section imap.BodySectionName

items := []imap.FetchItem{section.FetchItem(), imap.FetchEnvelope}

// criteria := imap.NewSearchCriteria()

messages := make(chan *imap.Message, 10)
go func() {
    if err := c.Fetch(seqSet, items, messages); err != nil {
        log.Fatal(err)
    }
}()

msg := <-messages
if msg == nil {
    log.Fatal("Server didn't returned message")
}

// Create a new mail reader
mailReader, err := mail.CreateReader(msg.GetBody(&section))
if err != nil {
    log.Fatal(err)
}
// Print some info about the message
header := mailReader.Header
if ID, err := header.MessageID(); err == nil {
    log.Println("ID:", ID)
}

if date, err := header.Date(); err == nil {
    log.Println("Date:", date)
}
if from, err := header.AddressList("From"); err == nil {
    log.Println("From:", from)
}
if to, err := header.AddressList("To"); err == nil {
    log.Println("To:", to)
}
if subject, err := header.Subject(); err == nil {
    log.Println("Subject:", subject)
}

// Process each message's part
count := 0
for {
    p, err := mailReader.NextPart()
    if err == io.EOF {
        break
    } else if err != nil {
        panic(err)
    }

    switch h := p.Header.(type) {
    case *mail.InlineHeader:
        // This is the message's text (can be plain-text or HTML)
        b, _ := ioutil.ReadAll(p.Body)
        fmt.Printf("Got text: %v\n", string(b))
    case *mail.AttachmentHeader:
        // This is an attachment
        filename, _ := h.Filename()
        fmt.Printf("Got attachment: %v\n", filename)
        // set filename
        file, err := os.Create(filename)
        if err != nil {
            panic(err)
        }
        defer file.Close()
        // create file
        // using io.Copy instead of io.ReadAll to avoid insufficient memory issues
        size, err := io.Copy(file, p.Body)
        if err != nil {
            panic(err)
        }
        fmt.Printf("Saved %v bytes into %v\n", size, filename)

    }
    count++
}
fmt.Printf("\n\nRound of mail : %v", count)

Solution

  • I find a way to feed all of conversations in gmail. Gmail is have setting about grouping mail. I turn off this setting mail of reply will show one by one mail and can get data what I want.

    going to settings --> turn of conversation view.

    setting picture