77 lines
2 KiB
Go
77 lines
2 KiB
Go
package api
|
|
|
|
import (
|
|
"context"
|
|
|
|
"connectrpc.com/connect"
|
|
"github.com/tigorlazuardi/bluemage/go/gen/reddit"
|
|
"github.com/tigorlazuardi/bluemage/go/pkg/errs"
|
|
"github.com/tigorlazuardi/bluemage/go/pkg/log"
|
|
"github.com/tigorlazuardi/bluemage/go/pkg/telemetry"
|
|
)
|
|
|
|
type SubredditResolveNameRequest struct {
|
|
Name string
|
|
Type string
|
|
}
|
|
|
|
func (api *API) SubredditResolveName(ctx context.Context, request SubredditResolveNameRequest) (resolved string, err error) {
|
|
ctx, span := tracer.Start(ctx, "SubredditResolveName")
|
|
defer func() { telemetry.EndWithStatus(span, err) }()
|
|
|
|
ctx, httplog := log.ContextWithRoundTripCollector(ctx)
|
|
typ := reddit.GetListingTypeR
|
|
if request.Type == "user" {
|
|
typ = reddit.GetListingTypeUser
|
|
}
|
|
|
|
resp, err := api.Reddit.GetListing(ctx, reddit.GetListingParams{
|
|
Type: typ,
|
|
Name: request.Name,
|
|
})
|
|
if err != nil {
|
|
err = errs.Wrapw(err, "failed to get listing from reddit", "round_trip", httplog)
|
|
return resolved, err
|
|
}
|
|
|
|
switch resp := resp.(type) {
|
|
case *reddit.GetListingForbidden:
|
|
err = errs.
|
|
Failw(
|
|
"subreddit is private",
|
|
"round_trip", httplog,
|
|
).
|
|
Code(connect.CodePermissionDenied)
|
|
return resolved, err
|
|
case *reddit.GetListingTooManyRequests:
|
|
err = errs.
|
|
Failw(
|
|
"too many requests error response from reddit",
|
|
"round_trip", httplog,
|
|
).
|
|
Code(connect.CodeResourceExhausted)
|
|
return resolved, err
|
|
case *reddit.ListingResponse:
|
|
if !isValidSubreddit(resp) {
|
|
err = errs.
|
|
Failf("subreddit '%s' of type '%s' seems to be empty or not valid", request.Name, request.Type).
|
|
Details("round_trip", httplog).
|
|
Code(connect.CodeNotFound)
|
|
return resolved, err
|
|
}
|
|
data := resp.Data.Children[0].Data
|
|
if request.Type == "user" {
|
|
return data.Author, nil
|
|
}
|
|
return data.Subreddit, nil
|
|
default:
|
|
err = errs.
|
|
Failw("unexpected response from reddit", "round_trip", httplog)
|
|
return resolved, err
|
|
}
|
|
}
|
|
|
|
func isValidSubreddit(list *reddit.ListingResponse) bool {
|
|
return list.Data.After.Null && len(list.Data.Children) == 0
|
|
}
|