A community based topic aggregation platform built on atproto
at main 297 lines 9.5 kB view raw view rendered
1# Aggregator Setup Scripts 2 3This directory contains scripts to help you set up and register your aggregator with Coves instances. 4 5## Overview 6 7Aggregators are automated services that post content to Coves communities. They are similar to Bluesky's feed generators and labelers. To use aggregators with Coves, you need to: 8 91. Create a PDS account for your aggregator (gets you a DID) 102. **(Optional)** Verify a custom domain via `.well-known/atproto-did` 113. Register with a Coves instance 124. Create a service declaration record 135. **Generate an API key** for authentication 14 15These scripts automate this process for you. 16 17### Handle Options 18 19You have two choices for your aggregator's handle: 20 211. **PDS-assigned handle** (simpler): Use the handle from your PDS, e.g., `my-aggregator.bsky.social`. No domain verification needed—skip steps 2-3. 22 232. **Custom domain handle** (branded): Use your own domain, e.g., `news.example.com`. Requires hosting a `.well-known/atproto-did` file on your domain. 24 25## Prerequisites 26 27- **Tools**: `curl`, `jq` (for JSON processing) 28- **Account**: Email address for creating the PDS account 29- **(For custom domain only)**: Domain ownership and ability to serve HTTPS files 30 31## Quick Start 32 33### Interactive Setup (Recommended) 34 35Run the scripts in order: 36 37```bash 38# Make scripts executable 39chmod +x *.sh 40 41# Step 1: Create PDS account 42./1-create-pds-account.sh 43 44# Steps 2-3: OPTIONAL - Only if you want a custom domain handle 45# ./2-setup-wellknown.sh 46# ./3-register-with-coves.sh (after uploading .well-known) 47 48# Step 4: Create service declaration 49./4-create-service-declaration.sh 50 51# Step 5: Generate API key (requires browser for OAuth) 52./5-create-api-key.sh 53``` 54 55**Minimal setup** (PDS handle only): Steps 1, 4, 5 56**Custom domain**: Steps 1, 2, 3, 4, 5 57 58### Automated Setup Example 59 60For a reference implementation of automated setup, see the Kagi News aggregator at [aggregators/kagi-news/scripts/setup.sh](../../aggregators/kagi-news/scripts/setup.sh). 61 62The Kagi script shows how to automate all 4 steps (with the manual .well-known upload step in between). 63 64## Script Reference 65 66### 1-create-pds-account.sh 67 68**Purpose**: Creates a PDS account for your aggregator 69 70**Prompts for**: 71- PDS URL (default: https://bsky.social) 72- Handle (e.g., mynewsbot.bsky.social) 73- Email 74- Password 75 76**Outputs**: 77- `aggregator-config.env` - Configuration file with DID and credentials 78- Prints your DID and access tokens 79 80**Notes**: 81- Keep the config file secure! It contains your credentials 82- The PDS automatically generates a DID:PLC for you 83- You can use any PDS service, not just bsky.social 84 85### 2-setup-wellknown.sh 86 87**Purpose**: Generates the `.well-known/atproto-did` file for domain verification 88 89**Prompts for**: 90- Your domain (e.g., rss-bot.example.com) 91 92**Outputs**: 93- `.well-known/atproto-did` - File containing your DID 94- `nginx-example.conf` - Example nginx configuration 95- `apache-example.conf` - Example Apache configuration 96 97**Manual step required**: 98Upload the `.well-known` directory to your web server. The file must be accessible at: 99``` 100https://yourdomain.com/.well-known/atproto-did 101``` 102 103**Verify it works**: 104```bash 105curl https://yourdomain.com/.well-known/atproto-did 106# Should return your DID (e.g., did:plc:abc123...) 107``` 108 109### 3-register-with-coves.sh 110 111**Purpose**: Registers your aggregator with a Coves instance 112 113**Prompts for**: 114- Coves instance URL (default: https://api.coves.social) 115 116**Prerequisites**: 117- `.well-known/atproto-did` must be accessible from your domain 118- Scripts 1 and 2 must be completed 119 120**What it does**: 1211. Verifies your `.well-known/atproto-did` is accessible 1222. Calls `social.coves.aggregator.register` XRPC endpoint 1233. Coves verifies domain ownership 1244. Inserts your aggregator into the `users` table 125 126**Outputs**: 127- Updates `aggregator-config.env` with Coves instance URL 128- Prints registration confirmation 129 130### 4-create-service-declaration.sh 131 132**Purpose**: Creates the service declaration record in your repository 133 134**Prompts for**: 135- Display name (e.g., "RSS News Aggregator") 136- Description 137- Source URL (GitHub repo, etc.) 138- Maintainer DID (optional) 139 140**What it does**: 1411. Creates a `social.coves.aggregator.service` record at `at://your-did/social.coves.aggregator.service/self` 1422. Jetstream consumer will index this into the `aggregators` table 1433. Communities can now discover and authorize your aggregator 144 145**Outputs**: 146- Updates `aggregator-config.env` with record URI and CID 147- Prints record details 148 149### 5-create-api-key.sh 150 151**Purpose**: Generates an API key for aggregator authentication 152 153**Prerequisites**: 154- Steps 1-4 completed 155- Aggregator indexed by Coves (usually takes a few seconds after step 4) 156- Web browser for OAuth login 157 158**What it does**: 1591. Guides you through OAuth login in your browser 1602. Provides the JavaScript to call the `createApiKey` endpoint 1613. Validates the API key format 1624. Saves the key to your config file 163 164**Outputs**: 165- Updates `aggregator-config.env` with `COVES_API_KEY` 166- Provides instructions for updating your `.env` file 167 168**Important Notes**: 169- The API key is shown **ONCE** and cannot be retrieved later 170- API keys replace password-based authentication 171- Keys can be revoked and regenerated at any time 172- Store securely - never commit to version control 173 174## Configuration File 175 176After running all scripts, you'll have an `aggregator-config.env` file with: 177 178```bash 179# Identity 180AGGREGATOR_DID="did:plc:..." 181AGGREGATOR_HANDLE="mynewsbot.example.com" 182AGGREGATOR_PDS_URL="https://bsky.social" 183AGGREGATOR_DOMAIN="mynewsbot.example.com" 184 185# Coves Instance 186COVES_INSTANCE_URL="https://coves.social" 187SERVICE_DECLARATION_URI="at://did:plc:.../social.coves.aggregator.service/self" 188SERVICE_DECLARATION_CID="..." 189 190# API Key (from Step 5) 191COVES_API_KEY="ckapi_..." 192``` 193 194**For your aggregator's `.env` file, you only need:** 195 196```bash 197COVES_API_KEY=ckapi_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 198COVES_API_URL=https://coves.social 199``` 200 201## What Happens Next? 202 203After completing all 5 steps: 204 2051. **Your aggregator is registered** in the Coves instance's `users` table 2062. **Your service declaration is indexed** in the `aggregators` table (takes a few seconds) 2073. **Your API key is stored** and can be used for authentication 2084. **Community moderators can authorize** your aggregator for their communities 2095. **Your aggregator can post** to authorized communities (or all if you're a trusted aggregator) 210 211## Creating an Authorization 212 213Authorizations are created by community moderators, not by aggregators. The moderator writes a `social.coves.aggregator.authorization` record to their community's repository. 214 215See `docs/aggregators/SETUP_GUIDE.md` for more information on the authorization process. 216 217## Posting to Communities 218 219Once authorized, your aggregator can post using your API key: 220 221```bash 222curl -X POST https://coves.social/xrpc/social.coves.community.post.create \ 223 -H "Authorization: Bearer $COVES_API_KEY" \ 224 -H "Content-Type: application/json" \ 225 -d '{ 226 "community": "c-worldnews.coves.social", 227 "content": "Your post content", 228 "facets": [] 229 }' 230``` 231 232The API key handles all authentication - no OAuth token refresh needed. 233 234## Troubleshooting 235 236### Error: "DomainVerificationFailed" 237 238- Verify `.well-known/atproto-did` is accessible: `curl https://yourdomain.com/.well-known/atproto-did` 239- Check the content matches your DID exactly (no extra whitespace) 240- Ensure HTTPS is working (not HTTP) 241- Check CORS headers if accessing from browser 242 243### Error: "AlreadyRegistered" 244 245- You've already registered this DID with this Coves instance 246- This is safe to ignore if you're re-running the setup 247 248### Error: "DIDResolutionFailed" 249 250- Your DID might be invalid or not found in the PLC directory 251- Verify your DID exists: `curl https://plc.directory/<your-did>` 252- Wait a few seconds and try again (PLC directory might be propagating) 253 254### Service declaration not appearing 255 256- Wait 5-10 seconds for Jetstream consumer to index it 257- Check the Jetstream logs for errors 258- Verify the record was created: Check your PDS at `at://your-did/social.coves.aggregator.service/self` 259 260## Example: Kagi News Aggregator 261 262For a complete reference implementation, see the Kagi News aggregator at `aggregators/kagi-news/`. 263 264The Kagi aggregator includes an automated setup script at [aggregators/kagi-news/scripts/setup.sh](../../aggregators/kagi-news/scripts/setup.sh) that demonstrates how to: 265 266- Automate the entire registration process 267- Use environment variables for configuration 268- Handle errors gracefully 269- Integrate the setup into your aggregator project 270 271This shows how you can package scripts 1-4 into a single automated flow for your specific aggregator. 272 273## Security Notes 274 275- **Never commit `aggregator-config.env`** to version control 276- Store credentials securely (use environment variables or secret management) 277- Rotate access tokens regularly 278- Use HTTPS for all API calls 279- Validate community authorization before posting 280 281## More Information 282 283- [Aggregator Setup Guide](../../docs/aggregators/SETUP_GUIDE.md) 284- [Aggregator PRD](../../docs/aggregators/PRD_AGGREGATORS.md) 285- [atProto Identity Guide](../../ATPROTO_GUIDE.md) 286- [Coves Communities PRD](../../docs/PRD_COMMUNITIES.md) 287 288## Support 289 290If you encounter issues: 291 2921. Check the troubleshooting section above 2932. Review the full documentation in `docs/aggregators/` 2943. Open an issue on GitHub with: 295 - Which script failed 296 - Error message 297 - Your domain (without credentials)