Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/mrmartineau/Otter
Otter is a self-hosted bookmark manager made with Next.js and Supabase with Mastodon integration.
https://github.com/mrmartineau/Otter
reactjs supabase-auth supabase-db supabase-js typescript
Last synced: about 1 month ago
JSON representation
Otter is a self-hosted bookmark manager made with Next.js and Supabase with Mastodon integration.
- Host: GitHub
- URL: https://github.com/mrmartineau/Otter
- Owner: mrmartineau
- Created: 2023-09-26T18:34:50.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2024-10-21T06:56:45.000Z (about 2 months ago)
- Last Synced: 2024-10-30T03:48:12.694Z (about 1 month ago)
- Topics: reactjs, supabase-auth, supabase-db, supabase-js, typescript
- Language: TypeScript
- Homepage: https://otter.zander.wtf
- Size: 5.46 MB
- Stars: 133
- Watchers: 3
- Forks: 21
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
- my-awesome-list - Otter - hosted bookmark manager made with Next.js and Supabase with Mastodon integration. | mrmartineau | 147 | (TypeScript)
README
Otter> Otter is a self-hosted bookmark manager made with [Next.js](https://nextjs.org) and [Supabase](https://supabase.com) with Mastodon integration.
Features •
Getting started •
Docs •
Ecosystem
## Features
- Private bookmarking app with search, tagging and filtering
- Dark/light colour modes
- Mastodon integration - backup of your own toots as well as your favourite toots
- Raycast extension to search your bookmarks, view recent bookmarks and create new ones
- Chrome extension for easy bookmarking
- Bookmarklet### Screenshots
| Feed (dark mode)
| Feed (light mode)
|
| ------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------ |
| New bookmark
| Search
|
| Feed (showing tags sidebar)
| Toots feed
|## Getting started
### Prerequisites
- [pnpm](https://pnpm.io) - install with `npm i -g pnpm`
- [Vercel](https://vercel.com) account and the [Vercel CLI](https://vercel.com/cli) - install with `npm i -g vercel`
- [Supabase](https://supabase.com) account and the [Supabase CLI](https://supabase.com/docs/reference/cli/introduction) - install with `npm i -g supabase`
- [Cloudflare](https://cloudflare.com) account (optional) - used for the page scraper and Mastodon to Supabase worker### Setup
1. Fork this repo
2. Go to [database.new](https://database.new) and create a new [Supabase](https://supabase.com) project. You will need the project ID (found in the project settings page) and the the database password for the next step.
3. Link your Supabase project to your local dev environment: `pnpm supabase:link`
4. Seed your database with `pnpm supabase:setup`
5. Install npm dependencies with [pnpm](https://pnpm.io): `pnpm install`
6. Create a new project on vercel and setup env vars (see below)
7. To allow signups, set the value of `ALLOW_SIGNUP` in `./src/constants.ts` to `true`
8. Run the app locally using `pnpm dev`
9. Visit [`http://localhost:5678`](http://localhost:5678) and create an account### Env vars
Set up the following env vars using either the Vercel CLI or through the Vercel project settings. Once they are added run `vc env pull` to pull them down to your local dev environment.
```bash
# Find these in your Supabase project settings > API
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
SUPABASE_SERVICE_KEY=your-service-key # only needed for testing APIs using the `*.rest` filesPERSONAL_MASTODON_ACCESS_TOKEN=your-personal-app-mastodon-access-token
BOT_MASTODON_ACCESS_TOKEN=your-bot-app-mastodon-access-token
OTTER_API_TOKEN=your-otter-api-token
```### Docs
### API Endpoints
Interactive API docs can be found in the various `*.rest` files in the `/app/api` directory.
- `POST /api/new` - create new item in Otter
- `GET /api/new?url=https://example.com` - quick create new item in Otter. Pass in a `url` query param and it will create a new item with that URL and includes its metadata too
- `GET /api/bookmarks` - returns all bookmarks- `GET /api/search?searchTerm=zander` - search bookmark
- `POST /api/toot` - A PostgreSQL trigger function calls this endpoint anytime a bookmark is created or edited which then creates a new toot on two of my Mastodon accounts ([@[email protected]](https://botsin.space/@otterbot) & [@[email protected]](https://toot.cafe/@zander)). It only sends a toot if the bookmark has the `public` column set to `true`.### Mastodon integration
Otter has the ability to auto-toot to 2 Mastodon accounts when a new bookmark is created or edited. This is done via a PostgreSQL trigger function that calls the `/api/toot` endpoint.
The trigger function below uses an environment variable in the `Authorization` header to ensure only the owner of the Otter instance can call the endpoint.
```sql
create trigger "toot-otter-items"
after insert
or
update on bookmarks for each row
execute function supabase_functions.http_request (
'https://{your-otter-instance}/api/toot',
'POST',
-- replace {OTTER_API_TOKEN} with your own token
'{"Content-type":"application/json","Authorization":"{OTTER_API_TOKEN}"}',
'{}',
'1000'
);
```TODO:
- [ ] document the PostgreSQL trigger function that calls the `/api/toot` endpoint
### Bookmarks
#### Adding new bookmark types
1. Add the new type to the types enum `ALTER TYPE type ADD VALUE '???';`
2. Run `pnpm run supabase:types` to update the TypeScript types
3. Add a new `case` to the `TypeToIcon` component
4. Add a new `TypeRadio` component to the `BookmarkForm` component## Otter ecosystem
I use various other tools to make Otter even better:
- [Raycast extension](https://www.raycast.com/mrmartineau/otter) (on the Raycast extension store)
- [Chrome extension](https://github.com/mrmartineau/otter-extension) (not currently on the Chrome webstore)
- [Apple Shortcut](https://github.com/mrmartineau/Otter/blob/main/public/Add%20to%20Otter.shortcut) - download this shortcut and update your Otter instance URL within it. Then you can add it to your iOS share sheet and quickly add new bookmarks to Otter
- [Page scraper Cloudflare worker](https://github.com/mrmartineau/cloudflare-worker-scraper) used to scrape the metadata of a URL. This is used when adding new bookmarks to Otter
- [Mastodon to Supabase Cloudflare worker](https://github.com/mrmartineau/mastodon-to-supabase) used to backup my Mastodon toots to Supabase## License
[MIT](https://choosealicense.com/licenses/mit/) © [Zander Martineau](https://zander.wtf)
> Made by Zander • [zander.wtf](https://zander.wtf) • [GitHub](https://github.com/mrmartineau/) • [Mastodon](https://main.elk.zone/toot.cafe/@zander)