forked from
atpota.to/flushes.app
The 1st decentralized social network for sharing when you're on the toilet. Post a "flush" today! Powered by the AT Protocol.
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}