An open API service indexing awesome lists of open source software.

https://github.com/amake/org_social_mastodon_bridge

A tool for mirroring an Org Social feed to Mastodon
https://github.com/amake/org_social_mastodon_bridge

Last synced: about 1 month ago
JSON representation

A tool for mirroring an Org Social feed to Mastodon

Awesome Lists containing this project

README

          

# org_social_mastodon_bridge

Sync an [Org Social](https://org-social.org/) feed to a Mastodon account.

This project provides a CLI tool `osmb` to:

- fetch and parse `social.org` feeds
- lint and preview posts against Mastodon character limits
- sync posts to Mastodon with idempotency and state management
- support local authoring with local `.org` file inputs

It also supports scheduled execution via AWS Lambda.

## Installation

```sh
dart pub global activate --source path .
```

(Note: Once published, you will be able to run `dart pub global activate org_social_mastodon_bridge`)

## CLI Usage

The `osmb` CLI is the primary way to interact with the bridge.

### `osmb init`

Interactive setup to bootstrap your configuration.

```sh
osmb init
```

This will prompt for your Mastodon instance and default feed URL, then create a configuration file at `~/.org_social_mastodon_bridge/config.json`.

### `osmb auth`

Perform or refresh Mastodon OAuth authorization.

```sh
osmb auth
```

This registers an application on your instance (if needed) and guides you through the OAuth flow to obtain an access token.

### `osmb lint [SOURCE]`

Check a source for errors or Mastodon limit violations. `SOURCE` can be a local file path or a URL.

```sh
osmb lint my_posts.org
```

### `osmb preview [SOURCE]`

Render posts as they would be sent to Mastodon, showing character counts and publication modes.

```sh
osmb preview my_posts.org
```

### `osmb sync`

Perform a synchronization pass using the configured source.

```sh
osmb sync
osmb sync --dry-run
```

## Config

By default, `osmb` looks for configuration at `~/.org_social_mastodon_bridge/config.json`. You can override this with the `-c` or `--config` flag, or by setting the `ORG_SOCIAL_MASTODON_BRIDGE_CONFIG` environment variable.

The configuration file contains:

- `source.feed_url`: URL of the Org Social feed to mirror
- `mastodon.base_url`: Base URL of the target instance
- `mastodon.access_token`: Posting token for the target account
- `sync.dry_run`: Safety switch to prevent actual posting
- `sync.include_source_link`: Whether to append a link to the original post
- `state`: Configuration for the state store (local file or S3)

### Manual Limit Overrides

For offline linting or specific instance needs, you can override Mastodon limits in `config.json`:

```json
"mastodon": {
"max_characters": 500,
"characters_reserved_per_url": 23,
"max_media_attachments": 4
}
```

## Common Development Commands

These commands use `make` and typically target a local `config.json` in the repository root.

- `make deps`: Install dependencies
- `make generate`: Generate the Mastodon OpenAPI client
- `make test`: Run tests
- `make analyze`: Run static analysis
- `make sync`: Run one sync pass (uses `osmb sync`)
- `make preview`: Preview configured source (uses `osmb preview`)
- `make provision`: Transition to Lambda: push state to S3 and config to environment variables
- `make build`: Build the Lambda ZIP payload
- `make deploy`: Update the Lambda function code

## Logging

Logs are written to stderr.

Supported log levels:

- `debug`
- `info`
- `warning`
- `error`

Set the level with `ORG_SOCIAL_MASTODON_BRIDGE_LOG_LEVEL`. If that is unset,
the code also falls back to `LOG_LEVEL`. The default is `info`.

Examples:

- `ORG_SOCIAL_MASTODON_BRIDGE_LOG_LEVEL=debug dart run bin/org_social_mastodon_bridge.dart`
- `make run`
- `make run run_log_level=info`

## State And Idempotency

Each mirrored source post is recorded by source ID in the state store together
with the created Mastodon status ID. The bridge also sends the source ID as the
Mastodon `Idempotency-Key` header, which reduces duplicate posts if a run fails
midway and is retried quickly.

Current state files are expected to contain `content_hash`,
`rendered_hash`, and `selected_media` for each record. State generated by the
current code will include those fields automatically; manually edited or stale
state files that omit them are no longer supported.

## AWS Notes

The Lambda deployment target is a ZIP package for the AWS OS-only runtime
`provided.al2023`, using a root-level `bootstrap`.

`make build` compiles `bin/bootstrap.dart` to a Linux executable and zips it as
`dist/lambda.zip`. `make deploy` updates the configured Lambda function using
the function name from `config.json`.

Requirements for deployment tooling:

- Dart SDK with cross-compilation artifacts available
- `aws` CLI
- `jq`

The trickiest gotcha is that if you provision the state file with `make
provision` it will be private, so you will need to ensure that the Lambda
executor role has appropriate permissions like:

```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::$MY_BUCKET/path/to/state.json"
}
]
}
```

## License

MIT