I am trying to fetch all E-Mails from the Server with the following source Code (this function is called in the main module):
package internal
import (
"fmt"
"io"
"io/ioutil"
"log"
"github.com/emersion/go-imap"
"github.com/emersion/go-imap/client"
"github.com/emersion/go-message"
)
func FetchEMail(server string, username string, password string) error {
//Connect to Server
log.Println("Connecting to server...")
c, err := client.DialTLS(server, nil)
log.Println("Connected to " server)
defer c.Logout()
//check if connection successful
if err != nil {
log.Println("In connection Error")
return err
}
//err = nil
//Login
log.Println("Logging in...")
err = c.Login(username, password)
log.Println("Logged in as " username)
//check if login successful
if err != nil {
log.Println("In login Error")
return err
}
//Select INBOX
log.Println("Selecting INBOX...")
mbox, err := c.Select("INBOX", false)
log.Println("Selected INBOX")
//check if select successful
if err != nil {
return err
}
//Fetch all messages
log.Println("Fetching all messages...")
seqset := new(imap.SeqSet)
seqset.AddRange(1, mbox.Messages)
items := []imap.FetchItem{imap.FetchRFC822}
messages := make(chan *imap.Message, 10)
done := make(chan error, 1)
go func() {
done <- c.Fetch(seqset, items, messages)
}()
//check if fetch successful
if err := <-done; err != nil {
log.Println("In fetch Error")
return err
}
log.Println("Run Successful - Terminating...")
return nil
}
This results into the following error:
panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x5ee505]
goroutine 1 [running]:
I already have tried imap.FetchEvelope() which works, but for some reason imap.FetchRFC822 does not work.
My main goal is to export all E-Mail attachments (.gz, .zip, ...) from all E-Mails, that is why I need the whole E-Mail, not only the Envelope.
CodePudding user response:
I think the issue was in this line items := []imap.FetchItem{imap.FetchRFC822}
.
First, let's clarify what the FetchItem
type is. This represents the different parts of an email that can be fetched (envelope, body, UID, flags, and so on).
Then, let's talk about the Fetch
method. It expects a slice of imap.FetchItem
passed in. It retrieves from the emails all of the parts specified by the slice.
So what fixes your issue is replacing this line with items := []imap.FetchItem{imap.FetchRFC822, imap.FetchEnvelope}
.
I fixed and tested your program as you can see from the code snippet below:
package main
import (
"fmt"
"log"
"github.com/emersion/go-imap"
"github.com/emersion/go-imap/client"
)
func FetchEMail(server string, username string, password string) error {
// Connect to Server
log.Println("Connecting to server...")
c, err := client.Dial(server)
log.Println("Connected to " server)
defer c.Logout()
// check if connection successful
if err != nil {
log.Println("In connection Error")
return err
}
// Login
log.Println("Logging in...")
err = c.Login(username, password)
log.Println("Logged in as " username)
// check if login successful
if err != nil {
log.Println("In login Error")
return err
}
// Select INBOX
log.Println("Selecting INBOX...")
mbox, err := c.Select("INBOX", false)
log.Println("Selected INBOX")
// check if select successful
if err != nil {
return err
}
// Fetch all messages
log.Println("Fetching all messages...")
seqset := new(imap.SeqSet)
seqset.AddRange(1, mbox.Messages)
items := []imap.FetchItem{imap.FetchRFC822, imap.FetchEnvelope}
messages := make(chan *imap.Message, 10)
done := make(chan error, 1)
go func() {
done <- c.Fetch(seqset, items, messages)
}()
for msg := range messages {
fmt.Printf("suject: %v\n", msg.Envelope.Subject)
}
// check if fetch successful
if err := <-done; err != nil {
log.Println("In fetch Error")
return err
}
log.Println("Run Successful - Terminating...")
return nil
}
func main() {
err := FetchEMail("xxxxxxx", "xxxxx", "xxxxx")
if err != nil {
panic(err)
}
}
Near the end, I added a for
to print the subject of the retrieved emails. Here, you can replace the code with your own logic. The nil pointer dereference
error disappears.
Let me know if this solves your issue!