forked from tangled.org/core
this repo has no description

appview: initial posthog events

+6
appview/config.go
···
SharedSecret string `env:"SHARED_SECRET"`
}
+
type PosthogConfig struct {
+
ApiKey string `env:"API_KEY"`
+
Endpoint string `env:"ENDPOINT, default=https://eu.i.posthog.com"`
+
}
+
type Config struct {
Core CoreConfig `env:",prefix=TANGLED_"`
Jetstream JetstreamConfig `env:",prefix=TANGLED_JETSTREAM_"`
Resend ResendConfig `env:",prefix=TANGLED_RESEND_"`
+
Posthog PosthogConfig `env:",prefix=TANGLED_POSTHOG_"`
Camo CamoConfig `env:",prefix=TANGLED_CAMO_"`
Avatar AvatarConfig `env:",prefix=TANGLED_AVATAR_"`
OAuth OAuthConfig `env:",prefix=TANGLED_OAUTH_"`
+12
appview/oauth/handler/handler.go
···
"github.com/gorilla/sessions"
"github.com/haileyok/atproto-oauth-golang/helpers"
"github.com/lestrrat-go/jwx/v2/jwk"
+
"github.com/posthog/posthog-go"
"tangled.sh/tangled.sh/core/appview"
"tangled.sh/tangled.sh/core/appview/db"
"tangled.sh/tangled.sh/core/appview/knotclient"
···
Store *sessions.CookieStore
OAuth *oauth.OAuth
Enforcer *rbac.Enforcer
+
Posthog posthog.Client
}
func (o *OAuthHandler) Router() http.Handler {
···
log.Println("session saved successfully")
go o.addToDefaultKnot(oauthRequest.Did)
+
+
if !o.Config.Core.Dev {
+
err = o.Posthog.Enqueue(posthog.Capture{
+
DistinctId: oauthRequest.Did,
+
Event: "signin",
+
})
+
if err != nil {
+
log.Println("failed to enqueue posthog event:", err)
+
}
+
}
http.Redirect(w, r, "/", http.StatusFound)
}
+23
appview/state/follow.go
···
comatproto "github.com/bluesky-social/indigo/api/atproto"
lexutil "github.com/bluesky-social/indigo/lex/util"
+
"github.com/posthog/posthog-go"
"tangled.sh/tangled.sh/core/api/tangled"
"tangled.sh/tangled.sh/core/appview"
"tangled.sh/tangled.sh/core/appview/db"
···
FollowStatus: db.IsFollowing,
})
+
if !s.config.Core.Dev {
+
err = s.posthog.Enqueue(posthog.Capture{
+
DistinctId: currentUser.Did,
+
Event: "follow",
+
Properties: posthog.Properties{"subject": subjectIdent.DID.String()},
+
})
+
if err != nil {
+
log.Println("failed to enqueue posthog event:", err)
+
}
+
}
+
return
case http.MethodDelete:
// find the record in the db
···
UserDid: subjectIdent.DID.String(),
FollowStatus: db.IsNotFollowing,
})
+
+
if !s.config.Core.Dev {
+
err = s.posthog.Enqueue(posthog.Capture{
+
DistinctId: currentUser.Did,
+
Event: "unfollow",
+
Properties: posthog.Properties{"subject": subjectIdent.DID.String()},
+
})
+
if err != nil {
+
log.Println("failed to enqueue posthog event:", err)
+
}
+
}
return
}
+11
appview/state/profile.go
···
"github.com/bluesky-social/indigo/atproto/syntax"
lexutil "github.com/bluesky-social/indigo/lex/util"
"github.com/go-chi/chi/v5"
+
"github.com/posthog/posthog-go"
"tangled.sh/tangled.sh/core/api/tangled"
"tangled.sh/tangled.sh/core/appview/db"
"tangled.sh/tangled.sh/core/appview/pages"
···
log.Println("failed to update profile", err)
s.pages.Notice(w, "update-profile", "Failed to update profile, try again later.")
return
+
}
+
+
if !s.config.Core.Dev {
+
err = s.posthog.Enqueue(posthog.Capture{
+
DistinctId: user.Did,
+
Event: "edit_profile",
+
})
+
if err != nil {
+
log.Println("failed to enqueue posthog event:", err)
+
}
}
s.pages.HxRedirect(w, "/"+user.Did)
+23
appview/state/pull.go
···
lexutil "github.com/bluesky-social/indigo/lex/util"
"github.com/go-chi/chi/v5"
"github.com/google/uuid"
+
"github.com/posthog/posthog-go"
)
// htmx fragment
···
return
}
+
if !s.config.Core.Dev {
+
err = s.posthog.Enqueue(posthog.Capture{
+
DistinctId: user.Did,
+
Event: "new_pull_comment",
+
Properties: posthog.Properties{"repo_at": f.RepoAt.String(), "pull_id": pull.PullId},
+
})
+
if err != nil {
+
log.Println("failed to enqueue posthog event:", err)
+
}
+
}
+
s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d#comment-%d", f.OwnerSlashRepo(), pull.PullId, commentId))
return
}
···
log.Println("failed to create pull request", err)
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
return
+
}
+
+
if !s.config.Core.Dev {
+
err = s.posthog.Enqueue(posthog.Capture{
+
DistinctId: user.Did,
+
Event: "new_pull",
+
Properties: posthog.Properties{"repo_at": f.RepoAt.String(), "pull_id": pullId},
+
})
+
if err != nil {
+
log.Println("failed to enqueue posthog event:", err)
+
}
}
s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d", f.OwnerSlashRepo(), pullId))
+12
appview/state/repo.go
···
securejoin "github.com/cyphar/filepath-securejoin"
"github.com/go-chi/chi/v5"
"github.com/go-git/go-git/v5/plumbing"
+
"github.com/posthog/posthog-go"
comatproto "github.com/bluesky-social/indigo/api/atproto"
lexutil "github.com/bluesky-social/indigo/lex/util"
···
log.Println("failed to set issue at", err)
s.pages.Notice(w, "issues", "Failed to create issue.")
return
+
}
+
+
if !s.config.Core.Dev {
+
err = s.posthog.Enqueue(posthog.Capture{
+
DistinctId: user.Did,
+
Event: "new_issue",
+
Properties: posthog.Properties{"repo_at": f.RepoAt.String(), "issue_id": issueId},
+
})
+
if err != nil {
+
log.Println("failed to enqueue posthog event:", err)
+
}
s.pages.HxLocation(w, fmt.Sprintf("/%s/issues/%d", f.OwnerSlashRepo(), issueId))
+1
appview/state/router.go
···
Store: sessions.NewCookieStore([]byte(s.config.Core.CookieSecret)),
OAuth: s.oauth,
Enforcer: s.enforcer,
+
Posthog: s.posthog,
}
return oauth.Router()
+23
appview/state/star.go
···
comatproto "github.com/bluesky-social/indigo/api/atproto"
"github.com/bluesky-social/indigo/atproto/syntax"
lexutil "github.com/bluesky-social/indigo/lex/util"
+
"github.com/posthog/posthog-go"
"tangled.sh/tangled.sh/core/api/tangled"
"tangled.sh/tangled.sh/core/appview"
"tangled.sh/tangled.sh/core/appview/db"
···
},
})
+
if !s.config.Core.Dev {
+
err = s.posthog.Enqueue(posthog.Capture{
+
DistinctId: currentUser.Did,
+
Event: "star",
+
Properties: posthog.Properties{"repo_at": subjectUri.String()},
+
})
+
if err != nil {
+
log.Println("failed to enqueue posthog event:", err)
+
}
+
}
+
return
case http.MethodDelete:
// find the record in the db
···
StarCount: starCount,
},
})
+
+
if !s.config.Core.Dev {
+
err = s.posthog.Enqueue(posthog.Capture{
+
DistinctId: currentUser.Did,
+
Event: "unstar",
+
Properties: posthog.Properties{"repo_at": subjectUri.String()},
+
})
+
if err != nil {
+
log.Println("failed to enqueue posthog event:", err)
+
}
+
}
return
}
+19 -76
appview/state/state.go
···
lexutil "github.com/bluesky-social/indigo/lex/util"
securejoin "github.com/cyphar/filepath-securejoin"
"github.com/go-chi/chi/v5"
+
"github.com/posthog/posthog-go"
"tangled.sh/tangled.sh/core/api/tangled"
"tangled.sh/tangled.sh/core/appview"
"tangled.sh/tangled.sh/core/appview/db"
···
tidClock syntax.TIDClock
pages *pages.Pages
resolver *appview.Resolver
+
posthog posthog.Client
jc *jetstream.JetstreamClient
config *appview.Config
}
···
oauth := oauth.NewOAuth(d, config)
+
posthog, err := posthog.NewWithConfig(config.Posthog.ApiKey, posthog.Config{Endpoint: config.Posthog.Endpoint})
+
if err != nil {
+
return nil, fmt.Errorf("failed to create posthog client: %w", err)
+
}
+
wrapper := db.DbWrapper{d}
jc, err := jetstream.NewJetstreamClient(
config.Jetstream.Endpoint,
···
clock,
pgs,
resolver,
+
posthog,
jc,
config,
}
···
func TID(c *syntax.TIDClock) string {
return c.Next().String()
}
-
-
// func (s *State) Login(w http.ResponseWriter, r *http.Request) {
-
// ctx := r.Context()
-
-
// switch r.Method {
-
// case http.MethodGet:
-
// err := s.pages.Login(w, pages.LoginParams{})
-
// if err != nil {
-
// log.Printf("rendering login page: %s", err)
-
// }
-
-
// return
-
// case http.MethodPost:
-
// handle := strings.TrimPrefix(r.FormValue("handle"), "@")
-
// appPassword := r.FormValue("app_password")
-
-
// resolved, err := s.resolver.ResolveIdent(ctx, handle)
-
// if err != nil {
-
// log.Println("failed to resolve handle:", err)
-
// s.pages.Notice(w, "login-msg", fmt.Sprintf("\"%s\" is an invalid handle.", handle))
-
// return
-
// }
-
-
// atSession, err := s.oauth.CreateInitialSession(ctx, resolved, appPassword)
-
// if err != nil {
-
// s.pages.Notice(w, "login-msg", "Invalid handle or password.")
-
// return
-
// }
-
// sessionish := auth.CreateSessionWrapper{ServerCreateSession_Output: atSession}
-
-
// err = s.oauth.StoreSession(r, w, &sessionish, resolved.PDSEndpoint())
-
// if err != nil {
-
// s.pages.Notice(w, "login-msg", "Failed to login, try again later.")
-
// return
-
// }
-
-
// log.Printf("successfully saved session for %s (%s)", atSession.Handle, atSession.Did)
-
-
// did := resolved.DID.String()
-
// defaultKnot := "knot1.tangled.sh"
-
-
// go func() {
-
// log.Printf("adding %s to default knot", did)
-
// err = s.enforcer.AddMember(defaultKnot, did)
-
// if err != nil {
-
// log.Println("failed to add user to knot1.tangled.sh: ", err)
-
// return
-
// }
-
// err = s.enforcer.E.SavePolicy()
-
// if err != nil {
-
// log.Println("failed to add user to knot1.tangled.sh: ", err)
-
// return
-
// }
-
-
// secret, err := db.GetRegistrationKey(s.db, defaultKnot)
-
// if err != nil {
-
// log.Println("failed to get registration key for knot1.tangled.sh")
-
// return
-
// }
-
// signedClient, err := NewSignedClient(defaultKnot, secret, s.config.Core.Dev)
-
// resp, err := signedClient.AddMember(did)
-
// if err != nil {
-
// log.Println("failed to add user to knot1.tangled.sh: ", err)
-
// return
-
// }
-
-
// if resp.StatusCode != http.StatusNoContent {
-
// log.Println("failed to add user to knot1.tangled.sh: ", resp.StatusCode)
-
// return
-
// }
-
// }()
-
-
// s.pages.HxRedirect(w, "/")
-
// return
-
// }
-
// }
func (s *State) Logout(w http.ResponseWriter, r *http.Request) {
s.oauth.ClearSession(r, w)
···
log.Println("failed to update ACLs", err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
+
}
+
+
if !s.config.Core.Dev {
+
err = s.posthog.Enqueue(posthog.Capture{
+
DistinctId: user.Did,
+
Event: "new_repo",
+
Properties: posthog.Properties{"repo": repoName, "repo_at": repo.AtUri},
+
})
+
if err != nil {
+
log.Println("failed to enqueue posthog event:", err)
+
}
}
s.pages.HxLocation(w, fmt.Sprintf("/@%s/%s", user.Handle, repoName))
+1
go.mod
···
github.com/lestrrat-go/jwx/v2 v2.0.12
github.com/mattn/go-sqlite3 v1.14.24
github.com/microcosm-cc/bluemonday v1.0.27
+
github.com/posthog/posthog-go v1.5.5
github.com/resend/resend-go/v2 v2.15.0
github.com/sethvargo/go-envconfig v1.1.0
github.com/whyrusleeping/cbor-gen v0.2.1-0.20241030202151-b7a6831be65e
+2
go.sum
···
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/polydawn/refmt v0.89.1-0.20221221234430-40501e09de1f h1:VXTQfuJj9vKR4TCkEuWIckKvdHFeJH/huIFJ9/cXOB0=
github.com/polydawn/refmt v0.89.1-0.20221221234430-40501e09de1f/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw=
+
github.com/posthog/posthog-go v1.5.5 h1:2o3j7IrHbTIfxRtj4MPaXKeimuTYg49onNzNBZbwksM=
+
github.com/posthog/posthog-go v1.5.5/go.mod h1:3RqUmSnPuwmeVj/GYrS75wNGqcAKdpODiwc83xZWgdE=
github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=