func (p ParsedMessage) Hash() string {
	hasher := sha256.New()
	m, err := mail.ReadMessage(bytes.NewReader(*p.Bytes))
	if err != nil {
		return ""
	}
	io.Copy(hasher, m.Body)
	return hex.EncodeToString(hasher.Sum(nil))
}
Hash provides an ideally stable handle for a message.
package lib
import (
	"bufio"
	"bytes"
	"crypto/sha256"
	"encoding/hex"
	"errors"
	"io"
	"log"
	"net/mail"
	"os"
	"path"
	"strings"
	"github.com/spf13/viper"
)
func splitAddress(email string) (account, host string) {
	i := strings.LastIndexByte(email, '@')
	account = email[:i]
	host = email[i+1:]
	return
}
func joinAddresses(addresses []*mail.Address) string {
	out := ""
	for _, addr := range addresses {
		if addr != nil {
			if out != "" {
				out = out + ", " + addr.String()
			} else {
				out = addr.String()
			}
		}
	}
	return out
}
func ReadMessage(reader io.Reader) []byte {
	scanner := bufio.NewScanner(reader)
	scanner.Split(bufio.ScanBytes)
	mailMsg := make([]byte, 0)
	for scanner.Scan() {
		mailMsg = append(mailMsg, scanner.Bytes()...)
	}
	if err := scanner.Err(); err != nil && err != io.EOF {
		log.Fatalf("reading message: %v", err)
	}
	return mailMsg
}
type ParsedMessage struct {
	Sender       string
	SourceDomain string
	Rcpt         map[string][]string
	DestDomain   []string
	Bytes        *[]byte
	*mail.Message
}