The 1st decentralized social network for sharing when you're on the toilet. Post a "flush" today! Powered by the AT Protocol.
at main 165 lines 5.0 kB view raw
1import { OAuthSession } from '@atproto/oauth-client-browser'; 2import { Agent } from '@atproto/api'; 3 4// API client for OAuth session using @atproto/api Agent 5 6// Create a post using the OAuth session with @atproto/api Agent 7export async function createPost(session: OAuthSession, options: { 8 text: string; 9 reply?: { 10 root: { uri: string; cid: string }; 11 parent: { uri: string; cid: string }; 12 }; 13 embed?: any; 14 langs?: string[]; 15 createdAt?: string; 16}) { 17 // Ensure we're on the client side 18 if (typeof window === 'undefined') { 19 throw new Error('API client can only be used on the client side'); 20 } 21 22 try { 23 console.log('Creating post with session:', session.sub); 24 console.log('Post text:', options.text); 25 26 // Create an Agent instance using the OAuth session 27 const agent = new Agent(session); 28 29 // Extract emoji from text if present, default to toilet 30 let emoji = '🚽'; 31 let cleanText = options.text; 32 33 // Simple emoji extraction - look for common toilet/bathroom emojis 34 const toiletEmojis = ['🚽', '🧻', '💩', '💨', '🚾', '🧼', '🪠', '🚻', '🩸', '💧', '💦', '😌', 35 '😣', '🤢', '🤮', '🥴', '😮‍💨', '😳', '😵', '🌾', '🍦', '📱', '📖', '💭', 36 '1️⃣', '2️⃣', '🟡', '🟤']; 37 38 // Sort emojis by length (longest first) to handle compound emojis correctly 39 const sortedEmojis = [...toiletEmojis].sort((a, b) => b.length - a.length); 40 41 // Look for any of these emojis in the text 42 for (const testEmoji of sortedEmojis) { 43 if (options.text.includes(testEmoji)) { 44 emoji = testEmoji; 45 cleanText = options.text.replace(testEmoji, '').trim(); 46 break; 47 } 48 } 49 50 // Create a record directly using the Agent, following the cred.blue pattern 51 const flushRecord = { 52 $type: 'im.flushing.right.now', 53 text: cleanText, 54 emoji: emoji, 55 createdAt: new Date().toISOString(), 56 }; 57 58 console.log('Creating flush record:', flushRecord); 59 60 // Use the agent to create the record directly in the user's PDS 61 const result = await agent.api.com.atproto.repo.createRecord({ 62 repo: session.sub, // Use the user's DID 63 collection: 'im.flushing.right.now', 64 record: flushRecord, 65 }); 66 67 console.log('Post created successfully:', result); 68 return result; 69 } catch (error) { 70 console.error('Failed to create post:', error); 71 throw error; 72 } 73} 74 75// Delete a flush record 76export async function deleteFlushRecord(session: OAuthSession, recordUri: string) { 77 if (typeof window === 'undefined') { 78 throw new Error('API client can only be used on the client side'); 79 } 80 81 try { 82 console.log('Deleting flush record:', recordUri); 83 84 // Create an Agent instance using the OAuth session 85 const agent = new Agent(session); 86 87 // Parse the AT URI to extract repo, collection, and rkey 88 // Format: at://did:plc:xxx/collection.name/rkey 89 const uriParts = recordUri.replace('at://', '').split('/'); 90 if (uriParts.length !== 3) { 91 throw new Error('Invalid record URI format'); 92 } 93 94 const [repo, collection, rkey] = uriParts; 95 96 console.log('Deleting record:', { repo, collection, rkey }); 97 98 // Delete the record 99 const result = await agent.api.com.atproto.repo.deleteRecord({ 100 repo, 101 collection, 102 rkey 103 }); 104 105 console.log('Record deleted successfully'); 106 return result; 107 } catch (error) { 108 console.error('Failed to delete record:', error); 109 throw error; 110 } 111} 112 113// Update a flush record using putRecord 114export async function updateFlushRecord( 115 session: OAuthSession, 116 recordUri: string, 117 text: string, 118 emoji: string, 119 originalCreatedAt?: string 120) { 121 if (typeof window === 'undefined') { 122 throw new Error('API client can only be used on the client side'); 123 } 124 125 try { 126 console.log('Updating flush record:', recordUri); 127 128 // Create an Agent instance using the OAuth session 129 const agent = new Agent(session); 130 131 // Parse the AT URI 132 const uriParts = recordUri.replace('at://', '').split('/'); 133 if (uriParts.length !== 3) { 134 throw new Error('Invalid record URI format'); 135 } 136 137 const [repo, collection, rkey] = uriParts; 138 139 console.log('Updating record:', { repo, collection, rkey }); 140 141 // Create the updated record 142 const updatedRecord = { 143 $type: 'im.flushing.right.now', 144 text, 145 emoji, 146 createdAt: originalCreatedAt || new Date().toISOString(), 147 }; 148 149 console.log('Updated record data:', updatedRecord); 150 151 // Update the record using putRecord 152 const result = await agent.api.com.atproto.repo.putRecord({ 153 repo, 154 collection, 155 rkey, 156 record: updatedRecord 157 }); 158 159 console.log('Record updated successfully'); 160 return result; 161 } catch (error) { 162 console.error('Failed to update record:', error); 163 throw error; 164 } 165}