PHPackages                             fof/open-collective - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. fof/open-collective

ActiveFlarum-extension[Utility &amp; Helpers](/categories/utility)

fof/open-collective
===================

Open Collective integration for your Flarum forum

1.2.0(4mo ago)31.4k2[2 PRs](https://github.com/FriendsOfFlarum/open-collective/pulls)1MITPHPCI failing

Since Jun 12Pushed 3mo ago1 watchersCompare

[ Source](https://github.com/FriendsOfFlarum/open-collective)[ Packagist](https://packagist.org/packages/fof/open-collective)[ Docs](https://friendsofflarum.org)[ Fund](https://opencollective.com/fof/donate)[ RSS](/packages/fof-open-collective/feed)WikiDiscussions 2.x Synced 1mo ago

READMEChangelog (8)Dependencies (4)Versions (15)Used By (1)

Open Collective by FriendsOfFlarum
==================================

[](#open-collective-by-friendsofflarum)

[![License](https://camo.githubusercontent.com/7013272bd27ece47364536a221edb554cd69683b68a46fc0ee96881174c4214c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667)](https://camo.githubusercontent.com/7013272bd27ece47364536a221edb554cd69683b68a46fc0ee96881174c4214c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667) [![Latest Stable Version](https://camo.githubusercontent.com/72dbaaf3e618e26bb890b0ab5083bde93ce59b1eaaba15572ec9797f380e497b/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f666f662f6f70656e2d636f6c6c6563746976652e737667)](https://packagist.org/packages/fof/open-collective) [![OpenCollective](https://camo.githubusercontent.com/1903c197bb0307e60d6328653532b8a6b9890b898fbc92e314ab39d699491e74/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6f70656e636f6c6c6563746976652d666f662d626c75652e737667)](https://opencollective.com/fof/donate) [![Donate](https://camo.githubusercontent.com/6c7b26396e320eb8dd60d767a4500684b60bb7d37f7cacbaf6b2eae6f2d30010/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646f6e6174652d6461746974697365762d696d706f7274616e742e737667)](https://datitisev.me/donate)

A [Flarum](http://flarum.org) extension that automatically synchronizes your Open Collective backers with Flarum user groups.

Features
--------

[](#features)

- 🔄 **Automatic Synchronization**: Hourly checks for new and removed backers
- 👥 **Smart User Matching**: Matches backers via email addresses
- 🎯 **Dual Group Support**: Separate groups for recurring and one-time backers
- 🔄 **Status-Based Categorization**: Automatically moves past recurring backers to one-time group
- 🔒 **Safe Group Management**: Only manages users it adds, won't interfere with manually assigned groups
- 📝 **Detailed Logging**: Tracks all changes in dedicated log files
- 🧪 **Dry-Run Mode**: Preview changes before applying them
- 📊 **Verbose Output**: Detailed information about the synchronization process

How It Works
------------

[](#how-it-works)

This extension connects your Open Collective account with your Flarum forum by:

1. **Fetching Backers**: Queries Open Collective's GraphQL API to retrieve your current backers (active recurring, cancelled recurring, and one-time contributors)
2. **Categorizing Backers**: Separates backers into two groups:
    - **Recurring backers**: Users with active monthly or yearly subscriptions
    - **One-time backers**: Users who made one-time contributions or whose recurring subscription has ended
3. **Matching Users**: Identifies Flarum users by matching email addresses from Open Collective backers with Flarum user emails
4. **Managing Groups**: Automatically adds backers to designated Flarum groups and removes users who are no longer backers
5. **Handling Transitions**: When a recurring backer's subscription ends, they are automatically moved to the one-time backers group
6. **Tracking Changes**: Logs all additions, removals, and transitions to help you monitor the process

Installation
------------

[](#installation)

Install with composer:

```
composer require fof/open-collective:"*"
php flarum migrate
php flarum cache:clear
```

### Required: Flarum Scheduler

[](#required-flarum-scheduler)

This extension requires [Flarum's scheduler](https://docs.flarum.org/scheduler/) to be set up and running. The extension will automatically check for backer updates every hour.

Add this cron job to your server:

```
* * * * * cd /path-to-your-project && php flarum schedule:run >> /dev/null 2>&1

```

Configuration
-------------

[](#configuration)

After installation, configure the extension in your Flarum admin panel:

### 1. Create an Open Collective Personal Token

[](#1-create-an-open-collective-personal-token)

1. Go to [Open Collective Applications](https://opencollective.com/applications)
2. Create a new Personal Token
3. Copy the token (you won't be able to see it again)

**Legacy API Keys**: If you have an existing legacy API key, you can continue using it by enabling "Use Legacy Application API Key" in the settings. However, it's recommended to migrate to a Personal Token.

### 2. Configure the Extension

[](#2-configure-the-extension)

In your Flarum admin panel, navigate to the Open Collective extension settings:

- **Personal Token** (or **API Key** if using legacy): Paste your Open Collective token
- **Collective Slug**: Enter your collective slug (e.g., if your collective is at `opencollective.com/your-collective`, enter `your-collective`)
- **Recurring Backers Group**: Select which Flarum group to assign to recurring backers (required)
- **One-Time Backers Group**: Optionally select a group for one-time backers and past recurring backers (optional)

**Note**: If you only configure the recurring backers group, all backers (both recurring and one-time) will be added to that single group. If you configure both groups, the extension will automatically categorize backers based on their subscription status.

Save the settings, and the extension will start syncing on the next scheduled run.

Usage
-----

[](#usage)

Once configured, the extension runs automatically every hour. You can also manually trigger an update:

```
php flarum fof:open-collective:update
```

### Command Options

[](#command-options)

#### Dry-Run Mode

[](#dry-run-mode)

Preview what changes would be made without actually applying them:

```
php flarum fof:open-collective:update --dry-run
```

This is useful for testing your configuration before letting the extension make real changes to your groups.

#### Verbose Output

[](#verbose-output)

Get detailed information about the synchronization process:

```
php flarum fof:open-collective:update -v
```

Verbose mode shows:

- Configuration details (API type, collective slug, target groups)
- Total number of backers and breakdown by type (recurring vs one-time)
- All backers from Open Collective with their emails and type
- Matched Flarum users for each group
- Unmatched backers who couldn't be linked to Flarum accounts
- Summary of users staying, being added, removed, and moved between groups

Combine both options for detailed preview:

```
php flarum fof:open-collective:update --dry-run -v
```

### Viewing Logs

[](#viewing-logs)

Check the synchronization logs:

```
tail -f storage/logs/fof-open-collective.log
```

Log output includes:

- Number of backers found on Open Collective
- Number of backers matched to Flarum users
- Users added to the group (with `+ #userID username`)
- Users removed from the group (with `- #userID username`)
- Any API errors or configuration issues

How User Matching Works
-----------------------

[](#how-user-matching-works)

The extension matches Open Collective backers to Flarum users by comparing email addresses. For a backer to be matched:

- The backer must have a public email address on their Open Collective profile
- A Flarum user must exist with that same email address
- The Flarum user's email must be confirmed

Important Notes
---------------

[](#important-notes)

- **Safe Group Management**: The extension only removes the group from users it previously added. It won't affect users who were manually added to the group.
- **Email Matching**: Users must have the same email address as their Open Collective account.
- **Backer Categorization**:
    - Users with active monthly or yearly subscriptions are placed in the recurring backers group
    - Users who made one-time contributions or whose subscription has ended are placed in the one-time backers group
    - When a recurring subscription ends, the user is automatically moved to the one-time group (if configured)
- **Rate Limits**: The Open Collective API has rate limits. The extension checks once per hour to stay well within these limits.
- **Email Privacy**: Some backers may have private email addresses on Open Collective. These backers cannot be matched to Flarum users automatically.

For Developers: Event System
----------------------------

[](#for-developers-event-system)

This extension dispatches events when backers are added or removed, allowing other extensions to react to these changes.

### Available Events

[](#available-events)

#### `FoF\OpenCollective\Event\BackerAdded`

[](#fofopencollectiveeventbackeradded)

Dispatched when a user is added to the backers group.

**Properties:**

- `$user` (Flarum\\User\\User) - The Flarum user who was added
- `$backerData` (object|null) - Open Collective backer data including:
    - `email` - Backer's email address
    - Other fields from the Open Collective API

**Example listener:**

```
use Flarum\Extend;
use FoF\OpenCollective\Event\BackerAdded;

return [
    (new Extend\Event)
        ->listen(BackerAdded::class, function (BackerAdded $event) {
            $user = $event->user;
            $email = $event->backerData->email ?? null;

            // Your custom logic here
            // e.g., send a welcome email, grant additional permissions, etc.
        }),
];
```

#### `FoF\OpenCollective\Event\BackerRemoved`

[](#fofopencollectiveeventbackerremoved)

Dispatched when a user is removed from the backers group (backing ended).

**Properties:**

- `$user` (Flarum\\User\\User) - The Flarum user who was removed

**Example listener:**

```
use Flarum\Extend;
use FoF\OpenCollective\Event\BackerRemoved;

return [
    (new Extend\Event)
        ->listen(BackerRemoved::class, function (BackerRemoved $event) {
            $user = $event->user;

            // Your custom logic here
            // e.g., send a thank you message, revoke special access, etc.
        }),
];
```

### Notes on Events

[](#notes-on-events)

- Events are **not dispatched** when running with the `--dry-run` flag
- Events fire after the database changes have been made
- The `BackerAdded` event includes raw Open Collective data for additional context
- These events only fire for automated changes, not manual group assignments

Troubleshooting
---------------

[](#troubleshooting)

### No backers are being synced

[](#no-backers-are-being-synced)

- Verify your token is correct and has proper permissions
- Check that the collective slug matches your Open Collective account exactly
- Ensure the cron job is running (`schedule:run`)
- Check logs in `storage/logs/fof-open-collective.log`

### Some backers aren't being matched

[](#some-backers-arent-being-matched)

- Ensure backers have public email addresses on their Open Collective profiles
- Verify that corresponding Flarum users exist with the same email addresses
- Check that Flarum user emails are confirmed

### Authentication errors

[](#authentication-errors)

- If using a Personal Token, ensure it was created correctly
- If using a legacy API Key, consider migrating to a Personal Token
- Check that the token hasn't expired or been revoked

Updating
--------

[](#updating)

```
composer update fof/open-collective
php flarum migrate
php flarum cache:clear
```

Links
-----

[](#links)

[![OpenCollective](https://camo.githubusercontent.com/8ea53c451470d1a72789d650c77e2b22eee915f7fbf2cbeeeeaa25f47301efe2/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646f6e6174652d667269656e64736f66666c6172756d2d3434414545353f7374796c653d666f722d7468652d6261646765266c6f676f3d6f70656e2d636f6c6c656374697665)](https://opencollective.com/fof/donate) [![GitHub](https://camo.githubusercontent.com/19562cc0996a556a7abda08327f57924e288bbbc3c5312b096c62175a2841ae4/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646f6e6174652d6461746974697365762d6561346161613f7374796c653d666f722d7468652d6261646765266c6f676f3d676974687562)](https://datitisev.me/donate/github)

- [Packagist](https://packagist.org/packages/fof/open-collective)
- [GitHub](https://github.com/FriendsOfFlarum/open-collective)
- [Discuss](https://discuss.flarum.org/d/22256)

An extension by [FriendsOfFlarum](https://github.com/FriendsOfFlarum).

###  Health Score

50

—

FairBetter than 96% of packages

Maintenance79

Regular maintenance activity

Popularity24

Limited adoption so far

Community22

Small or concentrated contributor base

Maturity67

Established project with proven stability

 Bus Factor2

2 contributors hold 50%+ of commits

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~203 days

Recently: every ~126 days

Total

13

Last Release

90d ago

Major Versions

0.3.0 → 1.0.02021-06-05

1.2.0 → 2.0.0-beta.12025-12-24

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/16573496?v=4)[IanM](/maintainers/imorland)[@imorland](https://github.com/imorland)

![](https://avatars.githubusercontent.com/u/1630413?v=4)[Gregor Hammerschmidt](/maintainers/GreXXL)[@GreXXL](https://github.com/GreXXL)

![](https://www.gravatar.com/avatar/0538135c1debcef5602dce7ece027909cc832b7a6284ab9189a19aa8de98d60d?d=identicon)[clarkwinkelmann](/maintainers/clarkwinkelmann)

![](https://www.gravatar.com/avatar/1298cdc0b2402a1aa34fb75a254947d655e090d62bd0531311331d369cac934e?d=identicon)[datitisev](/maintainers/datitisev)

---

Top Contributors

[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (11 commits)")[![flarum-bot](https://avatars.githubusercontent.com/u/39334649?v=4)](https://github.com/flarum-bot "flarum-bot (9 commits)")[![imorland](https://avatars.githubusercontent.com/u/16573496?v=4)](https://github.com/imorland "imorland (8 commits)")[![dsevillamartin](https://avatars.githubusercontent.com/u/6401250?v=4)](https://github.com/dsevillamartin "dsevillamartin (8 commits)")[![karaok491](https://avatars.githubusercontent.com/u/72854852?v=4)](https://github.com/karaok491 "karaok491 (2 commits)")[![skmedix](https://avatars.githubusercontent.com/u/3246162?v=4)](https://github.com/skmedix "skmedix (1 commits)")[![StyleCIBot](https://avatars.githubusercontent.com/u/11048387?v=4)](https://github.com/StyleCIBot "StyleCIBot (1 commits)")

---

Tags

flarumfriendsofflarumhacktoberfestflarum

### Embed Badge

![Health badge](/badges/fof-open-collective/health.svg)

```
[![Health](https://phpackages.com/badges/fof-open-collective/health.svg)](https://phpackages.com/packages/fof-open-collective)
```

###  Alternatives

[fof/byobu

Well integrated, advanced private discussions.

61105.8k9](/packages/fof-byobu)[fof/user-bio

Add a user bio to user profiles

2196.5k9](/packages/fof-user-bio)[fof/sitemap

Generate a sitemap

1988.7k2](/packages/fof-sitemap)[fof/drafts

Allow users to create post and discussion drafts

1771.1k5](/packages/fof-drafts)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
