Laravel AT Protocol Client (alpha & unstable)
at dev 4.6 kB view raw
1<?php 2 3namespace SocialDept\AtpClient\Client\Records; 4 5use DateTimeInterface; 6use SocialDept\AtpClient\Attributes\ScopedEndpoint; 7use SocialDept\AtpClient\Builders\PostBuilder; 8use SocialDept\AtpClient\Client\Requests\Request; 9use SocialDept\AtpClient\Contracts\Recordable; 10use SocialDept\AtpClient\Data\Record; 11use SocialDept\AtpClient\Data\Responses\Atproto\Repo\CreateRecordResponse; 12use SocialDept\AtpClient\Data\Responses\Atproto\Repo\DeleteRecordResponse; 13use SocialDept\AtpClient\Data\Responses\Atproto\Repo\PutRecordResponse; 14use SocialDept\AtpClient\Data\StrongRef; 15use SocialDept\AtpClient\Enums\Nsid\BskyFeed; 16use SocialDept\AtpClient\Enums\Scope; 17use SocialDept\AtpClient\RichText\TextBuilder; 18use SocialDept\AtpSchema\Generated\App\Bsky\Feed\Defs\PostView; 19 20class PostRecordClient extends Request 21{ 22 /** 23 * Create a new post builder bound to this client 24 */ 25 public function build(): PostBuilder 26 { 27 return PostBuilder::make()->for($this); 28 } 29 30 /** 31 * Create a post 32 * 33 * @requires transition:generic OR (rpc:com.atproto.repo.createRecord AND repo:app.bsky.feed.post?action=create) 34 */ 35 #[ScopedEndpoint(Scope::TransitionGeneric, granular: 'rpc:com.atproto.repo.createRecord')] 36 #[ScopedEndpoint(Scope::TransitionGeneric, granular: 'repo:app.bsky.feed.post?action=create')] 37 public function create( 38 string|array|Recordable $content, 39 ?array $facets = null, 40 ?array $embed = null, 41 ?array $reply = null, 42 ?array $langs = null, 43 ?DateTimeInterface $createdAt = null 44 ): CreateRecordResponse { 45 // Handle different input types 46 if (is_string($content)) { 47 $record = [ 48 'text' => $content, 49 'facets' => $facets ?? TextBuilder::parse($content)['facets'], 50 ]; 51 } elseif ($content instanceof Recordable) { 52 $record = $content->toArray(); 53 } else { 54 $record = $content; 55 } 56 57 // Add optional fields (only for non-Recordable inputs) 58 if (! ($content instanceof Recordable)) { 59 if ($embed) { 60 $record['embed'] = $embed; 61 } 62 if ($reply) { 63 $record['reply'] = $reply; 64 } 65 if ($langs) { 66 $record['langs'] = $langs; 67 } 68 } 69 70 if (! isset($record['createdAt'])) { 71 $record['createdAt'] = ($createdAt ?? now())->format('c'); 72 } 73 74 // Ensure $type is set 75 if (! isset($record['$type'])) { 76 $record['$type'] = BskyFeed::Post->value; 77 } 78 79 return $this->atp->atproto->repo->createRecord( 80 collection: BskyFeed::Post, 81 record: $record 82 ); 83 } 84 85 /** 86 * Update a post 87 * 88 * @requires transition:generic OR (rpc:com.atproto.repo.putRecord AND repo:app.bsky.feed.post?action=update) 89 */ 90 #[ScopedEndpoint(Scope::TransitionGeneric, granular: 'rpc:com.atproto.repo.putRecord')] 91 #[ScopedEndpoint(Scope::TransitionGeneric, granular: 'repo:app.bsky.feed.post?action=update')] 92 public function update(string $rkey, array $record): PutRecordResponse 93 { 94 // Ensure $type is set 95 if (! isset($record['$type'])) { 96 $record['$type'] = BskyFeed::Post->value; 97 } 98 99 return $this->atp->atproto->repo->putRecord( 100 collection: BskyFeed::Post, 101 rkey: $rkey, 102 record: $record 103 ); 104 } 105 106 /** 107 * Delete a post 108 * 109 * @requires transition:generic OR (rpc:com.atproto.repo.deleteRecord AND repo:app.bsky.feed.post?action=delete) 110 */ 111 #[ScopedEndpoint(Scope::TransitionGeneric, granular: 'rpc:com.atproto.repo.deleteRecord')] 112 #[ScopedEndpoint(Scope::TransitionGeneric, granular: 'repo:app.bsky.feed.post?action=delete')] 113 public function delete(string $rkey): DeleteRecordResponse 114 { 115 return $this->atp->atproto->repo->deleteRecord( 116 collection: BskyFeed::Post, 117 rkey: $rkey 118 ); 119 } 120 121 /** 122 * Get a post 123 * 124 * @requires transition:generic (rpc:com.atproto.repo.getRecord) 125 */ 126 #[ScopedEndpoint(Scope::TransitionGeneric, granular: 'rpc:com.atproto.repo.getRecord')] 127 public function get(string $rkey, ?string $cid = null): Record 128 { 129 $response = $this->atp->atproto->repo->getRecord( 130 repo: $this->atp->client->session()->did(), 131 collection: BskyFeed::Post, 132 rkey: $rkey, 133 cid: $cid 134 ); 135 136 return Record::fromArrayRaw($response->toArray()); 137 } 138 139}