github.com/mailgun/mailgun-go/v3@v3.6.4/tags.go (about)

     1  package mailgun
     2  
     3  import (
     4  	"context"
     5  	"net/url"
     6  	"strconv"
     7  	"time"
     8  )
     9  
    10  type Tag struct {
    11  	Value       string     `json:"tag"`
    12  	Description string     `json:"description"`
    13  	FirstSeen   *time.Time `json:"first-seen,omitempty"`
    14  	LastSeen    *time.Time `json:"last-seen,omitempty"`
    15  }
    16  
    17  type tagsResponse struct {
    18  	Items  []Tag  `json:"items"`
    19  	Paging Paging `json:"paging"`
    20  }
    21  
    22  type ListTagOptions struct {
    23  	// Restrict the page size to this limit
    24  	Limit int
    25  	// Return only the tags starting with the given prefix
    26  	Prefix string
    27  }
    28  
    29  // DeleteTag removes all counters for a particular tag, including the tag itself.
    30  func (mg *MailgunImpl) DeleteTag(ctx context.Context, tag string) error {
    31  	r := newHTTPRequest(generateApiUrl(mg, tagsEndpoint) + "/" + tag)
    32  	r.setClient(mg.Client())
    33  	r.setBasicAuth(basicAuthUser, mg.APIKey())
    34  	_, err := makeDeleteRequest(ctx, r)
    35  	return err
    36  }
    37  
    38  // GetTag retrieves metadata about the tag from the api
    39  func (mg *MailgunImpl) GetTag(ctx context.Context, tag string) (Tag, error) {
    40  	r := newHTTPRequest(generateApiUrl(mg, tagsEndpoint) + "/" + tag)
    41  	r.setClient(mg.Client())
    42  	r.setBasicAuth(basicAuthUser, mg.APIKey())
    43  	var tagItem Tag
    44  	return tagItem, getResponseFromJSON(ctx, r, &tagItem)
    45  }
    46  
    47  // ListTags returns a cursor used to iterate through a list of tags
    48  //	it := mg.ListTags(nil)
    49  //	var page []mailgun.Tag
    50  //	for it.Next(&page) {
    51  //		for _, tag := range(page) {
    52  //			// Do stuff with tags
    53  //		}
    54  //	}
    55  //	if it.Err() != nil {
    56  //		log.Fatal(it.Err())
    57  //	}
    58  func (mg *MailgunImpl) ListTags(opts *ListTagOptions) *TagIterator {
    59  	req := newHTTPRequest(generateApiUrl(mg, tagsEndpoint))
    60  	if opts != nil {
    61  		if opts.Limit != 0 {
    62  			req.addParameter("limit", strconv.Itoa(opts.Limit))
    63  		}
    64  		if opts.Prefix != "" {
    65  			req.addParameter("prefix", opts.Prefix)
    66  		}
    67  	}
    68  
    69  	url, err := req.generateUrlWithParameters()
    70  	return &TagIterator{
    71  		tagsResponse: tagsResponse{Paging: Paging{Next: url, First: url}},
    72  		err:          err,
    73  		mg:           mg,
    74  	}
    75  }
    76  
    77  type TagIterator struct {
    78  	tagsResponse
    79  	mg  Mailgun
    80  	err error
    81  }
    82  
    83  // Next returns the next page in the list of tags
    84  func (ti *TagIterator) Next(ctx context.Context, items *[]Tag) bool {
    85  	if ti.err != nil {
    86  		return false
    87  	}
    88  
    89  	if !canFetchPage(ti.Paging.Next) {
    90  		return false
    91  	}
    92  
    93  	ti.err = ti.fetch(ctx, ti.Paging.Next)
    94  	if ti.err != nil {
    95  		return false
    96  	}
    97  	*items = ti.Items
    98  	if len(ti.Items) == 0 {
    99  		return false
   100  	}
   101  	return true
   102  }
   103  
   104  // Previous returns the previous page in the list of tags
   105  func (ti *TagIterator) Previous(ctx context.Context, items *[]Tag) bool {
   106  	if ti.err != nil {
   107  		return false
   108  	}
   109  
   110  	if ti.Paging.Previous == "" {
   111  		return false
   112  	}
   113  
   114  	if !canFetchPage(ti.Paging.Previous) {
   115  		return false
   116  	}
   117  
   118  	ti.err = ti.fetch(ctx, ti.Paging.Previous)
   119  	if ti.err != nil {
   120  		return false
   121  	}
   122  	*items = ti.Items
   123  	if len(ti.Items) == 0 {
   124  		return false
   125  	}
   126  	return true
   127  }
   128  
   129  // First returns the first page in the list of tags
   130  func (ti *TagIterator) First(ctx context.Context, items *[]Tag) bool {
   131  	if ti.err != nil {
   132  		return false
   133  	}
   134  	ti.err = ti.fetch(ctx, ti.Paging.First)
   135  	if ti.err != nil {
   136  		return false
   137  	}
   138  	*items = ti.Items
   139  	return true
   140  }
   141  
   142  // Last returns the last page in the list of tags
   143  func (ti *TagIterator) Last(ctx context.Context, items *[]Tag) bool {
   144  	if ti.err != nil {
   145  		return false
   146  	}
   147  	ti.err = ti.fetch(ctx, ti.Paging.Last)
   148  	if ti.err != nil {
   149  		return false
   150  	}
   151  	*items = ti.Items
   152  	return true
   153  }
   154  
   155  // Err returns any error if one occurred
   156  func (ti *TagIterator) Err() error {
   157  	return ti.err
   158  }
   159  
   160  func (ti *TagIterator) fetch(ctx context.Context, url string) error {
   161  	req := newHTTPRequest(url)
   162  	req.setClient(ti.mg.Client())
   163  	req.setBasicAuth(basicAuthUser, ti.mg.APIKey())
   164  	return getResponseFromJSON(ctx, req, &ti.tagsResponse)
   165  }
   166  
   167  func canFetchPage(slug string) bool {
   168  	parts, err := url.Parse(slug)
   169  	if err != nil {
   170  		return false
   171  	}
   172  	params, _ := url.ParseQuery(parts.RawQuery)
   173  	if err != nil {
   174  		return false
   175  	}
   176  	value, ok := params["tag"]
   177  	// If tags doesn't exist, it's our first time fetching pages
   178  	if !ok {
   179  		return true
   180  	}
   181  	// If tags has no value, there are no more pages to fetch
   182  	return len(value) == 0
   183  }