Skip to content

Commit

Permalink
Small rework
Browse files Browse the repository at this point in the history
  • Loading branch information
felixstrobel committed Oct 22, 2023
1 parent e5d5628 commit a697f75
Show file tree
Hide file tree
Showing 12 changed files with 287 additions and 305 deletions.
54 changes: 23 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,63 +1,55 @@
# mailtm

The `mailtm` module wraps the [Mail.tm API](https://api.mail.tm) and provides full functionality.
The `mailtm` module wraps the [Mail.tm API](https://api.mail.tm) and provides full functionality.

This is the seconds version. It solves the login problem from version 1 and adds a login with existing credentials.

If you like it, please consider giving it a :star:

###### Install
### Install

`go get github.com/felixstrobel/mailtm`

###### Documentation
### Documentation

Firstly, create an `MailClient` object. This is the object that communicates with the API and contains all important
information.
Firstly, create an `MailClient` object. This is the object that communicates with the API.
```go
import "github.com/felixstrobel/mailtm"

func main() {
client, err := mailtm.NewMailClient()
client, err := mailtm.New()
}
```

After that you can either create an account:
After that you can directly create an account:
```go
client.GetDomains()
client.CreateAccount()
// With random password
client.NewAccount()

// With custom password
client.NewAccountWithPassword("password")
```
You have to fetch the available domains before creating an account (see above). The created account can be accessed through `client.Account`. The account's address and password are randomized.

If you already have an account and know the address and password, you can skip this step and go on with fetching the JWT token.
If you already have an account and know the address and password, you can simply sign back in:
```go
// if you don't have valid credentials:
client.GetAuthToken()

// if you have valid credentials:
client.GetAuthTokenCredentials(yourAddress, yourPassword)
client.RetrieveAccount("your@email.com", "your_password")
```
---
You are authenticated now! You can begin...

...fetching your messages:
##### Fetching your messages of the first page (around 30 messages):
```go
messages, err := client.GetMessages()
client.GetMessages(&account, 1)
```
...get details of a message:
##### Get detailed message:
```go
message, err := client.GetMessageByID(messages[0].ID)
client.GetMessageByID(&account, "the_id_of_the_message")
```
...delete one:
#### Delete a message:
```go
client.DeleteMessageByID(message.ID)
client.DeleteMessageByID(&account, "the_id_of_the_message")
```
...or update the seen status to true:
#### Mark a message as seen:
```go
client.SeenMessageByID(message.ID)
client.SeenMessageByID(&account, "the_id_of_the_message")
```
---
If you decide to delete an account, you can use the `DeleteAccountByID` function to do so:
If you decide to delete an account, you can use the `DeleteAccount` function to do so:
```go
client.DeleteAccountByID(c.Account.ID)
client.DeleteAccount(&account)
```
124 changes: 69 additions & 55 deletions account.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,55 +4,70 @@ import (
"bytes"
"encoding/json"
"errors"
"io/ioutil"
"io"
"net/http"
"time"
)

type Account struct {
ID string `json:"id"`
Address string `json:"address"`
Password string
Token string
ID string `json:"id"`
Address string `json:"address"`
Quota int `json:"quota"`
Used int `json:"used"`
IsDisabled bool `json:"isDisabled"`
IsDeleted bool `json:"isDeleted"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`

Password string
Token string
}

func (c *MailClient) CreateAccount() (*Account, error) {
var account Account
func (c *MailClient) NewAccount() (*Account, error) {
var password, err = RandomString(16)
if err != nil {
return nil, err
}
mailName, err := RandomString(20)

return c.NewAccountWithPassword(password)
}

func (c *MailClient) NewAccountWithPassword(password string) (*Account, error) {
var account Account

domains, err := c.GetDomains()
if err != nil {
return nil, err
}
if len(domains) == 0 {
return nil, errors.New("account hasn't been created due to receiving no domains from the server")
}

handle, err := RandomString(20)
if err != nil {
return nil, err
}

address := mailName + "@" + c.Domain.Path
address := handle + "@" + domains[0].TLD

reqBody, err := json.Marshal(map[string]string{
"address": address,
"password": password,
})

req, err := http.NewRequest("POST", c.Service.Url+"/accounts", bytes.NewBuffer(reqBody))
req, err := http.NewRequest("POST", string(c.service)+"/accounts", bytes.NewBuffer(reqBody))
if err != nil {
return nil, err
}

req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
res, err := c.HttpClient.Do(req)
res, err := c.http.Do(req)
if err != nil {
return nil, err
}

body, err := ioutil.ReadAll(res.Body)
body, err := io.ReadAll(res.Body)
if err != nil {
return nil, err
}
Expand All @@ -64,86 +79,85 @@ func (c *MailClient) CreateAccount() (*Account, error) {

account.Address = address
account.Password = password
c.Account = account

return &account, nil
}

func (c *MailClient) GetAccountByID(id string) (*Account, error) {
var account Account

if c.Token == "" {
return nil, errors.New("please fetch the auth-token first using GetAuthToken()")
}

req, err := http.NewRequest("GET", c.Service.Url+"/accounts/"+id, nil)
err = res.Body.Close()
if err != nil {
return nil, err
}

req.Header.Set("Accept", "application/json")
req.Header.Set("Authorization", "Bearer "+c.Token)
res, err := c.HttpClient.Do(req)
if err != nil {
return nil, err
}
return &account, c.addAuthToken(&account)
}

body, err := ioutil.ReadAll(res.Body)
func (c *MailClient) RetrieveAccount(address string, password string) (*Account, error) {
account := &Account{Address: address, Password: password}
err := c.addAuthToken(account)
if err != nil {
return nil, err
}

err = json.Unmarshal(body, &account)
err = c.UpdateAccountInformation(account)
if err != nil {
return nil, err
}

return &account, nil
return account, nil
}

func (c *MailClient) DeleteAccountByID(id string) error {
if c.Token == "" {
return errors.New("please fetch the auth-token first using GetAuthToken()")
func (c *MailClient) UpdateAccountInformation(account *Account) error {
var response Account

req, err := http.NewRequest("GET", string(c.service)+"/me", nil)
if err != nil {
return err
}

req, err := http.NewRequest("DELETE", c.Service.Url+"/accounts/"+id, nil)
req.Header.Set("Accept", "application/json")
req.Header.Set("Authorization", "Bearer "+account.Token)
res, err := c.http.Do(req)
if err != nil {
return err
}

req.Header.Set("Authorization", "Bearer "+c.Token)
_, err = c.HttpClient.Do(req)
body, err := io.ReadAll(res.Body)
if err != nil {
return err
}

return nil
}
err = json.Unmarshal(body, &response)
if err != nil {
return err
}

func (c *MailClient) GetCurrentAccountInformation() (*Account, error) {
var account Account
account.Quota = response.Quota
account.Used = response.Used
account.UpdatedAt = response.UpdatedAt

req, err := http.NewRequest("GET", c.Service.Url+"/me", nil)
err = res.Body.Close()
if err != nil {
return nil, err
return err
}

req.Header.Add("Authorization", "Bearer "+c.Token)
req.Header.Set("Accept", "application/json")
res, err := c.HttpClient.Do(req)
if err != nil {
return nil, err
return nil
}

func (c *MailClient) DeleteAccount(account *Account) error {
if account.Token == "" {
return errors.New("the account hasn't been deleted because auth token hasn't been found")
}

body, err := ioutil.ReadAll(res.Body)
req, err := http.NewRequest("DELETE", string(c.service)+"/accounts/"+account.ID+"?id="+account.ID, nil)
if err != nil {
return nil, err
return err
}

err = json.Unmarshal(body, &account)
req.Header.Set("Authorization", "Bearer "+account.Token)
res, err := c.http.Do(req)
if err != nil {
return nil, err
return err
}
if res.StatusCode != 204 {
return errors.New("wasn't able to delete account")
}

return &account, nil
return nil
}
81 changes: 81 additions & 0 deletions domain.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package mailtm

import (
"encoding/json"
"io"
"net/http"
"time"
)

type Domain struct {
ID string `json:"id"`
TLD string `json:"domain"`
IsActive bool `json:"isActive"`
IsPrivate bool `json:"isPrivate"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt time.Time `json:"updatedAt"`
}

func (c *MailClient) GetDomains() ([]Domain, error) {
var response []Domain

req, err := http.NewRequest("GET", string(c.service)+"/domains", nil)
if err != nil {
return nil, err
}

req.Header.Add("Accept", "application/json")
res, err := c.http.Do(req)
if err != nil {
return nil, err
}

body, err := io.ReadAll(res.Body)
if err != nil {
return nil, err
}

err = json.Unmarshal(body, &response)
if err != nil {
return nil, err
}

err = res.Body.Close()
if err != nil {
return nil, err
}

return response, nil
}

func (c *MailClient) GetDomainByID(id string) (*Domain, error) {
var response Domain

req, err := http.NewRequest("GET", string(c.service)+"/domains/"+id, nil)
if err != nil {
return nil, err
}

req.Header.Add("Accept", "application/json")
res, err := c.http.Do(req)
if err != nil {
return nil, err
}

body, err := io.ReadAll(res.Body)
if err != nil {
return nil, err
}

err = json.Unmarshal(body, &response)
if err != nil {
return nil, err
}

err = res.Body.Close()
if err != nil {
return nil, err
}

return &response, nil
}
Loading

0 comments on commit a697f75

Please sign in to comment.