Distort your Bluesky avatar based on how much you're tired, according to your WHOOP band
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 76 lines 2.3 kB view raw
1package main 2 3import ( 4 "context" 5 "fmt" 6 "io" 7 "os" 8 9 comatproto "github.com/bluesky-social/indigo/api/atproto" 10 "github.com/bluesky-social/indigo/api/bsky" 11 "github.com/bluesky-social/indigo/atproto/atclient" 12 "github.com/bluesky-social/indigo/atproto/identity" 13 "github.com/bluesky-social/indigo/atproto/syntax" 14 lexutil "github.com/bluesky-social/indigo/lex/util" 15) 16 17// bskyCredentials reads BSKY_USER and BSKY_PASSWORD from the environment. 18func bskyCredentials() (username, password string, err error) { 19 username = os.Getenv("BSKY_USER") 20 if username == "" { 21 return "", "", fmt.Errorf("BSKY_USER environment variable is not set") 22 } 23 password = os.Getenv("BSKY_PASSWORD") 24 if password == "" { 25 return "", "", fmt.Errorf("BSKY_PASSWORD environment variable is not set") 26 } 27 return username, password, nil 28} 29 30// updateAvatar logs in to Bluesky with the given credentials, uploads the 31// image from r, and sets it as the account's avatar. 32func updateAvatar(ctx context.Context, username, password string, r io.Reader) error { 33 dir := identity.DefaultDirectory() 34 atID, err := syntax.ParseAtIdentifier(username) 35 if err != nil { 36 return fmt.Errorf("parsing identifier %q: %w", username, err) 37 } 38 39 client, err := atclient.LoginWithPassword(ctx, dir, atID, password, "", nil) 40 if err != nil { 41 return fmt.Errorf("bluesky login: %w", err) 42 } 43 44 profileNsid := "app.bsky.actor.profile" 45 selfKey := "self" 46 47 currentRecord, err := comatproto.RepoGetRecord(ctx, client, "", profileNsid, client.AccountDID.String(), selfKey) 48 if err != nil { 49 return fmt.Errorf("fetching current profile record: %w", err) 50 } 51 52 profile, ok := currentRecord.Value.Val.(*bsky.ActorProfile) 53 if !ok { 54 return fmt.Errorf("unexpected profile record type: %T", currentRecord.Value.Val) 55 } 56 57 uploaded, err := comatproto.RepoUploadBlob(ctx, client, r) 58 if err != nil { 59 return fmt.Errorf("uploading avatar blob: %w", err) 60 } 61 62 profile.Avatar = uploaded.Blob 63 64 _, err = comatproto.RepoPutRecord(ctx, client, &comatproto.RepoPutRecord_Input{ 65 Collection: profileNsid, 66 Repo: client.AccountDID.String(), 67 Rkey: selfKey, 68 SwapRecord: currentRecord.Cid, 69 Record: &lexutil.LexiconTypeDecoder{Val: profile}, 70 }) 71 if err != nil { 72 return fmt.Errorf("updating profile: %w", err) 73 } 74 75 return nil 76}