From 39ecedd1b2f712a6f13c8070cde6ad5447726b33 Mon Sep 17 00:00:00 2001 From: Steven Maude Date: Sun, 25 Mar 2018 15:30:21 +0100 Subject: [PATCH 1/6] Get message IDs from getnada.com Start replacing Mailinator with the nada service. Mailinator started using some fancy WebSockets application making it much more complicated to collect data. Also nada is less well-known than Mailinator, meaning it's less likely to be blocked by services. --- main.go | 61 +++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 17 deletions(-) diff --git a/main.go b/main.go index eb25b6b..213a2f6 100644 --- a/main.go +++ b/main.go @@ -28,6 +28,14 @@ type mailboxDetails struct { PublicMsgs []publicMsg `json:"messages"` } +type msg struct { + UID string `json:"uid"` +} + +type inbox struct { + Msgs []msg `json:"msgs"` +} + func getMailboxDetails(localPart string) (mailboxDetails, error) { webInboxURL := "https://www.mailinator.com/fetch_inbox?zone=public&to=" + localPart fmt.Println("Retrieving URL:", webInboxURL) @@ -100,6 +108,23 @@ func getMail(latestMsg publicMsg, cookies []*http.Cookie) error { return nil } +func getInbox(address string) (inbox, error) { + webInboxURL := "https://getnada.com/api/v1/inboxes/" + address + fmt.Println("Retrieving URL:", webInboxURL) + + addressInbox := inbox{} + resp, err := http.Get(webInboxURL) + if err != nil { + return addressInbox, err + } + + defer resp.Body.Close() + err = json.NewDecoder(resp.Body).Decode(&addressInbox) + // No need for error check here as we return mbxDetails and err whether + // we have an error or not. + return addressInbox, err +} + func main() { // TODO: consider allow to retrieve more than one message. if len(os.Args) != 2 { @@ -107,30 +132,32 @@ func main() { os.Exit(1) } - localPart := os.Args[1] - mbxDetails, err := getMailboxDetails(localPart) + address := os.Args[1] + addressInbox, err := getInbox(address) if err != nil { fmt.Println("failed to get message ID:", err) os.Exit(1) } - numberMsgs := len(mbxDetails.PublicMsgs) + fmt.Println(addressInbox) + numberMsgs := len(addressInbox.Msgs) if numberMsgs == 0 { fmt.Println("no messages in inbox") os.Exit(0) } - - latestMsg := mbxDetails.PublicMsgs[numberMsgs-1] - - cookies, err := getCookies(latestMsg) - if err != nil { - fmt.Println("failed to get cookies:", err) - os.Exit(1) - } - - err = getMail(latestMsg, cookies) - if err != nil { - fmt.Println("failed to get mail:", err) - os.Exit(1) - } + fmt.Println(numberMsgs) + + // latestMsg := mbxDetails.PublicMsgs[numberMsgs-1] + + //cookies, err := getCookies(latestMsg) + //if err != nil { + // fmt.Println("failed to get cookies:", err) + // os.Exit(1) + //} + // + // err = getMail(latestMsg, cookies) + // if err != nil { + // fmt.Println("failed to get mail:", err) + // os.Exit(1) + // } } From 2980803d3cea5c0c11bd825c483e1a7a502745e9 Mon Sep 17 00:00:00 2001 From: Steven Maude Date: Sun, 25 Mar 2018 15:38:00 +0100 Subject: [PATCH 2/6] Remove getCookies functionality Not needed for nada. --- main.go | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/main.go b/main.go index 213a2f6..97bf738 100644 --- a/main.go +++ b/main.go @@ -53,22 +53,6 @@ func getMailboxDetails(localPart string) (mailboxDetails, error) { return mbxDetails, err } -func getCookies(latestMsg publicMsg) ([]*http.Cookie, error) { - // This request is for nothing but getting required cookies. - // Otherwise, the subsequent request fails. - inboxURL := "https://www.mailinator.com/inbox2.jsp?to=" + latestMsg.To - fmt.Println("Retrieving URL:", inboxURL) - - inboxResp, err := http.Get(inboxURL) - defer inboxResp.Body.Close() - if err != nil { - return nil, err - } - - cookies := inboxResp.Cookies() - return cookies, err -} - func getMail(latestMsg publicMsg, cookies []*http.Cookie) error { msgURL := "https://www.mailinator.com/fetch_email?zone=public&msgid=" + latestMsg.ID fmt.Println("Retrieving URL:", msgURL) @@ -149,12 +133,6 @@ func main() { // latestMsg := mbxDetails.PublicMsgs[numberMsgs-1] - //cookies, err := getCookies(latestMsg) - //if err != nil { - // fmt.Println("failed to get cookies:", err) - // os.Exit(1) - //} - // // err = getMail(latestMsg, cookies) // if err != nil { // fmt.Println("failed to get mail:", err) From 408f8ec4619cf0a473df19a3a9065c6f938ae225 Mon Sep 17 00:00:00 2001 From: Steven Maude Date: Sun, 25 Mar 2018 15:51:35 +0100 Subject: [PATCH 3/6] Retrieve mail with given ID from nada Implement end-to-end working functionality. --- main.go | 63 +++++++++++++++++++++------------------------------------ 1 file changed, 23 insertions(+), 40 deletions(-) diff --git a/main.go b/main.go index 97bf738..ded1825 100644 --- a/main.go +++ b/main.go @@ -8,15 +8,10 @@ import ( ) type mail struct { - Data struct { - Subject string `json:"subject"` - Parts []struct { - Body string `json:"body"` - } `json:"parts"` - Headers struct { - From string `json:"from"` - } `json:"headers"` - } `json:"data"` + From string `json:"f"` + Subject string `json:"s"` + HTML string `json:"html"` + Text string `json:"text"` } type publicMsg struct { @@ -53,41 +48,31 @@ func getMailboxDetails(localPart string) (mailboxDetails, error) { return mbxDetails, err } -func getMail(latestMsg publicMsg, cookies []*http.Cookie) error { - msgURL := "https://www.mailinator.com/fetch_email?zone=public&msgid=" + latestMsg.ID +func getMail(latestMsg msg) error { + msgURL := "https://getnada.com/api/v1/messages/" + latestMsg.UID fmt.Println("Retrieving URL:", msgURL) - req, err := http.NewRequest("GET", msgURL, nil) - if err != nil { - return err - } - for _, c := range cookies { - req.AddCookie(c) - } - - client := &http.Client{} - - mailResp, err := client.Do(req) - defer mailResp.Body.Close() + resp, err := http.Get(msgURL) if err != nil { return err } + // TODO: move out display of mail from getting mail. + defer resp.Body.Close() + mailMessage := mail{} - err = json.NewDecoder(mailResp.Body).Decode(&mailMessage) + err = json.NewDecoder(resp.Body).Decode(&mailMessage) if err != nil { return err } - fmt.Println("\nFrom :", mailMessage.Data.Headers.From) - fmt.Println("Subject:", mailMessage.Data.Subject) + fmt.Println("\nFrom :", mailMessage.From) + fmt.Println("Subject:", mailMessage.Subject) fmt.Println("Plain text:") - fmt.Println(mailMessage.Data.Parts[0].Body) + fmt.Println(mailMessage.Text) - if len(mailMessage.Data.Parts) == 2 { - fmt.Println("HTML:") - fmt.Println(mailMessage.Data.Parts[1].Body) - } + fmt.Println("HTML:") + fmt.Println(mailMessage.HTML) return nil } @@ -123,19 +108,17 @@ func main() { os.Exit(1) } - fmt.Println(addressInbox) numberMsgs := len(addressInbox.Msgs) if numberMsgs == 0 { fmt.Println("no messages in inbox") os.Exit(0) } - fmt.Println(numberMsgs) - - // latestMsg := mbxDetails.PublicMsgs[numberMsgs-1] + fmt.Println("Found", numberMsgs, "messages") - // err = getMail(latestMsg, cookies) - // if err != nil { - // fmt.Println("failed to get mail:", err) - // os.Exit(1) - // } + latestMsg := addressInbox.Msgs[0] + err = getMail(latestMsg) + if err != nil { + fmt.Println("failed to get mail:", err) + os.Exit(1) + } } From aa0dd76d1c7dd83cb1e3068e10630f0f9cdfef2e Mon Sep 17 00:00:00 2001 From: Steven Maude Date: Sun, 25 Mar 2018 15:52:40 +0100 Subject: [PATCH 4/6] Update usage string We need the full address, because nada requires the domain to be specified, whereas Mailinator didn't, even if other non-mailinator.com domains were being used in the email address. --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index ded1825..dbc1058 100644 --- a/main.go +++ b/main.go @@ -97,7 +97,7 @@ func getInbox(address string) (inbox, error) { func main() { // TODO: consider allow to retrieve more than one message. if len(os.Args) != 2 { - fmt.Println("Usage: mailin8 ") + fmt.Println("Usage: mailin8
") os.Exit(1) } From 9441c3335e7449c27fe449fa4b7ff940e29881c3 Mon Sep 17 00:00:00 2001 From: Steven Maude Date: Sun, 25 Mar 2018 15:58:31 +0100 Subject: [PATCH 5/6] Remove unused Mailinator code --- main.go | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/main.go b/main.go index dbc1058..e7c9d05 100644 --- a/main.go +++ b/main.go @@ -14,15 +14,6 @@ type mail struct { Text string `json:"text"` } -type publicMsg struct { - ID string `json:"id"` - To string `json:"to"` -} - -type mailboxDetails struct { - PublicMsgs []publicMsg `json:"messages"` -} - type msg struct { UID string `json:"uid"` } @@ -31,23 +22,6 @@ type inbox struct { Msgs []msg `json:"msgs"` } -func getMailboxDetails(localPart string) (mailboxDetails, error) { - webInboxURL := "https://www.mailinator.com/fetch_inbox?zone=public&to=" + localPart - fmt.Println("Retrieving URL:", webInboxURL) - - mbxDetails := mailboxDetails{} - resp, err := http.Get(webInboxURL) - if err != nil { - return mbxDetails, err - } - - defer resp.Body.Close() - err = json.NewDecoder(resp.Body).Decode(&mbxDetails) - // No need for error check here as we return mbxDetails and err whether - // we have an error or not. - return mbxDetails, err -} - func getMail(latestMsg msg) error { msgURL := "https://getnada.com/api/v1/messages/" + latestMsg.UID fmt.Println("Retrieving URL:", msgURL) From 17437bd32557b317ae3fbc7252833cfaf9265d0a Mon Sep 17 00:00:00 2001 From: Steven Maude Date: Sun, 25 Mar 2018 15:58:52 +0100 Subject: [PATCH 6/6] Update the README to reflect change of service From Mailinator to nada. --- README.md | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index f170ad5..24bfe5c 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,22 @@ # go-mailin8 -Display the latest mail from a temporary Mailinator email address, at -the command line. +Display the latest mail from a temporary [nada](https://getnada.com) +email address, at the command line. Useful for getting confirmation emails for throwaway purposes, or for testing. -This is a version of a [bash script I +## History (or "why is this called go-mailin8?") + +Originally, this used Mailinator's service to retrieve email; however, +they rebuilt their site and this became a WebSocket powered application, +making it more difficult to work with. + +This was a version of a [bash script I made](https://gist.github.com/StevenMaude/914e9187c09027866fe88958798acb7e) that uses [jq](https://stedolan.github.io/jq/). However, this Go version -requires no other dependencies. +requires no other dependencies, and now uses a different disposable +email service. ## Build @@ -17,20 +24,11 @@ requires no other dependencies. ## Usage -1. Send, or get an email sent to a Mailinator email address of your - choosing. -2. Note the local-part (the part before @, e.g. - `somefakeemail1234@mailinator.com`). -3. Run `go-mailin8 ` - -## Notes - -NB: you may get unpredictable results from the server if you run this -too often in a short time. See TODO. +1. Send, or get an email sent to a [nada](https://getnada.com) email + address of your choosing. +2. Run `go-mailin8 ` ## TODO: -* Consider introducing slight pauses between requests to try and - improve reliability. * Possibly consider selecting other than latest message (though outside of my original use case).