Peter Sanchez: 1 Added support to specify which Sendy list-id to integrate with depending on the situation. 6 files changed, 36 insertions(+), 16 deletions(-)
Copy & paste the following snippet into your terminal to import this patchset into git:
curl -s https://lists.code.netlandish.com/~netlandish/links-dev/patches/91/mbox | git am -3Learn more about email & git
Changelog-added: Specify Sendy list-id when integrating per situation --- Also includes some misc cleanup done while working on this. accounts/processors.go | 11 +++++++---- accounts/userfetch.go | 6 +++--- api/graph/schema.resolvers.go | 17 +++++++++-------- billing/processors.go | 14 ++++++++++++++ billing/routes_test.go | 3 ++- config.example.ini | 1 + 6 files changed, 36 insertions(+), 16 deletions(-) diff --git a/accounts/processors.go b/accounts/processors.go index 8aa0fa4..b78e3ee 100644 --- a/accounts/processors.go +++ b/accounts/processors.go @@ -99,12 +99,12 @@ func AddWelcomeLinkTask(user gobwebs.User, gctx *server.Context) *work.Task { }) } -func sendSendySubscribe(ctx context.Context, user gobwebs.User, gctx *server.Context) error { +func sendSendySubscribe(ctx context.Context, user gobwebs.User, gctx *server.Context, listid string) error { u := user.(*models.User) file := gctx.Server.Config.File key, ok1 := file.Get("sendy", "api-key") url, ok2 := file.Get("sendy", "api-url") - list, ok3 := file.Get("sendy", "list-id") + list, ok3 := file.Get("sendy", listid) if !ok1 || !ok2 || !ok3 { gctx.Server.Logger().Printf("No Sendy config present. Failing silently") return nil @@ -124,9 +124,12 @@ func sendSendySubscribe(ctx context.Context, user gobwebs.User, gctx *server.Con return nil } -func SendySubscribeTask(user gobwebs.User, gctx *server.Context) *work.Task { +func SendySubscribeTask(user gobwebs.User, gctx *server.Context, listid string) *work.Task { return work.NewTask(func(ctx context.Context) error { - return sendSendySubscribe(ctx, user, gctx) + if listid == "" { + listid = "list-id" + } + return sendSendySubscribe(ctx, user, gctx, listid) }).Retries(3).Before(func(ctx context.Context, task *work.Task) { gobwebs.TaskIDWork(task) gctx.Server.Logger().Printf( diff --git a/accounts/userfetch.go b/accounts/userfetch.go index c368bfd..6b8bba4 100644 --- a/accounts/userfetch.go +++ b/accounts/userfetch.go @@ -176,7 +176,7 @@ func (u *UserFetch) ProcessSuccessfulEmailConfirmation(c echo.Context) error { } // Sendy - err = gctx.Server.QueueTask("general", SendySubscribeTask(user, gctx)) + err = gctx.Server.QueueTask("general", SendySubscribeTask(user, gctx, "")) if err != nil { gctx.Server.Logger().Printf("Error queueing SendySubscribeTask: %v", err) } @@ -219,9 +219,9 @@ func (u *UserFetch) ProcessLogin(c echo.Context, user gobwebs.User) error { if err != nil { return err } - return fmt.Errorf(lt.Translate("You must verify your email address before logging in")) + return fmt.Errorf("%s", lt.Translate("You must verify your email address before logging in")) } else if linkUser.IsLocked { - return fmt.Errorf(lt.Translate("This account is currently unable to access the system.")) + return fmt.Errorf("%s", lt.Translate("This account is currently unable to access the system.")) } return nil } diff --git a/api/graph/schema.resolvers.go b/api/graph/schema.resolvers.go index 2a3a255..9f02533 100644 --- a/api/graph/schema.resolvers.go +++ b/api/graph/schema.resolvers.go @@ -1286,7 +1286,7 @@ func (r *mutationResolver) Register(ctx context.Context, input *model.RegisterIn // Sendy users list. Log on error srv := server.ForContext(ctx) gctx := c.(*server.Context) - err = srv.QueueTask("general", accounts.SendySubscribeTask(user, gctx)) + err = srv.QueueTask("general", accounts.SendySubscribeTask(user, gctx, "")) if err != nil { gctx.Server.Logger().Printf("Error queueing sendSendySubscribeTask: %v", err) } @@ -1477,7 +1477,7 @@ func (r *mutationResolver) CompleteRegister(ctx context.Context, input *model.Co srv := server.ForContext(ctx) c := server.EchoForContext(ctx) gctx := c.(*server.Context) - err = srv.QueueTask("general", accounts.SendySubscribeTask(user, gctx)) + err = srv.QueueTask("general", accounts.SendySubscribeTask(user, gctx, "")) if err != nil { gctx.Server.Logger().Printf("Error queueing sendSendySubscribeTask: %v", err) } @@ -6238,6 +6238,13 @@ func (r *queryResolver) GetUsers(ctx context.Context, input *model.GetUserInput) return nil, nil } + + if input.After != nil && input.Before != nil { + validator.Error("%s", lt.Translate("You can not send both after and before cursors")). + WithCode(valid.ErrValidationGlobalCode) + return nil, nil + } + opts := &database.FilterOptions{ Filter: sq.And{ sq.Eq{"o.org_type": models.OrgTypeUser}, @@ -6256,12 +6263,6 @@ func (r *queryResolver) GetUsers(ctx context.Context, input *model.GetUserInput) } - if input.After != nil && input.Before != nil { - validator.Error("%s", lt.Translate("You can not send both after and before cursors")). - WithCode(valid.ErrValidationGlobalCode) - return nil, nil - } - numElements := model.PaginationDefault var hasPrevPage bool var hasNextPage bool diff --git a/billing/processors.go b/billing/processors.go index bdc18f8..c75448c 100644 --- a/billing/processors.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "links" + "links/accounts" "links/internal/localizer" "links/models" "strings" @@ -37,6 +38,7 @@ func ProcessCheckoutSessionCompletedTask(ctx context.Context, conf *config.Confi } org := orgs[0] + srv := server.ForContext(ctx) stripeClient, err := GetStripeClient(conf) if err != nil { return err @@ -135,6 +137,17 @@ func ProcessCheckoutSessionCompletedTask(ctx context.Context, conf *config.Confi return err } + // Fetch user and add their email to Sendy paid user list. Ignore error fetching user + user, err := models.GetUser(ctx, org.OwnerID, false) + if err == nil { + gctx := &server.Context{ + Server: srv, + User: user, + } + // Again, ignore errors here. + srv.QueueTask("general", accounts.SendySubscribeTask(user, gctx, "paid-list-id")) + } + return nil } @@ -142,6 +155,7 @@ func CheckoutSessionCompletedTask(srv *server.Server, data map[string]any) *work return work.NewTask(func(ctx context.Context) error { ctx = database.Context(ctx, srv.DB) ctx = timezone.Context(ctx, "UTC") + ctx = server.ServerContext(ctx, srv) return ProcessCheckoutSessionCompletedTask(ctx, srv.Config, data) }).Retries(3).Before(func(ctx context.Context, task *work.Task) { gobwebs.TaskIDWork(task) diff --git a/billing/routes_test.go b/billing/routes_test.go index 70d73d6..3082be4 100644 --- a/billing/routes_test.go @@ -286,7 +286,8 @@ func TestWebhooks(t *testing.T) { httpmock.RegisterResponder("GET", "https://api.stripe.com/v1/subscriptions/stripe_subscription_id_test", httpmock.NewStringResponder(200, string(subscriptionsBody))) - err = billing.ProcessCheckoutSessionCompletedTask(dbCtx, srv.Config, dataMap) + srvCtx := server.ServerContext(dbCtx, srv) + err = billing.ProcessCheckoutSessionCompletedTask(srvCtx, srv.Config, dataMap) c.NoError(err) opts := &database.FilterOptions{ diff --git a/config.example.ini b/config.example.ini index caa93e7..7d56af8 100644 --- a/config.example.ini +++ b/config.example.ini @@ -222,3 +222,4 @@ enabled=true api-key=API Key for Sendy api-url=https://yoursendydomain.com list-id=Sendy List ID +paid-list-id=Sendy Paid User List ID -- 2.47.2
Thanks! To git@git.code.netlandish.com:~netlandish/links fad7b6a..b30ddca master -> master