Laravel AT Protocol Client (alpha & unstable)
at dev 4.4 kB view raw
1<?php 2 3namespace SocialDept\AtpClient\Client\Records; 4 5use SocialDept\AtpClient\Attributes\ScopedEndpoint; 6use SocialDept\AtpClient\Client\Requests\Request; 7use SocialDept\AtpClient\Data\Record; 8use SocialDept\AtpClient\Data\Responses\Atproto\Repo\PutRecordResponse; 9use SocialDept\AtpClient\Enums\Nsid\BskyActor; 10use SocialDept\AtpClient\Enums\Scope; 11 12class ProfileRecordClient extends Request 13{ 14 /** 15 * Update profile 16 * 17 * @requires transition:generic OR (rpc:com.atproto.repo.putRecord AND repo:app.bsky.actor.profile?action=update) 18 */ 19 #[ScopedEndpoint(Scope::TransitionGeneric, granular: 'rpc:com.atproto.repo.putRecord')] 20 #[ScopedEndpoint(Scope::TransitionGeneric, granular: 'repo:app.bsky.actor.profile?action=update')] 21 public function update(array $profile): PutRecordResponse 22 { 23 // Ensure $type is set 24 if (! isset($profile['$type'])) { 25 $profile['$type'] = BskyActor::Profile->value; 26 } 27 28 return $this->atp->atproto->repo->putRecord( 29 collection: BskyActor::Profile, 30 rkey: 'self', // Profile records always use 'self' as rkey 31 record: $profile 32 ); 33 } 34 35 /** 36 * Get current profile 37 * 38 * @requires transition:generic (rpc:com.atproto.repo.getRecord) 39 */ 40 #[ScopedEndpoint(Scope::TransitionGeneric, granular: 'rpc:com.atproto.repo.getRecord')] 41 public function get(): Record 42 { 43 $response = $this->atp->atproto->repo->getRecord( 44 repo: $this->atp->client->session()->did(), 45 collection: BskyActor::Profile, 46 rkey: 'self' 47 ); 48 49 return Record::fromArrayRaw($response->toArray()); 50 } 51 52 /** 53 * Update display name 54 * 55 * @requires transition:generic OR (rpc:com.atproto.repo.putRecord AND repo:app.bsky.actor.profile?action=update) 56 */ 57 #[ScopedEndpoint(Scope::TransitionGeneric, granular: 'rpc:com.atproto.repo.putRecord')] 58 #[ScopedEndpoint(Scope::TransitionGeneric, granular: 'repo:app.bsky.actor.profile?action=update')] 59 public function updateDisplayName(string $displayName): PutRecordResponse 60 { 61 $profile = $this->getOrCreateProfile(); 62 $profile['displayName'] = $displayName; 63 64 return $this->update($profile); 65 } 66 67 /** 68 * Update description/bio 69 * 70 * @requires transition:generic OR (rpc:com.atproto.repo.putRecord AND repo:app.bsky.actor.profile?action=update) 71 */ 72 #[ScopedEndpoint(Scope::TransitionGeneric, granular: 'rpc:com.atproto.repo.putRecord')] 73 #[ScopedEndpoint(Scope::TransitionGeneric, granular: 'repo:app.bsky.actor.profile?action=update')] 74 public function updateDescription(string $description): PutRecordResponse 75 { 76 $profile = $this->getOrCreateProfile(); 77 $profile['description'] = $description; 78 79 return $this->update($profile); 80 } 81 82 /** 83 * Update avatar 84 * 85 * @requires transition:generic OR (rpc:com.atproto.repo.putRecord AND repo:app.bsky.actor.profile?action=update) 86 */ 87 #[ScopedEndpoint(Scope::TransitionGeneric, granular: 'rpc:com.atproto.repo.putRecord')] 88 #[ScopedEndpoint(Scope::TransitionGeneric, granular: 'repo:app.bsky.actor.profile?action=update')] 89 public function updateAvatar(array $avatarBlob): PutRecordResponse 90 { 91 $profile = $this->getOrCreateProfile(); 92 $profile['avatar'] = $avatarBlob; 93 94 return $this->update($profile); 95 } 96 97 /** 98 * Update banner 99 * 100 * @requires transition:generic OR (rpc:com.atproto.repo.putRecord AND repo:app.bsky.actor.profile?action=update) 101 */ 102 #[ScopedEndpoint(Scope::TransitionGeneric, granular: 'rpc:com.atproto.repo.putRecord')] 103 #[ScopedEndpoint(Scope::TransitionGeneric, granular: 'repo:app.bsky.actor.profile?action=update')] 104 public function updateBanner(array $bannerBlob): PutRecordResponse 105 { 106 $profile = $this->getOrCreateProfile(); 107 $profile['banner'] = $bannerBlob; 108 109 return $this->update($profile); 110 } 111 112 /** 113 * Get profile or create empty one if doesn't exist 114 */ 115 protected function getOrCreateProfile(): array 116 { 117 try { 118 return $this->get()->value; 119 } catch (\Exception $e) { 120 // Profile doesn't exist, return empty structure 121 return [ 122 '$type' => BskyActor::Profile->value, 123 ]; 124 } 125 } 126}