reeln-plugin-meta 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- reeln_plugin_meta-0.4.0/.github/workflows/ci.yml +42 -0
- reeln_plugin_meta-0.4.0/.github/workflows/release.yml +47 -0
- reeln_plugin_meta-0.4.0/.gitignore +50 -0
- reeln_plugin_meta-0.4.0/CHANGELOG.md +45 -0
- reeln_plugin_meta-0.4.0/Makefile +26 -0
- reeln_plugin_meta-0.4.0/PKG-INFO +173 -0
- reeln_plugin_meta-0.4.0/README.md +155 -0
- reeln_plugin_meta-0.4.0/pyproject.toml +53 -0
- reeln_plugin_meta-0.4.0/reeln_meta_plugin/__init__.py +9 -0
- reeln_plugin_meta-0.4.0/reeln_meta_plugin/auth.py +38 -0
- reeln_plugin_meta-0.4.0/reeln_meta_plugin/graph_api.py +78 -0
- reeln_plugin_meta-0.4.0/reeln_meta_plugin/livestream.py +93 -0
- reeln_plugin_meta-0.4.0/reeln_meta_plugin/plugin.py +212 -0
- reeln_plugin_meta-0.4.0/tests/__init__.py +0 -0
- reeln_plugin_meta-0.4.0/tests/conftest.py +47 -0
- reeln_plugin_meta-0.4.0/tests/unit/__init__.py +0 -0
- reeln_plugin_meta-0.4.0/tests/unit/test_auth.py +46 -0
- reeln_plugin_meta-0.4.0/tests/unit/test_graph_api.py +122 -0
- reeln_plugin_meta-0.4.0/tests/unit/test_init.py +19 -0
- reeln_plugin_meta-0.4.0/tests/unit/test_livestream.py +166 -0
- reeln_plugin_meta-0.4.0/tests/unit/test_plugin.py +588 -0
- reeln_plugin_meta-0.4.0/uv.lock +445 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- uses: astral-sh/setup-uv@v5
|
|
20
|
+
with:
|
|
21
|
+
enable-cache: true
|
|
22
|
+
|
|
23
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
24
|
+
run: uv python install ${{ matrix.python-version }}
|
|
25
|
+
|
|
26
|
+
- name: Create venv
|
|
27
|
+
run: uv venv --python ${{ matrix.python-version }}
|
|
28
|
+
|
|
29
|
+
- name: Install reeln-cli
|
|
30
|
+
run: uv pip install "git+https://github.com/StreamnDad/reeln-cli"
|
|
31
|
+
|
|
32
|
+
- name: Install dependencies
|
|
33
|
+
run: uv pip install -e ".[dev]"
|
|
34
|
+
|
|
35
|
+
- name: Lint
|
|
36
|
+
run: uv run ruff check .
|
|
37
|
+
|
|
38
|
+
- name: Type check
|
|
39
|
+
run: uv run mypy reeln_meta_plugin/
|
|
40
|
+
|
|
41
|
+
- name: Test
|
|
42
|
+
run: uv run python -m pytest tests/ -n auto --cov=reeln_meta_plugin --cov-branch --cov-fail-under=100 -q
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
publish:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
environment: release
|
|
12
|
+
permissions:
|
|
13
|
+
id-token: write
|
|
14
|
+
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
|
|
18
|
+
- uses: astral-sh/setup-uv@v5
|
|
19
|
+
with:
|
|
20
|
+
enable-cache: true
|
|
21
|
+
|
|
22
|
+
- name: Set up Python
|
|
23
|
+
run: uv python install 3.11
|
|
24
|
+
|
|
25
|
+
- name: Create venv
|
|
26
|
+
run: uv venv --python 3.11
|
|
27
|
+
|
|
28
|
+
- name: Install reeln-cli
|
|
29
|
+
run: uv pip install "git+https://github.com/StreamnDad/reeln-cli"
|
|
30
|
+
|
|
31
|
+
- name: Install dependencies
|
|
32
|
+
run: uv pip install -e ".[dev]"
|
|
33
|
+
|
|
34
|
+
- name: Lint
|
|
35
|
+
run: uv run ruff check .
|
|
36
|
+
|
|
37
|
+
- name: Type check
|
|
38
|
+
run: uv run mypy reeln_meta_plugin/
|
|
39
|
+
|
|
40
|
+
- name: Test
|
|
41
|
+
run: uv run python -m pytest tests/ -n auto --cov=reeln_meta_plugin --cov-branch --cov-fail-under=100 -q
|
|
42
|
+
|
|
43
|
+
- name: Build
|
|
44
|
+
run: uv build
|
|
45
|
+
|
|
46
|
+
- name: Publish to PyPI
|
|
47
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.egg-info/
|
|
6
|
+
*.egg
|
|
7
|
+
dist/
|
|
8
|
+
build/
|
|
9
|
+
.venv/
|
|
10
|
+
venv/
|
|
11
|
+
*.whl
|
|
12
|
+
|
|
13
|
+
# Testing / Coverage
|
|
14
|
+
.coverage
|
|
15
|
+
htmlcov/
|
|
16
|
+
.pytest_cache/
|
|
17
|
+
.tox/
|
|
18
|
+
|
|
19
|
+
# Media — prevent accidental video commits
|
|
20
|
+
*.mkv
|
|
21
|
+
*.mp4
|
|
22
|
+
*.mov
|
|
23
|
+
*.avi
|
|
24
|
+
*.webm
|
|
25
|
+
*.ts
|
|
26
|
+
|
|
27
|
+
# Project artifacts
|
|
28
|
+
secrets/
|
|
29
|
+
output/
|
|
30
|
+
.tmp/
|
|
31
|
+
|
|
32
|
+
# AI dev docs — dev-only, not tracked
|
|
33
|
+
CLAUDE.md
|
|
34
|
+
AGENTS.md
|
|
35
|
+
.claude/
|
|
36
|
+
|
|
37
|
+
# IDE
|
|
38
|
+
.idea/
|
|
39
|
+
.vscode/
|
|
40
|
+
*.swp
|
|
41
|
+
*.swo
|
|
42
|
+
*~
|
|
43
|
+
|
|
44
|
+
# OS
|
|
45
|
+
.DS_Store
|
|
46
|
+
Thumbs.db
|
|
47
|
+
|
|
48
|
+
# Environment
|
|
49
|
+
.env
|
|
50
|
+
.env.*
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/).
|
|
6
|
+
|
|
7
|
+
## [0.4.0] - 2026-03-09
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- `graph_api.py` module — shared HTTP helpers (`http_post`, `format_meta_error`, `GraphAPIError`)
|
|
12
|
+
- Cached authentication via `_ensure_auth()` — token read once per game session
|
|
13
|
+
- `ON_GAME_FINISH` hook handler — resets cached auth and game info between sessions
|
|
14
|
+
- `dry_run` config field (default `false`) — logs API calls without executing them
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- `livestream.py` now delegates HTTP to `graph_api.py`; `LivestreamError` subclasses `GraphAPIError`
|
|
19
|
+
- Plugin registers both `ON_GAME_INIT` and `ON_GAME_FINISH` hooks
|
|
20
|
+
|
|
21
|
+
## [0.3.0] - 2026-03-05
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- Feature flag system: each capability gated behind a boolean config field (default `false`)
|
|
26
|
+
- `create_livestream` feature flag for Facebook Live Video creation
|
|
27
|
+
|
|
28
|
+
## [0.2.0] - 2026-03-05
|
|
29
|
+
|
|
30
|
+
### Added
|
|
31
|
+
|
|
32
|
+
- Facebook Live Video settings: `status`, `privacy`, `content_category`, `game_id`,
|
|
33
|
+
`save_vod`, `published`, `stop_on_delete_stream`
|
|
34
|
+
- All settings configurable via plugin config and overridable via named profiles
|
|
35
|
+
|
|
36
|
+
## [0.1.0] - 2026-03-04
|
|
37
|
+
|
|
38
|
+
### Added
|
|
39
|
+
|
|
40
|
+
- Initial plugin scaffolding with `MetaPlugin` class
|
|
41
|
+
- Token-based auth module (`auth.py`) with file-based Page Access Token
|
|
42
|
+
- Facebook Live Video creation (`livestream.py`) via Graph API
|
|
43
|
+
- `ON_GAME_INIT` hook handler — creates Facebook Live Video, writes URL to shared context
|
|
44
|
+
- Plugin config schema with `page_access_token_file`, `page_id`, `graph_api_version` fields
|
|
45
|
+
- 100% line + branch test coverage
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
PLUGIN_PKG := reeln_meta_plugin
|
|
2
|
+
|
|
3
|
+
.PHONY: dev-install reeln-install test lint format check
|
|
4
|
+
|
|
5
|
+
VENV := .venv/bin
|
|
6
|
+
|
|
7
|
+
dev-install:
|
|
8
|
+
uv venv --clear
|
|
9
|
+
uv pip install -e ../reeln-cli
|
|
10
|
+
uv pip install -e ".[dev]"
|
|
11
|
+
|
|
12
|
+
reeln-install:
|
|
13
|
+
uv pip install --python ../reeln-cli/.venv/bin/python -e .
|
|
14
|
+
|
|
15
|
+
test:
|
|
16
|
+
$(VENV)/python -m pytest tests/ -n auto --cov=$(PLUGIN_PKG) --cov-branch --cov-fail-under=100 -q
|
|
17
|
+
|
|
18
|
+
lint:
|
|
19
|
+
$(VENV)/ruff check .
|
|
20
|
+
|
|
21
|
+
format:
|
|
22
|
+
$(VENV)/ruff format .
|
|
23
|
+
|
|
24
|
+
check: lint
|
|
25
|
+
$(VENV)/mypy $(PLUGIN_PKG)/
|
|
26
|
+
$(MAKE) test
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: reeln-plugin-meta
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: reeln-cli plugin for Meta platform integration (Facebook Live, Instagram, Threads)
|
|
5
|
+
Project-URL: Homepage, https://streamn.dad
|
|
6
|
+
Project-URL: Repository, https://github.com/StreamnDad/reeln-plugin-meta
|
|
7
|
+
Project-URL: Changelog, https://github.com/StreamnDad/reeln-plugin-meta/blob/main/CHANGELOG.md
|
|
8
|
+
Project-URL: Issues, https://github.com/StreamnDad/reeln-plugin-meta/issues
|
|
9
|
+
License-Expression: AGPL-3.0-only
|
|
10
|
+
Requires-Python: >=3.11
|
|
11
|
+
Provides-Extra: dev
|
|
12
|
+
Requires-Dist: mypy; extra == 'dev'
|
|
13
|
+
Requires-Dist: pytest; extra == 'dev'
|
|
14
|
+
Requires-Dist: pytest-cov; extra == 'dev'
|
|
15
|
+
Requires-Dist: pytest-xdist; extra == 'dev'
|
|
16
|
+
Requires-Dist: ruff; extra == 'dev'
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
|
|
19
|
+
# reeln-plugin-meta
|
|
20
|
+
|
|
21
|
+
A [reeln-cli](https://github.com/StreamnDad/reeln-cli) plugin for Meta platform integration (Facebook Live, Instagram, Threads).
|
|
22
|
+
|
|
23
|
+
## Install
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pip install reeln-plugin-meta
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Or for development:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
git clone https://github.com/StreamnDad/reeln-plugin-meta
|
|
33
|
+
cd reeln-plugin-meta
|
|
34
|
+
make dev-install
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Features
|
|
38
|
+
|
|
39
|
+
- **Facebook Live Video** — creates a live video on your Facebook Page during `ON_GAME_INIT`
|
|
40
|
+
- Writes the livestream embed URL to `context.shared["livestreams"]["meta"]`
|
|
41
|
+
- All features are opt-in via boolean feature flags (default `false`)
|
|
42
|
+
|
|
43
|
+
## Facebook Developer Setup
|
|
44
|
+
|
|
45
|
+
### 1. Create a Facebook Developer Account
|
|
46
|
+
|
|
47
|
+
Go to [developers.facebook.com](https://developers.facebook.com/) and register as a developer.
|
|
48
|
+
|
|
49
|
+
### 2. Create an App
|
|
50
|
+
|
|
51
|
+
1. Go to **My Apps** → **Create App**
|
|
52
|
+
2. Select a use case (e.g. **Other** → **Business**)
|
|
53
|
+
3. Choose **Business** app type
|
|
54
|
+
4. Fill in app name, contact email, and select a Business portfolio
|
|
55
|
+
5. Click **Create App**
|
|
56
|
+
|
|
57
|
+
### 3. Get a Page Access Token
|
|
58
|
+
|
|
59
|
+
1. Go to the [Graph API Explorer](https://developers.facebook.com/tools/explorer/)
|
|
60
|
+
2. Select your app from the **Meta App** dropdown
|
|
61
|
+
3. Click **Generate Access Token**
|
|
62
|
+
4. Grant the following permissions:
|
|
63
|
+
- `pages_show_list`
|
|
64
|
+
- `pages_manage_posts`
|
|
65
|
+
- `pages_read_engagement`
|
|
66
|
+
- `publish_video`
|
|
67
|
+
5. Select your Page from the **User or Page** dropdown
|
|
68
|
+
6. Copy the **Page Access Token**
|
|
69
|
+
|
|
70
|
+
> **Note:** The default token expires in ~1 hour. For a long-lived token
|
|
71
|
+
> (60 days), exchange it via the
|
|
72
|
+
> [Access Token Debugger](https://developers.facebook.com/tools/debug/accesstoken/)
|
|
73
|
+
> or the token exchange endpoint:
|
|
74
|
+
> ```
|
|
75
|
+
> GET /oauth/access_token?grant_type=fb_exchange_token
|
|
76
|
+
> &client_id=APP_ID&client_secret=APP_SECRET
|
|
77
|
+
> &fb_exchange_token=SHORT_LIVED_TOKEN
|
|
78
|
+
> ```
|
|
79
|
+
|
|
80
|
+
### 4. Save the Token to a File
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
mkdir -p secrets
|
|
84
|
+
echo "YOUR_PAGE_ACCESS_TOKEN" > secrets/meta_page_token.txt
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### 5. Get Your Page ID
|
|
88
|
+
|
|
89
|
+
Find your Page ID in **Page Settings → About → Page ID**, or query it via the API:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
curl "https://graph.facebook.com/v24.0/me?access_token=YOUR_TOKEN"
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### 6. Configure the Plugin
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
reeln config set meta.page_access_token_file ./secrets/meta_page_token.txt
|
|
99
|
+
reeln config set meta.page_id YOUR_PAGE_ID
|
|
100
|
+
reeln config set meta.create_livestream true
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Or edit your reeln config JSON directly:
|
|
104
|
+
|
|
105
|
+
```json
|
|
106
|
+
{
|
|
107
|
+
"plugins": {
|
|
108
|
+
"enabled": ["meta"],
|
|
109
|
+
"settings": {
|
|
110
|
+
"meta": {
|
|
111
|
+
"page_access_token_file": "./secrets/meta_page_token.txt",
|
|
112
|
+
"page_id": "123456789",
|
|
113
|
+
"create_livestream": true
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### 7. App Review
|
|
121
|
+
|
|
122
|
+
The `publish_video` permission may require App Review for production use.
|
|
123
|
+
During development, you can use the token with your own Pages without review.
|
|
124
|
+
|
|
125
|
+
## Configuration
|
|
126
|
+
|
|
127
|
+
### Feature Flags
|
|
128
|
+
|
|
129
|
+
Each capability is gated behind a boolean flag (default `false`):
|
|
130
|
+
|
|
131
|
+
| Field | Default | Description |
|
|
132
|
+
|---|---|---|
|
|
133
|
+
| `create_livestream` | `false` | Enable Facebook Live Video creation on `ON_GAME_INIT` |
|
|
134
|
+
| `dry_run` | `false` | Log API calls without executing them |
|
|
135
|
+
|
|
136
|
+
### Required Settings
|
|
137
|
+
|
|
138
|
+
| Field | Type | Description |
|
|
139
|
+
|---|---|---|
|
|
140
|
+
| `page_access_token_file` | str | Path to Facebook Page access token file |
|
|
141
|
+
| `page_id` | str | Facebook Page ID |
|
|
142
|
+
|
|
143
|
+
### Livestream Settings
|
|
144
|
+
|
|
145
|
+
| Field | Type | Default | Description |
|
|
146
|
+
|---|---|---|---|
|
|
147
|
+
| `graph_api_version` | str | `v24.0` | Graph API version |
|
|
148
|
+
| `status` | str | `LIVE_NOW` | Broadcast status (`LIVE_NOW` or `UNPUBLISHED`) |
|
|
149
|
+
| `privacy` | str | `EVERYONE` | Privacy setting (`EVERYONE` or `SELF`) |
|
|
150
|
+
| `content_category` | str | `SPORTS` | Content category (`SPORTS`, `VIDEO_GAMING`, etc.) |
|
|
151
|
+
| `game_id` | str | `""` | Facebook game ID to tag the broadcast with |
|
|
152
|
+
| `save_vod` | bool | `true` | Save a VOD recording after broadcast ends |
|
|
153
|
+
| `published` | bool | `true` | Publish VOD to Page timeline after broadcast ends |
|
|
154
|
+
| `stop_on_delete_stream` | bool | `false` | Auto-end broadcast when RTMP stream disconnects |
|
|
155
|
+
|
|
156
|
+
All settings can be overridden per [named profile](https://reeln-cli.readthedocs.io/en/latest/guide/configuration.html#named-profiles).
|
|
157
|
+
For example, a `config.testing.json` profile could set `"privacy": "SELF"` for test broadcasts
|
|
158
|
+
while your default config stays `"EVERYONE"` for game day.
|
|
159
|
+
|
|
160
|
+
## Development
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
make dev-install # uv venv + editable install with dev deps
|
|
164
|
+
make reeln-install # install into sibling reeln-cli venv
|
|
165
|
+
make test # pytest with 100% coverage
|
|
166
|
+
make lint # ruff check
|
|
167
|
+
make format # ruff format
|
|
168
|
+
make check # lint + mypy + test
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## License
|
|
172
|
+
|
|
173
|
+
AGPL-3.0-only
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# reeln-plugin-meta
|
|
2
|
+
|
|
3
|
+
A [reeln-cli](https://github.com/StreamnDad/reeln-cli) plugin for Meta platform integration (Facebook Live, Instagram, Threads).
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install reeln-plugin-meta
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or for development:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
git clone https://github.com/StreamnDad/reeln-plugin-meta
|
|
15
|
+
cd reeln-plugin-meta
|
|
16
|
+
make dev-install
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Features
|
|
20
|
+
|
|
21
|
+
- **Facebook Live Video** — creates a live video on your Facebook Page during `ON_GAME_INIT`
|
|
22
|
+
- Writes the livestream embed URL to `context.shared["livestreams"]["meta"]`
|
|
23
|
+
- All features are opt-in via boolean feature flags (default `false`)
|
|
24
|
+
|
|
25
|
+
## Facebook Developer Setup
|
|
26
|
+
|
|
27
|
+
### 1. Create a Facebook Developer Account
|
|
28
|
+
|
|
29
|
+
Go to [developers.facebook.com](https://developers.facebook.com/) and register as a developer.
|
|
30
|
+
|
|
31
|
+
### 2. Create an App
|
|
32
|
+
|
|
33
|
+
1. Go to **My Apps** → **Create App**
|
|
34
|
+
2. Select a use case (e.g. **Other** → **Business**)
|
|
35
|
+
3. Choose **Business** app type
|
|
36
|
+
4. Fill in app name, contact email, and select a Business portfolio
|
|
37
|
+
5. Click **Create App**
|
|
38
|
+
|
|
39
|
+
### 3. Get a Page Access Token
|
|
40
|
+
|
|
41
|
+
1. Go to the [Graph API Explorer](https://developers.facebook.com/tools/explorer/)
|
|
42
|
+
2. Select your app from the **Meta App** dropdown
|
|
43
|
+
3. Click **Generate Access Token**
|
|
44
|
+
4. Grant the following permissions:
|
|
45
|
+
- `pages_show_list`
|
|
46
|
+
- `pages_manage_posts`
|
|
47
|
+
- `pages_read_engagement`
|
|
48
|
+
- `publish_video`
|
|
49
|
+
5. Select your Page from the **User or Page** dropdown
|
|
50
|
+
6. Copy the **Page Access Token**
|
|
51
|
+
|
|
52
|
+
> **Note:** The default token expires in ~1 hour. For a long-lived token
|
|
53
|
+
> (60 days), exchange it via the
|
|
54
|
+
> [Access Token Debugger](https://developers.facebook.com/tools/debug/accesstoken/)
|
|
55
|
+
> or the token exchange endpoint:
|
|
56
|
+
> ```
|
|
57
|
+
> GET /oauth/access_token?grant_type=fb_exchange_token
|
|
58
|
+
> &client_id=APP_ID&client_secret=APP_SECRET
|
|
59
|
+
> &fb_exchange_token=SHORT_LIVED_TOKEN
|
|
60
|
+
> ```
|
|
61
|
+
|
|
62
|
+
### 4. Save the Token to a File
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
mkdir -p secrets
|
|
66
|
+
echo "YOUR_PAGE_ACCESS_TOKEN" > secrets/meta_page_token.txt
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### 5. Get Your Page ID
|
|
70
|
+
|
|
71
|
+
Find your Page ID in **Page Settings → About → Page ID**, or query it via the API:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
curl "https://graph.facebook.com/v24.0/me?access_token=YOUR_TOKEN"
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### 6. Configure the Plugin
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
reeln config set meta.page_access_token_file ./secrets/meta_page_token.txt
|
|
81
|
+
reeln config set meta.page_id YOUR_PAGE_ID
|
|
82
|
+
reeln config set meta.create_livestream true
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Or edit your reeln config JSON directly:
|
|
86
|
+
|
|
87
|
+
```json
|
|
88
|
+
{
|
|
89
|
+
"plugins": {
|
|
90
|
+
"enabled": ["meta"],
|
|
91
|
+
"settings": {
|
|
92
|
+
"meta": {
|
|
93
|
+
"page_access_token_file": "./secrets/meta_page_token.txt",
|
|
94
|
+
"page_id": "123456789",
|
|
95
|
+
"create_livestream": true
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### 7. App Review
|
|
103
|
+
|
|
104
|
+
The `publish_video` permission may require App Review for production use.
|
|
105
|
+
During development, you can use the token with your own Pages without review.
|
|
106
|
+
|
|
107
|
+
## Configuration
|
|
108
|
+
|
|
109
|
+
### Feature Flags
|
|
110
|
+
|
|
111
|
+
Each capability is gated behind a boolean flag (default `false`):
|
|
112
|
+
|
|
113
|
+
| Field | Default | Description |
|
|
114
|
+
|---|---|---|
|
|
115
|
+
| `create_livestream` | `false` | Enable Facebook Live Video creation on `ON_GAME_INIT` |
|
|
116
|
+
| `dry_run` | `false` | Log API calls without executing them |
|
|
117
|
+
|
|
118
|
+
### Required Settings
|
|
119
|
+
|
|
120
|
+
| Field | Type | Description |
|
|
121
|
+
|---|---|---|
|
|
122
|
+
| `page_access_token_file` | str | Path to Facebook Page access token file |
|
|
123
|
+
| `page_id` | str | Facebook Page ID |
|
|
124
|
+
|
|
125
|
+
### Livestream Settings
|
|
126
|
+
|
|
127
|
+
| Field | Type | Default | Description |
|
|
128
|
+
|---|---|---|---|
|
|
129
|
+
| `graph_api_version` | str | `v24.0` | Graph API version |
|
|
130
|
+
| `status` | str | `LIVE_NOW` | Broadcast status (`LIVE_NOW` or `UNPUBLISHED`) |
|
|
131
|
+
| `privacy` | str | `EVERYONE` | Privacy setting (`EVERYONE` or `SELF`) |
|
|
132
|
+
| `content_category` | str | `SPORTS` | Content category (`SPORTS`, `VIDEO_GAMING`, etc.) |
|
|
133
|
+
| `game_id` | str | `""` | Facebook game ID to tag the broadcast with |
|
|
134
|
+
| `save_vod` | bool | `true` | Save a VOD recording after broadcast ends |
|
|
135
|
+
| `published` | bool | `true` | Publish VOD to Page timeline after broadcast ends |
|
|
136
|
+
| `stop_on_delete_stream` | bool | `false` | Auto-end broadcast when RTMP stream disconnects |
|
|
137
|
+
|
|
138
|
+
All settings can be overridden per [named profile](https://reeln-cli.readthedocs.io/en/latest/guide/configuration.html#named-profiles).
|
|
139
|
+
For example, a `config.testing.json` profile could set `"privacy": "SELF"` for test broadcasts
|
|
140
|
+
while your default config stays `"EVERYONE"` for game day.
|
|
141
|
+
|
|
142
|
+
## Development
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
make dev-install # uv venv + editable install with dev deps
|
|
146
|
+
make reeln-install # install into sibling reeln-cli venv
|
|
147
|
+
make test # pytest with 100% coverage
|
|
148
|
+
make lint # ruff check
|
|
149
|
+
make format # ruff format
|
|
150
|
+
make check # lint + mypy + test
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## License
|
|
154
|
+
|
|
155
|
+
AGPL-3.0-only
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "reeln-plugin-meta"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "reeln-cli plugin for Meta platform integration (Facebook Live, Instagram, Threads)"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "AGPL-3.0-only"
|
|
11
|
+
requires-python = ">=3.11"
|
|
12
|
+
dependencies = []
|
|
13
|
+
|
|
14
|
+
[project.urls]
|
|
15
|
+
Homepage = "https://streamn.dad"
|
|
16
|
+
Repository = "https://github.com/StreamnDad/reeln-plugin-meta"
|
|
17
|
+
Changelog = "https://github.com/StreamnDad/reeln-plugin-meta/blob/main/CHANGELOG.md"
|
|
18
|
+
Issues = "https://github.com/StreamnDad/reeln-plugin-meta/issues"
|
|
19
|
+
|
|
20
|
+
[project.optional-dependencies]
|
|
21
|
+
dev = [
|
|
22
|
+
"pytest",
|
|
23
|
+
"pytest-cov",
|
|
24
|
+
"pytest-xdist",
|
|
25
|
+
"ruff",
|
|
26
|
+
"mypy",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
[project.entry-points."reeln.plugins"]
|
|
30
|
+
meta = "reeln_meta_plugin:MetaPlugin"
|
|
31
|
+
|
|
32
|
+
[tool.hatch.build.targets.wheel]
|
|
33
|
+
packages = ["reeln_meta_plugin"]
|
|
34
|
+
|
|
35
|
+
[tool.hatch.version]
|
|
36
|
+
path = "reeln_meta_plugin/__init__.py"
|
|
37
|
+
|
|
38
|
+
[tool.ruff]
|
|
39
|
+
target-version = "py311"
|
|
40
|
+
line-length = 120
|
|
41
|
+
|
|
42
|
+
[tool.ruff.lint]
|
|
43
|
+
select = ["E", "F", "I", "UP", "B", "SIM", "RUF"]
|
|
44
|
+
|
|
45
|
+
[tool.mypy]
|
|
46
|
+
strict = true
|
|
47
|
+
python_version = "3.11"
|
|
48
|
+
warn_return_any = true
|
|
49
|
+
warn_unused_configs = true
|
|
50
|
+
|
|
51
|
+
[[tool.mypy.overrides]]
|
|
52
|
+
module = "reeln.*"
|
|
53
|
+
ignore_missing_imports = true
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""Token-based authentication for Meta APIs."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from reeln.core.config import data_dir
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class AuthError(Exception):
|
|
11
|
+
"""Raised when authentication fails."""
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def default_token_path() -> Path:
|
|
15
|
+
"""Return the default Page Access Token file path."""
|
|
16
|
+
return Path(data_dir() / "meta" / "page_token.txt")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def read_token(path: Path) -> str:
|
|
20
|
+
"""Read and validate a token from a file.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
path: Path to the token file.
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
The token string (stripped of whitespace).
|
|
27
|
+
|
|
28
|
+
Raises:
|
|
29
|
+
AuthError: If the file is missing or empty.
|
|
30
|
+
"""
|
|
31
|
+
if not path.exists():
|
|
32
|
+
raise AuthError(f"Token file not found: {path}")
|
|
33
|
+
|
|
34
|
+
token = path.read_text().strip()
|
|
35
|
+
if not token:
|
|
36
|
+
raise AuthError(f"Token file is empty: {path}")
|
|
37
|
+
|
|
38
|
+
return token
|