Skip to content

Instantly share code, notes, and snippets.

@alexellis

alexellis/sponsors.go

Last active Oct 3, 2020
Embed
What would you like to do?
sponsors.go - query whether a GitHub user is your sponsor at a given tier (dollar amount)
// LICENSE for this file: MIT
// Copyright: Alex Ellis, OpenFaaS Ltd 2020
// You may not remove this notice
package handlers
import (
"context"
"encoding/json"
"os"
"github.com/shurcooL/githubv4"
"golang.org/x/oauth2"
)
const minDollars = 25
type SponsorTier struct {
MonthlyPriceInDollars int
}
// SponsorEntity is the User sponsoring
type SponsorEntity struct {
// SponsorUser with an annotation that expands the Union for the User type
SponsorUser SponsorUser `graphql:"... on User"`
}
// Sponsorable is the User receiving the sponsorshop
type Sponsorable struct {
// SponsorUser with an annotation that expands the Union for the User type
SponsorUser SponsorUser `graphql:"... on User"`
}
// SponsorUser is a User associated with either side of a
// sponsorship
type SponsorUser struct {
// Login name of the sponsor.
Login string
}
// IsSponsoring returns true if the login for the associated
// accessToken has an active sponsorship for the target login of
// the hard-coded dollar amount.
// The accessToken requires the whole "user" scope to read the
// dollar amount.
func IsSponsoring(login, target, accessToken string) (bool, error) {
// it's not possible to sponsor oneself
if login == target {
return true, nil
}
src := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: accessToken},
)
httpClient := oauth2.NewClient(context.Background(), src)
client := githubv4.NewClient(httpClient)
var q sponsorships
ctx := context.Background()
err := client.Query(ctx, &q, map[string]interface{}{})
if err != nil {
return false, err
}
// printJSON(q.Viewer.SponsorshipsAsSponsor.Nodes)
var users []SponsorUser
for _, node := range q.Viewer.SponsorshipsAsSponsor.Nodes {
sponsor := node.SponsorEntity.SponsorUser
if node.Sponsorable.SponsorUser.Login == target &&
node.Tier.MonthlyPriceInDollars >= minDollars {
users = append(users, sponsor)
}
}
for _, s := range users {
if s.Login == login {
return true, nil
}
}
return false, nil
}
// sponsorships is the query for graphql and it limits
// the search to 100, since most people will not be
// sponsoring more than a few other developers.
type sponsorships struct {
Viewer struct {
Login string
SponsorshipsAsSponsor struct {
Nodes []struct {
SponsorEntity SponsorEntity
Sponsorable Sponsorable
Tier SponsorTier
}
} `graphql:"sponsorshipsAsSponsor(first: 100)"`
}
}
// printJSON is from the github.com/shurcooL/githubv4 library
// and prints the response for debugging.
func printJSON(v interface{}) {
w := json.NewEncoder(os.Stdout)
w.SetIndent("", "\t")
err := w.Encode(v)
if err != nil {
panic(err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.