Go

Use FreeStuff API in any Go project using a community maintained package.

Freego

Freego is a comprehensive go library with support for the full API v2, including REST Api and Webhook handling.

Maintained by: eoussama

GitHub: https://github.com/eoussama/freego

Go Packages: https://pkg.go.dev/github.com/eoussama/freego

Install

go get github.com/eoussama/freego

Usage

package main

import (
    "context"
    "log"
    "os"
    "os/signal"

    "github.com/eoussama/freego"
    "github.com/eoussama/freego/webhook"
)

func main() {
  // Setting up a webhook receiver

    verifier, err := webhook.NewVerifier(os.Getenv("FREEGO_FREESTUFF_PUBLIC_KEY"))
    if err != nil {
        log.Fatal(err)
    }

    handler := webhook.NewHandler(verifier, webhook.Config{
        OnAnnouncementCreated: func(ctx context.Context, e *webhook.Event, a *freego.ResolvedAnnouncement) error {
            for _, p := range a.ResolvedProducts {
                if p.ShouldIgnore() {
                    continue
                }
                url, _ := p.BestURL(freego.URLFlagOpensInBrowser)
                log.Printf("%s is free on %s: %s", p.Title, p.Store, url.URL)
            }
            return nil
        },
        OnProductUpdated: func(ctx context.Context, e *webhook.Event, p *freego.Product) error {
            log.Printf("%s was updated", p.Title)
            return nil
        },
        OnError: func(ctx context.Context, e *webhook.Event, err error) {
            log.Print(err)
        },
    })

    ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
    defer stop()
    if err := webhook.ListenAndServe(ctx, ":8080", "/webhook", handler); err != nil {
        log.Fatal(err)
    }

  // Using the REST Api

  client, err := freego.New(os.Getenv("FREEGO_FREESTUFF_API_KEY"))
  if err != nil {
    log.Fatal(err)
  }

  ctx := context.Background()

  // Check the API and the key. Works on every plan.
  if err := client.Ping(ctx); err != nil {
    log.Fatal(err)
  }

  // List products (full tier). Without Resolve, only partial products are
  // returned: ID, Kind, Until, Type, Flags and Store.
  list, err := client.Products(ctx, &freego.ProductsQuery{
    Type:    freego.ChannelKeep,
    Resolve: true,
  })
  if errors.Is(err, freego.ErrUnavailableForFreeTier) {
    log.Fatal("listing products requires the full tier")
  }

  // Walk every page.
  it := client.ProductsIter(&freego.ProductsQuery{Resolve: true})
  for it.Next(ctx) {
    fmt.Println(it.Product().Title)
  }
  if err := it.Err(); err != nil {
    log.Fatal(err)
  }

  // Look up one product.
  product, err := client.Product(ctx, 123456)
}

See GitHub for the full and up to date documentation.