Esempio n. 1
0
func fetch(c *imap.Client, user string, thread Thread) ([]*ParsedMail, error) {
	var set imap.SeqSet
	for _, uid := range thread {
		set.AddNum(uid)
	}
	cmd, err := imap.Wait(c.UIDFetch(&set, "BODY[]", "X-GM-MSGID", "X-GM-THRID"))
	if err != nil {
		return nil, ErrBadConnection
	}
	parsed := make([]*ParsedMail, len(cmd.Data))
	for i, rsp := range cmd.Data {
		p, err := parseMail(imap.AsBytes(rsp.MessageInfo().Attrs["BODY[]"]), user)
		if err != nil {
			return nil, err
		}
		link, err := gmailLink(imap.AsString(rsp.MessageInfo().Attrs["X-GM-MSGID"]))
		if err != nil {
			return nil, err
		}
		p.GmailLink = link
		p.Thrid = imap.AsString(rsp.MessageInfo().Attrs["X-GM-THRID"])
		parsed[i] = p
	}
	return parsed, nil
}
Esempio n. 2
0
func archive(c *imap.Client, thrid string) error {
	cmd, err := imap.Wait(c.UIDSearch("X-GM-THRID", thrid))
	if err != nil {
		log.Println(err)
		return ErrBadConnection
	}
	if len(cmd.Data) == 0 {
		return nil
	}
	var set imap.SeqSet
	set.AddNum(cmd.Data[0].SearchResults()...)
	_, err = imap.Wait(c.UIDStore(&set, "+FLAGS.SILENT", `(\Deleted)`))
	return err
}
Esempio n. 3
0
// getEmails will fetch the full bodies of all emails listed in the given command.
func getEmails(client *imap.Client, cmd *imap.Command) ([]map[string]interface{}, error) {
	var emails []map[string]interface{}
	seq := new(imap.SeqSet)
	for _, rsp := range cmd.Data {
		for _, uid := range rsp.SearchResults() {
			seq.AddNum(uid)
		}
	}
	if seq.Empty() {
		return emails, nil
	}
	fCmd, err := imap.Wait(client.UIDFetch(seq, "INTERNALDATE", "BODY[]", "UID", "RFC822.HEADER"))
	if err != nil {
		return emails, err
	}

	var email map[string]interface{}
	for _, msgData := range fCmd.Data {
		msgFields := msgData.MessageInfo().Attrs
		email, err = newEmailMessage(msgFields)
		if err != nil {
			return emails, err
		}
		emails = append(emails, email)

		// mark message as read
		fSeq := new(imap.SeqSet)
		fSeq.AddNum(imap.AsNumber(msgFields["UID"]))
		_, err = imap.Wait(client.UIDStore(fSeq, "+FLAGS", "\\SEEN"))
		if err != nil {
			return emails, err
		}
	}
	return emails, nil
}
Esempio n. 4
0
// fetchMessage send UID FETCH command to retrieve message body
func fetchMessage(client *imap.Client, messageUID uint32) ([]byte, error) {
	seq := new(imap.SeqSet)

	seq.AddNum(messageUID)
	cmd, err := imap.Wait(client.UIDFetch(seq, "INTERNALDATE", "BODY[]", "UID", "RFC822.HEADER"))

	if err != nil {
		logger.Errorf("Unable to fetch message (%d): %s", messageUID, err.Error())
		return nil, nil
	}

	if len(cmd.Data) == 0 {
		logger.WithField("uid", messageUID).Info("Unable to fetch message from src: NO DATA")
		return nil, errors.New("message not found")
	}

	msgFields := cmd.Data[0].MessageInfo().Attrs
	body := imap.AsBytes(msgFields["BODY[]"])

	cmd.Data = nil

	return body, nil
}
Esempio n. 5
0
// loadMessages will search and fetch message body
func loadMessages(client *imap.Client, config *Config) error {
	cmd, err := imap.Wait(client.UIDSearch("FROM", client.Quote(config.From), "UNSEEN"))
	if err != nil {
		return err
	}

	seq := new(imap.SeqSet)

	if len(cmd.Data) > 0 {
		seq.AddNum(cmd.Data[0].SearchResults()...)
	}

	if seq.Empty() {
		return nil
	}

	logger.Infof("Fetched UIDs %v", seq)

	cmd, err = imap.Wait(client.UIDFetch(seq, "FLAGS", "INTERNALDATE", "RFC822.SIZE", "BODY[]"))
	if err != nil {
		return err
	}

	for _, rsp := range cmd.Data {
		body, err := fetchMessage(client, rsp.MessageInfo().UID)

		if err != nil {
			logger.Fatal(err)
			return err
		}

		err = writeFileFromBody(bytes.NewReader(body), config)

		if err != nil {
			logger.Fatal(err)
			return err
		}
	}

	if !seq.Empty() {
		_, err = imap.Wait(client.UIDStore(seq, "+FLAGS.SILENT", imap.NewFlagSet(`\Seen`)))
	}

	cmd.Data = nil

	return err
}