我正在try 从服务器获取具有以下源代码的所有邮箱(此函数在主模块中调用):

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
}

这会导致以下错误:

死机:运行时错误:内存地址无效或无指针取消引用 [信号SIGSEGV:分段违规代码=0x1地址=0x18 PC=0x5ee505]

Goroutine 1[正在运行]:

我已经try 过imap.FetchEtaine(),它可以工作,但由于某种原因,imap.FetchRFC822不能工作.

我的主要目标是从所有邮箱中导出所有邮箱附件(.gz,.zip,...),这就是为什么我需要整个邮箱,而不仅仅是信封.

推荐答案

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!

Go相关问答推荐

从Kafka到Clickhouse的实时消费数据

为什么工具链指令在这种情况下没有效果?

将类型定义为泛型类型实例化

在Mac中使用uname获取处理器体系 struct 时,在为AMD64构建Go二进制时出现错误结果

GO:如何指定类型约束,使S方法的参数类型与接收方的参数类型相同

如何使用Gio设置标题栏图标

在 Go 中使用 Apache Arrow 按时间间隔对事件进行分区

golang 上基于标头的版本控制

获取 nil 指针类型的 reflect.Value

设置 graphql 的最大文件上传大小(golang)

go version -m 输出中的箭头符号=>是什么意思?

致命错误:找不到由 zergon321/reisen 引起的libavcodec/avcodec.h文件

在 Golang 中,如何将接口作为泛型类型与 nil 进行比较?

在 docker kill --signal=SIGX 上以这种方式关闭容器内运行的 go 应用程序是否安全?

curl:(56)Recv失败:连接由golang中的对等方与docker重置

每 N 秒运行一次函数,上下文超时

如何在golang中使用ozzo验证进行时间最大验证

Go 赋值涉及到自定义类型的指针

如何从应用程序调用谷歌云身份 API

Golang 中的无实体函数