123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- package idavollr
- import (
- "bytes"
- "errors"
- "fmt"
- "io"
- "log"
- "github.com/emersion/go-imap"
- "github.com/emersion/go-imap/client"
- "github.com/emersion/go-message"
- )
- type AbstractImapMessage interface {
- Section() *imap.BodySectionName
- Message() *imap.Message
- MimeType() string
- SetMessageBytes([]byte)
- MessageBytes() []byte
- SetMimeMessage(*message.Entity)
- MimeMessage() *message.Entity
- SetMessageReader(io.Reader)
- MessageReader() io.Reader
- SetMessageBody([]byte)
- SetClient(*client.Client)
- Client() *client.Client
- }
- type ImapMessage struct {
- Sect *imap.BodySectionName
- Msg *imap.Message
- Mimetype string
- cli *client.Client
- msgBytes []byte
- mimeMsg *message.Entity
- bdyRdr io.Reader
- bdy []byte
- }
- func (m ImapMessage) Section() *imap.BodySectionName {
- return m.Sect
- }
- func (m ImapMessage) Message() *imap.Message {
- return m.Msg
- }
- func (m ImapMessage) MimeType() string {
- return m.Mimetype
- }
- func (m *ImapMessage) SetMessageBytes(b []byte) {
- m.msgBytes = b
- }
- func (m ImapMessage) MessageBytes() []byte {
- return m.msgBytes
- }
- func (m *ImapMessage) SetMimeMessage(msg *message.Entity) {
- m.mimeMsg = msg
- }
- func (m ImapMessage) MimeMessage() *message.Entity {
- return m.mimeMsg
- }
- func (m *ImapMessage) SetMessageReader(r io.Reader) {
- m.bdyRdr = r
- }
- func (m ImapMessage) MessageReader() io.Reader {
- return m.bdyRdr
- }
- func (m *ImapMessage) SetMessageBody(b []byte) {
- m.bdy = b
- }
- func (m ImapMessage) MessageBody() []byte {
- return m.bdy
- }
- func (m *ImapMessage) SetClient(c *client.Client) {
- m.cli = c
- }
- func (m ImapMessage) Client() *client.Client {
- return m.cli
- }
- func ReadMessageBody(m AbstractImapMessage) (AbstractImapMessage, error) {
- r := m.Message().GetBody(m.Section())
- if r == nil {
- return m, MalformedMessageError{
- Cause: errors.New("no body in message"),
- MessageID: m.Message().Envelope.MessageId,
- }
- }
- messageBytes, err := io.ReadAll(r)
- m.SetMessageBytes(messageBytes)
- return m, err
- }
- func ParseMimeMessage(m AbstractImapMessage) (AbstractImapMessage, error) {
- r := bytes.NewReader(m.MessageBytes())
- message, err := message.Read(r)
- m.SetMimeMessage(message)
- return m, err
- }
- func getNextPart(message *message.Entity, ID string, mimetype string) (io.Reader, error) {
- if mr := message.MultipartReader(); mr != nil {
- for {
- p, err := mr.NextPart()
- if err == io.EOF {
- break
- } else if err != nil {
- return nil, fmt.Errorf("while reading next part: %w", err)
- }
- return getNextPart(p, ID, mimetype)
- }
- } else {
- t, _, err := message.Header.ContentType()
- if err != nil {
- return nil, fmt.Errorf("while getting content type: %w", err)
- }
- if t == mimetype {
- return message.Body, nil
- }
- }
- return nil, MalformedMessageError{
- Cause: errors.New(mimetype + " not found"),
- MessageID: ID,
- }
- }
- func GetBody(m AbstractImapMessage) (AbstractImapMessage, error) {
- reader, err := getNextPart(m.MimeMessage(), m.Message().Envelope.MessageId, m.MimeType())
- m.SetMessageReader(reader)
- return m, err
- }
- func ReadBody(m AbstractImapMessage) (AbstractImapMessage, error) {
- body, err := io.ReadAll(m.MessageReader())
- m.SetMessageBody(body)
- return m, err
- }
- func RecoverMalformedMessage(m AbstractImapMessage, err error) (AbstractImapMessage, error) {
- var malformedMessageError MalformedMessageError
- if errors.As(err, &malformedMessageError) {
- err = nil
- log.Println(malformedMessageError.Error())
- log.Println(string(m.MessageBytes()))
- }
- return m, err
- }
- func RecoverErroredMessages(m AbstractImapMessage, err error) (AbstractImapMessage, error) {
- log.Printf("message %s errored: %v\n", m.Message().Envelope.MessageId, err)
- return m, nil
- }
|