From bbf122597cd7e920f5744265a56fd78c0463811a Mon Sep 17 00:00:00 2001 From: Aaron Bieber Date: Fri, 21 Jun 2024 14:16:55 -0600 Subject: [PATCH] add the ability to send / receive responses over mail --- chats/mail.go | 286 ++++++++++++++++++++++++++++++++++++++++++++++++++ chats/sms.go | 68 +----------- go.mod | 16 +-- go.sum | 36 ++++--- main.go | 20 +++- 5 files changed, 342 insertions(+), 84 deletions(-) create mode 100644 chats/mail.go diff --git a/chats/mail.go b/chats/mail.go new file mode 100644 index 0000000..ac8ea1f --- /dev/null +++ b/chats/mail.go @@ -0,0 +1,286 @@ +package chats + +import ( + "bytes" + "crypto/tls" + "fmt" + "io" + "log" + "net/smtp" + "strings" + "time" + + "github.com/emersion/go-imap" + "github.com/emersion/go-imap/client" + "github.com/emersion/go-message/mail" + "suah.dev/mcchunkie/plugins" +) + +type mmail struct { + smtpUser string + smtpServer string + password string + + imapClient *client.Client + updateChan chan client.Update +} + +func (m *mmail) buildFancyReply(msgID, to, from, originalSubject, resp string) error { + buf := new(bytes.Buffer) + w, err := mail.CreateWriter(buf, mail.HeaderFromMap(map[string][]string{ + "From": {to}, + "To": {from}, + "Subject": {"Re: " + originalSubject}, + "References": {msgID}, + "In-Reply-To": {msgID}, + })) + if err != nil { + return err + } + + textHeader := mail.InlineHeader{} + + textPart, err := w.CreateSingleInline(textHeader) + if err != nil { + return err + } + + _, err = textPart.Write([]byte(resp + "\r\n")) + if err != nil { + return err + } + + if err := textPart.Close(); err != nil { + return err + } + + if err := w.Close(); err != nil { + return err + } + + return m.send(to, from, buf.Bytes()) +} + +func (m *mmail) send(to, from string, data []byte) error { + conn, err := tls.Dial("tcp", m.smtpServer, &tls.Config{}) + if err != nil { + log.Println(err) + return err + } + defer conn.Close() + + host := strings.TrimRight(m.smtpServer, ":") + + sc, err := smtp.NewClient(conn, host) + if err != nil { + log.Println(err) + return err + } + defer sc.Close() + + sc.Auth(smtp.PlainAuth("", m.smtpUser, m.password, host)) + + if err := sc.Mail(to); err != nil { + log.Println(err) + return err + + } + + if err := sc.Rcpt(from); err != nil { + log.Println(err) + return err + } + + wc, err := sc.Data() + if err != nil { + log.Println(err) + return err + } + + fmt.Fprint(wc, string(data)) + + err = wc.Close() + if err != nil { + log.Println(err) + return err + } + + return sc.Quit() +} + +func (m *mmail) buildReply(msgID, subj, to, from, resp string) error { + + log.Printf("Mail: smtp sending mail to: %q, from: %q", from, to) + + reSubj := fmt.Sprintf("Re: %s", subj) + + wc := new(bytes.Buffer) + fmt.Fprintf(wc, fmt.Sprintf("To: %s\r\n", from)) + fmt.Fprintf(wc, fmt.Sprintf("From: %s\r\n", to)) + fmt.Fprintf(wc, fmt.Sprintf("Subject: %s\r\n", reSubj)) + fmt.Fprintf(wc, fmt.Sprintf("References: %s\r\n", msgID)) + fmt.Fprintf(wc, fmt.Sprintf("In-Reply-To: %s\r\n", msgID)) + fmt.Fprintf(wc, "\r\n"+resp+"\r\n") + + return m.send(to, from, wc.Bytes()) +} + +func MailListen(store ChatStore, plugins *plugins.Plugins) error { + var ( + smtpUser, _ = store.Get("smtp_user") + smtpServer, _ = store.Get("smtp_server") + imapServer, _ = store.Get("imap_server") + imapUser, _ = store.Get("imap_user") + mailPass, _ = store.Get("mail_password") + ) + + m := mmail{ + smtpUser: smtpUser, + smtpServer: smtpServer, + password: mailPass, + updateChan: make(chan client.Update), + } + + c, err := client.DialTLS(imapServer, nil) + if err != nil { + return err + } + log.Printf("Mail: connected to %q", imapServer) + + m.imapClient = c + + defer m.imapClient.Logout() + + if err = m.imapClient.Login(imapUser, mailPass); err != nil { + return err + } + log.Printf("Mail: logged in as %q", imapUser) + + _, err = m.imapClient.Select("INBOX", false) + if err != nil { + return err + } + + m.imapClient.Updates = m.updateChan + + go func() { + for update := range m.updateChan { + switch update.(type) { + case *client.MessageUpdate: + log.Println("Mail: received new message") + + crit := imap.NewSearchCriteria() + crit.WithoutFlags = []string{imap.SeenFlag} + + ids, err := m.imapClient.Search(crit) + if err != nil { + log.Println(err) + continue + } + + if len(ids) == 0 { + log.Println(len(ids)) + continue + } + + seq := &imap.SeqSet{} + seq.AddNum(ids...) + + messages := make(chan *imap.Message, 10) + done := make(chan error, 1) + + // Mark the messages as read + bodySeq := &imap.BodySectionName{ + Peek: false, + } + + go func() { + done <- c.Fetch(seq, []imap.FetchItem{bodySeq.FetchItem()}, messages) + }() + + for msg := range messages { + fullMsg := msg.GetBody(bodySeq) + to, from, subj, msg, msgID := "", "", "", "", "" + + mr, err := mail.CreateReader(fullMsg) + if err != nil { + log.Println(err) + continue + } + + for { + part, err := mr.NextPart() + if err == io.EOF { + break + } else if err != nil { + log.Println(err) + continue + } + maybeSubj := part.Header.Get("Subject") + if maybeSubj != "" { + subj = maybeSubj + } + maybeTo := part.Header.Get("To") + if maybeTo != "" { + to = maybeTo + } + maybeFrom := part.Header.Get("From") + if maybeFrom != "" { + from = maybeFrom + } + maybeID := part.Header.Get("Message-ID") + if maybeID != "" { + msgID = maybeID + } + + switch part.Header.(type) { + case *mail.InlineHeader: + b, _ := io.ReadAll(part.Body) + msg = strings.TrimSpace(string(b)) + } + log.Printf("to: %q, from: %q, subj: %q, msg: %q", to, from, subj, msg) + } + + if to != "" && from != "" && msg != "" && subj != "" { + for _, p := range *plugins { + if p.Match(from, msg) { + log.Printf("%s: responding to '%s'", p.Name(), from) + p.SetStore(store) + + resp := p.Process(from, msg) + log.Println(resp) + + /* + err := m.buildReply(msgID, subj, to, from, resp) + if err != nil { + log.Println(err) + continue + } + */ + + err := m.buildFancyReply(msgID, to, from, subj, resp) + if err != nil { + log.Println(err) + continue + } + + } + } + } + } + + if err := <-done; err != nil { + log.Fatal(err) + } + + } + } + }() + + for { + if err := m.imapClient.Noop(); err != nil { + return err + } + time.Sleep(1 * time.Second) + } +} diff --git a/chats/sms.go b/chats/sms.go index be692ba..5a1910d 100644 --- a/chats/sms.go +++ b/chats/sms.go @@ -4,7 +4,6 @@ import ( "fmt" "log" "net/http" - "net/smtp" "strings" "golang.org/x/crypto/bcrypt" @@ -23,11 +22,9 @@ func smsCanSend(number string, numbers []string) bool { // SMSListen listens for our incoming sms func SMSListen(store ChatStore, plugins *plugins.Plugins) { var ( - smsPort, _ = store.Get("sms_listen") - smsAllowed, _ = store.Get("sms_users") - smtpUser, _ = store.Get("smtp_user") - smtpReceiver, _ = store.Get("smtp_receiver") - smsUsers = strings.Split(smsAllowed, ",") + smsPort, _ = store.Get("sms_listen") + smsAllowed, _ = store.Get("sms_users") + smsUsers = strings.Split(smsAllowed, ",") ) if smsPort != "" { @@ -36,8 +33,7 @@ func SMSListen(store ChatStore, plugins *plugins.Plugins) { log.Printf("SMS: listening on %q\n", smsPort) http.HandleFunc("/_sms", func(w http.ResponseWriter, r *http.Request) { - var msg, from, id string - emailSend := false + var msg, from string user, pass, ok := r.BasicAuth() if !ok { log.Println("SMS: basic auth no ok") @@ -72,11 +68,8 @@ func SMSListen(store ChatStore, plugins *plugins.Plugins) { from = r.Form.Get("From") case http.MethodGet: // to={TO}&from={FROM}&message={MESSAGE}&id={ID}&date={TIMESTAMP} - id = r.URL.Query().Get("id") msg = r.URL.Query().Get("message") from = r.URL.Query().Get("from") - - emailSend = true default: http.Error( w, @@ -100,58 +93,7 @@ func SMSListen(store ChatStore, plugins *plugins.Plugins) { p.SetStore(store) resp := p.Process(from, msg) - - if emailSend { - sc, err := smtp.Dial("localhost:25") - if err != nil { - log.Printf("SMS: smtp dial failed: %q\n", err) - http.Error(w, "internal server error", http.StatusInternalServerError) - return - } - - if err := sc.Mail(smtpUser); err != nil { - log.Printf("SMS: smtp Mail failed: %q\n", err) - http.Error(w, "internal server error", http.StatusInternalServerError) - return - - } - if err := sc.Rcpt(smtpReceiver); err != nil { - log.Printf("SMS: smtp Rcpt failed: %q\n", err) - http.Error(w, "internal server error", http.StatusInternalServerError) - return - - } - - wc, err := sc.Data() - if err != nil { - log.Printf("SMS: smtp Data failed: %q\n", err) - http.Error(w, "internal server error", http.StatusInternalServerError) - return - - } - - log.Printf("SMS: smtp sending id: %q to: %q, from: %q", id, smtpReceiver, smtpUser) - fmt.Fprintf(wc, fmt.Sprintf("To: %s\r\n", smtpReceiver)) - fmt.Fprintf(wc, fmt.Sprintf("From: %s\r\n", smtpUser)) - fmt.Fprintf(wc, fmt.Sprintf("Subject: Message received from number %s to number %s [%s]\r\n", from, from, id)) - fmt.Fprintf(wc, resp) - - err = wc.Close() - if err != nil { - log.Printf("SMS: smtp Close failed: %q\n", err) - http.Error(w, "internal server error", http.StatusInternalServerError) - return - } - - err = sc.Quit() - if err != nil { - log.Printf("SMS: smtp Quit failed: %q\n", err) - http.Error(w, "internal server error", http.StatusInternalServerError) - return - } - } else { - fmt.Fprint(w, resp) - } + fmt.Fprint(w, resp) } } } else { diff --git a/go.mod b/go.mod index 58d3a09..12fb4ff 100644 --- a/go.mod +++ b/go.mod @@ -7,17 +7,21 @@ toolchain go1.22.3 require ( github.com/ProtonMail/go-crypto v1.0.0 github.com/caneroj1/stemmer v0.0.0-20170128035808-c9f2ce1504d5 + github.com/emersion/go-imap v1.2.1 + github.com/emersion/go-message v0.18.1 github.com/gomarkdown/markdown v0.0.0-20240419095408-642f0ee99ae2 github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530 - github.com/ollama/ollama v0.1.39 - golang.org/x/crypto v0.23.0 - golang.org/x/net v0.25.0 - golang.org/x/term v0.20.0 + github.com/ollama/ollama v0.1.44 + golang.org/x/crypto v0.24.0 + golang.org/x/net v0.26.0 + golang.org/x/term v0.21.0 gopkg.in/irc.v3 v3.1.4 - suah.dev/protect v1.2.3 + suah.dev/protect v1.2.4 ) require ( github.com/cloudflare/circl v1.3.3 // indirect - golang.org/x/sys v0.20.0 // indirect + github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21 // indirect + golang.org/x/sys v0.21.0 // indirect + golang.org/x/text v0.16.0 // indirect ) diff --git a/go.sum b/go.sum index 06aabce..baeb569 100644 --- a/go.sum +++ b/go.sum @@ -8,12 +8,20 @@ github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUK github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/emersion/go-imap v1.2.1 h1:+s9ZjMEjOB8NzZMVTM3cCenz2JrQIGGo5j1df19WjTA= +github.com/emersion/go-imap v1.2.1/go.mod h1:Qlx1FSx2FTxjnjWpIlVNEuX+ylerZQNFE5NsmKFSejY= +github.com/emersion/go-message v0.15.0/go.mod h1:wQUEfE+38+7EW8p8aZ96ptg6bAb1iwdgej19uXASlE4= +github.com/emersion/go-message v0.18.1 h1:tfTxIoXFSFRwWaZsgnqS1DSZuGpYGzSmCZD8SK3QA2E= +github.com/emersion/go-message v0.18.1/go.mod h1:XpJyL70LwRvq2a8rVbHXikPgKj8+aI0kGdHlg16ibYA= +github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21 h1:OJyUGMJTzHTd1XQp98QTaHernxMYzRaOasRir9hUlFQ= +github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ= +github.com/emersion/go-textwrapper v0.0.0-20200911093747-65d896831594/go.mod h1:aqO8z8wPrjkscevZJFVE1wXJrLpC5LtJG7fqLOsPb2U= github.com/gomarkdown/markdown v0.0.0-20240419095408-642f0ee99ae2 h1:yEt5djSYb4iNtmV9iJGVday+i4e9u6Mrn5iP64HH5QM= github.com/gomarkdown/markdown v0.0.0-20240419095408-642f0ee99ae2/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530 h1:kHKxCOLcHH8r4Fzarl4+Y3K5hjothkVW5z7T1dUM11U= github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530/go.mod h1:/gBX06Kw0exX1HrwmoBibFA98yBk/jxKpGVeyQbff+s= -github.com/ollama/ollama v0.1.39 h1:EYMew3AxWGXSrBycyjHhMEqau0dljg3s334Yfpx9ir8= -github.com/ollama/ollama v0.1.39/go.mod h1:dOOmmCPUbZJGdHLPbhghW7HCa8CUA8SP6edbRLqxNBs= +github.com/ollama/ollama v0.1.44 h1:3Htzf/mn0nNn1oBOm3rdnbSfX6dOTpOW0YRnxYTsqbo= +github.com/ollama/ollama v0.1.44/go.mod h1:TvVa25PEZI6M0bosiW1sa2XJGq3Xw/OPlpUAkMEntTU= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -25,8 +33,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= -golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -35,8 +43,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -47,24 +55,28 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= -golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= +golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= +golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= @@ -78,5 +90,5 @@ gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -suah.dev/protect v1.2.3 h1:aHeoNwZ9YPp64hrYaN0g0djNE1eRujgH63CrfRrUKdc= -suah.dev/protect v1.2.3/go.mod h1:n1R3XIbsnryKX7C1PO88i5Wgo0v8OTXm9K9FIKt4rfs= +suah.dev/protect v1.2.4 h1:iVZG/zQB63FKNpITDYM/cXoAeCTIjCiXHuFVByJFDzg= +suah.dev/protect v1.2.4/go.mod h1:vVrquYO3u1Ep9Ez2z8x+6N6/czm+TBmWKZfiXU2tb54= diff --git a/main.go b/main.go index 2c2b3d4..8dfdb20 100644 --- a/main.go +++ b/main.go @@ -31,11 +31,12 @@ A [Matrix](https://matrix.org) chat bot.` func main() { var username, shortName, password, userID, accessToken, server, db, avatar, botOwner, prof string var key, value, get string - var setup, doc, verbose bool + var setup, doc, verbose, irc bool flag.BoolVar(&doc, "doc", false, "print plugin information and exit") flag.BoolVar(&setup, "s", false, "setup account") flag.BoolVar(&verbose, "v", false, "print verbose messages") + flag.BoolVar(&irc, "irc", true, "enable irc") flag.StringVar(&avatar, "avatar", "", "set the avatar of the bot to specified url") flag.StringVar(&db, "db", "db", "full path to database directory") @@ -216,15 +217,28 @@ func main() { go func() { for { - err := chats.IRCConnect(store, &plugins.Plugs) + err := chats.MailListen(store, &plugins.Plugs) if err != nil { log.Println(err) } - log.Println("IRC: reconnecting in 60 seconds") + log.Println("Mail: reconnecting in 60 seconds") time.Sleep(time.Second * 60) } }() + if irc { + go func() { + for { + err := chats.IRCConnect(store, &plugins.Plugs) + if err != nil { + log.Println(err) + } + log.Println("IRC: reconnecting in 60 seconds") + time.Sleep(time.Second * 60) + } + }() + } + go func() { for { errataCount := 0