Compare commits

..

173 commits
0.1 ... main

Author SHA1 Message Date
3097ed4420 Version 2026-07-28 15:52:01 +02:00
814ac745a5 Version 2026-07-28 15:50:44 +02:00
6f237257d1 URL Fix 2026-07-28 15:49:56 +02:00
b8cb368c27 Codeberg entfernt 2026-07-28 15:46:43 +02:00
simonpipe
7825565b3d url 2026-05-29 09:41:46 +02:00
simonpipe
519a4ba9b0 Formating 2026-05-28 11:33:09 +02:00
simonpipe
cbb190d51e Add URL 2026-05-28 11:29:54 +02:00
simonpipe
c31766341a Add Fediverse contact 2026-05-28 11:25:59 +02:00
simonpipe
b7507290b6 Add Fediverse Contact 2026-05-28 11:24:47 +02:00
simonpipe
adb5b28713 Update .gitattributes 2026-05-28 08:18:02 +02:00
simonpipe
c395abeef3 Update readme.md 2026-05-27 14:21:14 +02:00
simonpipe
adfa390b9d Update readme-de.md 2026-05-27 14:20:52 +02:00
simonpipe
ea065984d8 Update extension.ini 2026-05-27 14:20:31 +02:00
simonpipe
6996fd4ac6 Update mastodonapi.php 2026-05-27 14:20:04 +02:00
simonpipe
faef38bec7 Update readme.md 2026-05-27 08:45:07 +02:00
simonpipe
111b5c4f90 Update readme-de.md 2026-05-27 08:44:52 +02:00
simonpipe
d290e887ff Update help-de.md 2026-05-27 08:43:45 +02:00
simonpipe
1059cb92c6 Update help-de.md 2026-05-27 08:43:15 +02:00
simonpipe
8117b30499 Update help-en.md 2026-05-27 08:42:07 +02:00
simonpipe
8d65e7aebc Update help-gotoso-en.md 2026-05-27 08:41:36 +02:00
simonpipe
8b625ba7f0 Update help-gotoso-en.md 2026-05-27 08:40:37 +02:00
simonpipe
1afcf3e9b8 Update extension.ini 2026-05-27 08:35:23 +02:00
simonpipe
1e461693ef Update mastodonapi.php 2026-05-27 08:35:04 +02:00
simonpipe
baaa18d817 Update extension.ini 2026-05-27 07:56:06 +02:00
simonpipe
6ad7d5a6ea Update mastodonapi.php 2026-05-27 07:54:37 +02:00
simonpipe
ffd25e65cc Update extension.ini 2026-05-27 07:52:04 +02:00
simonpipe
1a04be8868 Update readme-de.md 2026-05-27 07:49:43 +02:00
simonpipe
009217a5dc Update readme.md 2026-05-27 07:49:24 +02:00
simonpipe
4143d8705b Update readme-de.md 2026-05-27 07:48:57 +02:00
simonpipe
c861d784a6 Update readme-de.md 2026-05-27 07:39:28 +02:00
simonpipe
0608c80c0e Update readme-de.md 2026-05-27 07:39:18 +02:00
simonpipe
9fb9eb6167 Update readme.md 2026-05-27 07:38:33 +02:00
simonpipe
2809f64abf Update readme-de.md 2026-02-23 16:02:59 +01:00
simonpipe
c6e5093fdb Update readme.md 2026-02-23 16:02:33 +01:00
simonpipe
ac5e899371 Update readme-de.md 2026-02-23 11:01:36 +01:00
simonpipe
3ed242c0e9 Update readme.md 2026-02-23 11:01:28 +01:00
simonpipe
2a611e144a Update extension.ini 2026-02-23 08:41:03 +01:00
simonpipe
15f3da1b62 Update mastodonapi.php 2026-02-23 08:40:40 +01:00
simonpipe
128570ddc1 Update extension.ini 2026-02-22 17:45:30 +01:00
simonpipe
6b320c34bb Update mastodonapi.php 2026-02-22 17:45:04 +01:00
simonpipe
101315a5ff Update mastodonapi.php 2026-02-22 17:43:11 +01:00
simonpipe
6c6232534e Update mastodonapi.php 2026-01-08 08:53:34 +01:00
simonpipe
fe6e16c7d0 Update readme-de.md 2026-01-08 08:53:07 +01:00
simonpipe
26228b6661 Update readme.md 2026-01-08 08:52:58 +01:00
simonpipe
ab8b730955 Update extension.ini 2026-01-08 08:52:48 +01:00
simonpipe
0a0a8200f3 Update extension.ini 2026-01-08 08:52:34 +01:00
simonpipe
9456c5b930 Update mastodonapi.status 2026-01-08 08:52:12 +01:00
simonpipe
39f96c85a4 Update mastodonapi.log 2026-01-08 08:48:36 +01:00
simonpipe
c587ecc66a Update mastodonapi.log 2026-01-07 23:21:21 +01:00
simonpipe
19dc93bb49 Update mastodonapi.php 2026-01-07 23:18:16 +01:00
simonpipe
5bed76ad36 Update extension.ini 2026-01-07 23:17:52 +01:00
simonpipe
1cee502f03 Update extension.ini 2026-01-07 23:02:38 +01:00
simonpipe
62a84080df Update mastodonapi.php 2026-01-07 23:02:18 +01:00
simonpipe
d4742b355f Update extension.ini 2026-01-07 22:51:29 +01:00
simonpipe
44835d596b Update mastodonapi.ini 2026-01-07 22:50:56 +01:00
simonpipe
23540a1f76 Update mastodonapi.php 2026-01-07 22:50:46 +01:00
simonpipe
f7b2fa7378 Update mastodonapi.php 2026-01-07 22:47:17 +01:00
simonpipe
8a94d55c34 Update extension.ini 2026-01-07 22:46:25 +01:00
simonpipe
851bf57c38 Update mastodonapi.txt 2026-01-07 22:46:06 +01:00
simonpipe
c1ae73e365 Update extension.ini 2026-01-07 22:38:01 +01:00
simonpipe
174cdb580f Update extension.ini 2026-01-07 22:31:20 +01:00
simonpipe
835e44d998 Update readme-de.md 2026-01-07 22:29:12 +01:00
simonpipe
47511c4ff9 Update readme.md 2026-01-07 22:29:05 +01:00
simonpipe
2dacddf74f Update mastodonapi.php 2026-01-07 22:28:55 +01:00
simonpipe
0de22660b0 Update mastodonapi.php 2026-01-07 22:28:46 +01:00
simonpipe
fd7aa866f3 Update extension.ini 2026-01-07 22:23:42 +01:00
simonpipe
5fc2f5cc11 Add mastodonapi.status 2026-01-07 22:20:17 +01:00
simonpipe
9268d40c90 Update extension.ini 2026-01-07 22:20:04 +01:00
simonpipe
b4e6fbe3f4 Update readme-de.md 2026-01-07 19:56:30 +01:00
simonpipe
7048e854f9 Update readme.md 2026-01-07 19:56:23 +01:00
simonpipe
0e3e0dbac3 Update extension.ini 2026-01-07 19:37:32 +01:00
simonpipe
cc82e6ef79 Update mastodonapi.php 2026-01-07 19:37:18 +01:00
simonpipe
55b41aad48 Update mastodonapi.php 2026-01-07 19:31:36 +01:00
simonpipe
dd8a402bb0 Update mastodonapi.php 2026-01-07 19:26:18 +01:00
simonpipe
a187a962ef Update mastodonapi.php 2026-01-07 19:22:23 +01:00
simonpipe
bfeb41fdf1 Update mastodonapi.php 2026-01-07 19:14:15 +01:00
simonpipe
f605b3f8be Update mastodonapi.php 2026-01-07 16:02:13 +01:00
simonpipe
fcb54d5fc5 Update readme-de.md 2026-01-07 16:00:51 +01:00
simonpipe
7597d345d2 Update readme.md 2026-01-07 16:00:35 +01:00
simonpipe
b735decdab Update extension.ini 2026-01-07 16:00:25 +01:00
simonpipe
9d3555803f Update mastodonapi.php 2026-01-07 16:00:11 +01:00
simonpipe
5ace0f372d Update mastodonapi.php 2026-01-07 15:59:56 +01:00
simonpipe
80bd916b85 Update mastodonapi.php 2026-01-07 15:58:56 +01:00
simonpipe
f6189a2fde Update extension.ini 2026-01-07 15:54:42 +01:00
simonpipe
47b8a4c5f9 Update mastodonapi.php 2026-01-07 15:53:42 +01:00
simonpipe
4d00db6e22 Update readme-de.md 2026-01-07 15:51:14 +01:00
simonpipe
98103549ef Update readme.md 2026-01-07 15:50:31 +01:00
simonpipe
a70e70ec5b Update extension.ini 2026-01-07 15:50:20 +01:00
simonpipe
b28dfb2d1f Update extension.ini 2026-01-07 15:48:09 +01:00
simonpipe
31d51c131a Update readme-de.md 2026-01-07 15:46:57 +01:00
simonpipe
56be39a22f Update readme-de.md 2026-01-07 15:45:56 +01:00
simonpipe
fed0a8040f Update readme-de.md 2026-01-07 15:43:35 +01:00
simonpipe
0d1a881b1e Update readme-de.md 2026-01-07 15:42:53 +01:00
simonpipe
d1fc6613d3 Update readme-de.md 2026-01-07 15:42:29 +01:00
simonpipe
00c5c17e22 Update readme.md 2026-01-07 15:39:25 +01:00
simonpipe
fb09357905 Update readme.md 2026-01-07 15:39:13 +01:00
simonpipe
13c26b2731 Update readme.md 2026-01-07 15:36:04 +01:00
simonpipe
4e893e82aa Update readme.md 2026-01-07 15:32:39 +01:00
simonpipe
c7818ec83e Update extension.ini 2026-01-07 15:32:24 +01:00
simonpipe
db6a20325f Update mastodonapi.php 2026-01-07 15:31:26 +01:00
simonpipe
ad39532601 Update readme.md 2026-01-07 15:25:18 +01:00
simonpipe
073b1849a1 Update readme.md 2026-01-07 15:12:58 +01:00
simonpipe
a8550fc0b6 Update readme.md 2026-01-07 15:09:43 +01:00
simonpipe
51c9d72aea Update readme.md 2026-01-07 15:09:08 +01:00
simonpipe
f59641319c Update readme.md 2026-01-07 15:06:18 +01:00
simonpipe
b804f6cf6b Update readme.md 2026-01-07 15:03:37 +01:00
simonpipe
0920fe7314 Update readme.md 2026-01-07 15:02:53 +01:00
simonpipe
d1b0c828f1 Update readme.md 2026-01-07 15:02:07 +01:00
simonpipe
1c5b9f99e8 Update readme.md 2026-01-07 15:01:49 +01:00
simonpipe
29d4197835 Update readme.md 2026-01-07 14:59:24 +01:00
simonpipe
33aa39353c Update readme.md 2026-01-07 14:57:46 +01:00
simonpipe
d6813dbdf6 Update readme.md 2026-01-07 14:52:49 +01:00
simonpipe
2107b09c21 Update readme.md 2026-01-07 14:52:26 +01:00
simonpipe
016433e9a7 Update readme.md 2026-01-07 14:51:26 +01:00
simonpipe
9b4171dc7c Update readme.md 2026-01-07 14:50:52 +01:00
simonpipe
f90294de8f Update readme.md 2026-01-07 14:47:46 +01:00
simonpipe
05f5902857 Update readme.md 2026-01-07 14:46:50 +01:00
simonpipe
d11cf173b2 Update readme.md 2026-01-07 14:46:10 +01:00
simonpipe
7e290cd0ad Update readme.md 2026-01-07 14:45:30 +01:00
simonpipe
3a987c266b Update readme.md 2026-01-07 14:44:19 +01:00
simonpipe
167522e9de Update readme.md 2026-01-07 14:42:39 +01:00
simonpipe
784d92ad40 Update readme.md 2026-01-07 14:42:24 +01:00
simonpipe
67c36ee72b Update readme.md 2026-01-07 14:41:17 +01:00
simonpipe
5b48e5649f Update readme-de.md 2026-01-07 10:46:14 +01:00
simonpipe
bee65004f4 Update readme.md 2026-01-07 10:45:39 +01:00
simonpipe
234af208d5 Update readme-de.md 2026-01-07 10:45:26 +01:00
simonpipe
aaddc3ed55 Update readme.md 2026-01-07 10:45:01 +01:00
simonpipe
0816a76b39 Update readme-de.md 2026-01-07 10:44:44 +01:00
simonpipe
c043183855 Update extension.ini 2026-01-07 09:58:34 +01:00
simonpipe
fada60ed46 Update mastodonapi.php 2026-01-07 09:58:23 +01:00
simonpipe
60cee94861 Update extension.ini 2026-01-07 09:53:07 +01:00
simonpipe
ef65e3451f Update mastodonapi.php 2026-01-07 09:52:57 +01:00
simonpipe
950864df64 Update extension.ini 2026-01-07 09:49:17 +01:00
simonpipe
cf294020e8 Update mastodonapi.php 2026-01-07 09:46:49 +01:00
simonpipe
3b902a118b Update readme-en.md 2026-01-07 09:34:50 +01:00
simonpipe
24a3bb7e87 Update readme.md 2026-01-07 09:32:34 +01:00
simonpipe
5d0f649354 Update readme.md 2026-01-07 09:22:38 +01:00
simonpipe
c21fd9e4b9 Update readme.md 2026-01-07 09:22:13 +01:00
simonpipe
925f996db3 Update mastodonapi.php 2026-01-07 09:10:22 +01:00
simonpipe
315da16328 Update extension.ini 2026-01-07 09:04:37 +01:00
simonpipe
50ceea433d Update mastodonapi.php 2026-01-07 09:03:29 +01:00
simonpipe
5420ec8f50 Update mastodonapi.php 2026-01-01 18:36:49 +01:00
simonpipe
b2711fe7eb Update mastodonapi.php 2026-01-01 17:22:01 +01:00
simonpipe
8bcb974cbe Update extension.ini 2026-01-01 17:21:34 +01:00
simonpipe
3c849c1b6c Update extension.ini 2026-01-01 16:43:35 +01:00
simonpipe
e93bb20246 Update extension.ini 2026-01-01 16:41:58 +01:00
simonpipe
6b2042bbfa Update extension.ini 2026-01-01 16:35:00 +01:00
simonpipe
9fb48527eb Update extension.ini 2026-01-01 16:30:36 +01:00
simonpipe
d461d34048 Update extension.ini 2026-01-01 16:27:12 +01:00
simonpipe
12284b5d14 Update extension.ini 2026-01-01 16:25:18 +01:00
simonpipe
c59e878388 Update mastodonapi.php 2026-01-01 16:11:39 +01:00
simonpipe
6107808050 Update extension.ini 2026-01-01 16:10:54 +01:00
simonpipe
e0562cce9f Add .gitattributes 2026-01-01 15:59:00 +01:00
simonpipe
cdddcde33e Update extension.ini 2026-01-01 15:50:02 +01:00
simonpipe
04e6355d6a Update extension.ini 2026-01-01 15:41:15 +01:00
simonpipe
dd5a9904fa Update extension.ini 2026-01-01 15:38:48 +01:00
simonpipe
04748c4518 Update extension.ini 2026-01-01 15:38:30 +01:00
simonpipe
2508804b5e Update mastodonapi.php 2026-01-01 15:38:21 +01:00
simonpipe
50b8a42e1e Update readme.md 2026-01-01 15:37:50 +01:00
simonpipe
da19dd8648 Update readme-en.md 2026-01-01 15:35:59 +01:00
simonpipe
b751a8f997 Update readme-en.md 2026-01-01 15:35:02 +01:00
simonpipe
cb0b8f1d1e Update readme.md 2026-01-01 15:34:11 +01:00
simonpipe
4752460dd7 Update readme.md 2026-01-01 15:33:21 +01:00
simonpipe
3053604203 Update readme.md 2026-01-01 15:32:22 +01:00
simonpipe
0de1853edf Update readme.md 2026-01-01 15:32:08 +01:00
simonpipe
4d526baac6 Update readme.md 2026-01-01 15:31:37 +01:00
simonpipe
217495cfcd Update mastodonapi.php 2026-01-01 15:28:52 +01:00
simonpipe
4eaa3edf60 Update mastodonapi.php 2026-01-01 14:56:09 +01:00
simonpipe
0a4505986d Update mastodonapi.php 2026-01-01 14:55:08 +01:00
simonpipe
8fb6caedf4 Update help-gotoso-en.md 2025-08-21 12:17:01 +02:00
simonpipe
ced3a19f88 Update help-gotoso-de.md 2025-08-21 12:16:34 +02:00
simonpipe
34e175b5c3 LICENSE aktualisiert 2025-08-14 09:49:20 +02:00
simonpipe
68f171a1ef LICENSE.md aktualisiert 2025-08-14 09:47:27 +02:00
10 changed files with 361 additions and 307 deletions

6
.gitattributes vendored Normal file
View file

@ -0,0 +1,6 @@
.gitattributes export-ignore
LICENSE export-ignore
help*.md export-ignore
readme*.md export-ignore
# Auto detect text files and perform LF normalization
* text=auto

View file

@ -1,3 +1,5 @@
UNLICENSE
This is free and unencumbered software released into the public domain. This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or Anyone is free to copy, modify, publish, use, compile, sell, or

View file

@ -1,13 +1,14 @@
# Datenstrom Yellow extension settings # Datenstrom Yellow extension settings
Extension: MastodonAPI Extension: Mastodonapi
Version: 0.1 Version: 0.9.9
Description: Mastodon-API Feed to Blog Post (For Mastodon & GoToSocial) Description: Import your toots into your blog.
Developer: Simon Pipe Developer: Simon Rohr
Tag: feature Tag: feature
Download: https://codeberg.org/simonpipe/yellow-mastodonapi/archive/main.zip DownloadUrl: https://git.thepipes.ch/simon/yellow-mastodonapi/archive/main.zip
Documentation: https://codeberg.org/simonpipe/yellow-mastodonapi DocumentationUrl: https://git.thepipes.ch/simon/yellow-mastodonapi
DocumentationLanguage: en, de DocumentationLanguage: en, de
Published: 2025-08-13 20:52:00 Published: 2026-07-28 15:41:00
Status: experimental Status: experimental
system/workers/mastodonapi.php: mastodonapi.php, create update system/workers/mastodonapi.php: mastodonapi.php, create, update
system/workers/mastodonapi.status: mastodonapi.status, create, update, careful

View file

@ -1,6 +1,18 @@
# Hilfe für GoToSocial # Hilfe für Snac und GoToSocial
## 1. Account-ID herausfinden ## Snac
### Token erstellen
1. Ersetze in diesem Link die Platzhalter und öffne ihn im Browser:
```
https://DEINE_INSTANZ_URL/oauth/x-snac-get-token
```
→ Anmelden, bestätigen und den **Code** kopieren.
## GoToSocial
### Account-ID herausfinden
1. Öffne dein Profil: 1. Öffne dein Profil:
`https://DEINE_INSTANZ_URL/@DEIN_BENUTZERNAME` `https://DEINE_INSTANZ_URL/@DEIN_BENUTZERNAME`
2. Zeige den **Quelltext** der Seite an (Rechtsklick → *Seitenquelltext anzeigen*). 2. Zeige den **Quelltext** der Seite an (Rechtsklick → *Seitenquelltext anzeigen*).
@ -13,7 +25,7 @@
5. Trage die Account-ID in Yellow in der `yellow-system.ini` unter 5. Trage die Account-ID in Yellow in der `yellow-system.ini` unter
`MastodonapiAccountId` ein. `MastodonapiAccountId` ein.
## 2. Token erstellen ### Token erstellen
1. Melde dich in deiner GoToSocial-Instanz an: 1. Melde dich in deiner GoToSocial-Instanz an:
`https://DEINE_INSTANZ_URL/settings` `https://DEINE_INSTANZ_URL/settings`
@ -29,11 +41,11 @@
→ Anmelden, bestätigen und den **Code** kopieren. → Anmelden, bestätigen und den **Code** kopieren.
6. Ersetze in diesem `curl`-Befehl die Platzhalter: 6. Ersetze in diesem `curl`-Befehl die Platzhalter:
```bash ```bash
curl -X POST https://DEINE_INSTANZ_URL/oauth/token curl -X POST https://DEINE_INSTANZ_URL/oauth/token \
-d "client_id=DEIN_CLIENT_ID" -d "client_id=DEIN_CLIENT_ID" \
-d "client_secret=DEIN_CLIENT_SECRET" -d "client_secret=DEIN_CLIENT_SECRET" \
-d "grant_type=authorization_code" -d "grant_type=authorization_code" \
-d "code=DER_CODE_AUS_SCHRITT_5" -d "code=DER_CODE_AUS_SCHRITT_5" \
-d "redirect_uri=urn:ietf:wg:oauth:2.0:oob" -d "redirect_uri=urn:ietf:wg:oauth:2.0:oob"
``` ```
7. Führe den Befehl im **Terminal** aus. 7. Führe den Befehl im **Terminal** aus.

View file

@ -1,6 +1,18 @@
# Help for GoToSocial # Help for Snac and GoToSocial
## Find your Account ID ## Snac
### Create a Token
1. Adjust the following link and paste it into your browser:
```
https://YOUR_INSTANCE_URL/oauth/x-snac-get-token
```
→ Log in, authorize, and copy the **code**.
## GoToSocial
### Find your Account ID
1. Open your profile (`https://YOUR_INSTANCE_URL/@YOUR_USERNAME`) 1. Open your profile (`https://YOUR_INSTANCE_URL/@YOUR_USERNAME`)
2. View the **page source** and search for this line in the `<head>` section: 2. View the **page source** and search for this line in the `<head>` section:
```html ```html
@ -9,7 +21,7 @@
3. You will find your **account ID** in this line between `fileserver` and `attachment`: `.../fileserver/ACCOUNT_ID/attachment/...` 3. You will find your **account ID** in this line between `fileserver` and `attachment`: `.../fileserver/ACCOUNT_ID/attachment/...`
4. Copy your account ID and enter it in Yellow's `yellow-system.ini` under *MastodonapiAccountId*. 4. Copy your account ID and enter it in Yellow's `yellow-system.ini` under *MastodonapiAccountId*.
## Create a Token ### Create a Token
1. Log in to your GoToSocial instance under `/settings` and click **New Application** under **Applications**. 1. Log in to your GoToSocial instance under `/settings` and click **New Application** under **Applications**.
2. Under `Application name (required)`, enter a name (e.g., *yellow-mastodonapi*). The other fields can be left blank. Click **Create**. 2. Under `Application name (required)`, enter a name (e.g., *yellow-mastodonapi*). The other fields can be left blank. Click **Create**.
@ -21,11 +33,11 @@
→ Log in, authorize, and copy the **code**. → Log in, authorize, and copy the **code**.
5. Adjust the following lines: 5. Adjust the following lines:
```bash ```bash
curl -X POST https://DEINE_INSTANZ_URL/oauth/token curl -X POST https://DEINE_INSTANZ_URL/oauth/token \
-d "client_id=DEIN_CLIENT_ID" -d "client_id=DEIN_CLIENT_ID" \
-d "client_secret=DEIN_CLIENT_SECRET" -d "client_secret=DEIN_CLIENT_SECRET" \
-d "grant_type=authorization_code" -d "grant_type=authorization_code" \
-d "code=DER_CODE_AUS_SCHRITT_5" -d "code=DER_CODE_AUS_SCHRITT_4" \
-d "redirect_uri=urn:ietf:wg:oauth:2.0:oob" -d "redirect_uri=urn:ietf:wg:oauth:2.0:oob"
``` ```
6. Copy this code into your **terminal** and press Enter. You will now receive your **user token**, which you can enter in Yellow's `yellow-system.ini`. 6. Copy this code into your **terminal** and press Enter. You will now receive your **user token**, which you can enter in Yellow's `yellow-system.ini`.

View file

@ -1,154 +1,197 @@
<?php <?php
// Public Domain // Mastodonapi extension, https://git.thepipes.ch/simon/yellow-mastodonapi
// MastodonAPI extension, https://codeberg.org/simonpipe/yellow-mastodonapi
class YellowMastodonAPI { class YellowMastodonapi {
const VERSION = "0.1"; const VERSION = "0.9.9";
public $yellow; public $yellow; // access to API
// Initialize extension
public function onLoad($yellow) { public function onLoad($yellow) {
$this->yellow = $yellow; $this->yellow = $yellow;
$this->yellow->system->setDefault("mastodonapiInstanceUrl", "https://example.social"); $this->yellow->system->setDefault("mastodonapiInstanceUrl", "https://example.social");
$this->yellow->system->setDefault("mastodonapiAccountId", ""); $this->yellow->system->setDefault("mastodonapiAccountId", "");
$this->yellow->system->setDefault("mastodonapiAccessToken", ""); $this->yellow->system->setDefault("mastodonapiAccessToken", "");
$this->yellow->system->setDefault("mastodonapiUpdateInterval", "30");
$this->yellow->system->setDefault("mastodonapiLimit", "20");
$this->yellow->system->setDefault("mastodonapiHashtag", ""); $this->yellow->system->setDefault("mastodonapiHashtag", "");
$this->yellow->system->setDefault("mastodonapiAuthor", "YellowUser"); $this->yellow->system->setDefault("mastodonapiAuthor", "YellowUser");
$this->yellow->system->setDefault("mastodonapiTag", "Fediverse"); $this->yellow->system->setDefault("mastodonapiTag", "Fediverse");
$this->yellow->system->setDefault("mastodonapiFolder", "content/1-blog/"); $this->yellow->system->setDefault("mastodonapiFolder", "content/2-blog/");
$this->yellow->system->setDefault("mastodonapiTriggerPath", "/mastodonapi-webhook-CHANGE_THIS_SECRET_KEY"); $this->yellow->system->setDefault("mastodonapiMaxAge", "0");
$this->yellow->system->setDefault("mastodonapiLimit", "20"); $this->yellow->system->setDefault("mastodonapiStatus", "public");
} }
public function onRequest($scheme, $address, $base, $location, $fileName) { // Handle update
$triggerPath = $this->yellow->system->get("mastodonapiTriggerPath"); public function onUpdate($action) {
if ($location == $triggerPath) { if ( $action=="mastodon" || $action=="daily" || $action=="install" ) {
$postsCreated = $this->processMastodonFeed(); $this->updateMastodonPosts();
$this->sendResponse( }
$postsCreated !== false }
? "Mastodon/GoToSocial API feed processed. Created $postsCreated posts."
: "Error processing Mastodon/GoToSocial API feed.", // Handle command
$postsCreated !== false ? 200 : 500 public function onCommand($command, $text) {
); if ( $command=="mastodonapi" ) {
return 1; echo "Mastodon Import gestartet...\n";
$count = $this->updateMastodonPosts();
if ( $count===false ) {
echo "Fehler: API nicht erreichbar, falsche ID oder Zugriff verweigert.\n";
return 500;
}
echo "Erfolg: " . $count . " neue Posts verarbeitet.\n";
return true;
} }
return 0; return 0;
} }
public function onCommand($command, $text) { // Handle periodic update
if (!$this->yellow) return 500; public function onTick() {
switch ($command) { $interval = intval($this->yellow->system->get("mastodonapiUpdateInterval")) * 60;
case "mastodonapi": $statusFile = $this->getStatusFile();
if (!empty($text)) return 400; $lastUpdate = file_exists($statusFile) ? intval(file_get_contents($statusFile)) : 0;
$postsCreated = $this->processMastodonFeed(); if ( time() - $lastUpdate >= $interval ) {
return ($postsCreated !== false) ? 0 : 500; $this->updateMastodonPosts();
default:
return 0;
} }
} }
private function processMastodonFeed() { // Update Mastodon posts
$instanceUrl = $this->yellow->system->get("mastodonapiInstanceUrl"); public function updateMastodonPosts() {
$accountId = $this->yellow->system->get("mastodonapiAccountId"); $postsCreated = $this->processMastodonFeed();
$accessToken = $this->yellow->system->get("mastodonapiAccessToken"); if ( $postsCreated!==false ) {
$hashtag = ltrim($this->yellow->system->get("mastodonapiHashtag"), '#'); $statusFile = $this->getStatusFile();
$defaultAuthor = $this->yellow->system->get("mastodonapiAuthor"); file_put_contents($statusFile, time());
$defaultTag = $this->yellow->system->get("mastodonapiTag");
$targetFolder = $this->yellow->system->get("mastodonapiFolder");
$limit = intval($this->yellow->system->get("mastodonapiLimit"));
if (empty($instanceUrl) || empty($accountId)) {
return false;
} }
return $postsCreated;
}
// Process Mastodon feed and create pages
private function processMastodonFeed() {
$instanceUrl = $this->yellow->system->get("mastodonapiInstanceUrl");
$accountId = $this->yellow->system->get("mastodonapiAccountId");
$accessToken = $this->yellow->system->get("mastodonapiAccessToken");
$hashtag = ltrim($this->yellow->system->get("mastodonapiHashtag"), "#");
$defaultAuthor = $this->yellow->system->get("mastodonapiAuthor");
$defaultTag = $this->yellow->system->get("mastodonapiTag");
$targetFolder = $this->yellow->system->get("mastodonapiFolder");
$statusSetting = $this->yellow->system->get("mastodonapiStatus");
$maxAgeHours = intval($this->yellow->system->get("mastodonapiMaxAge"));
$limit = intval($this->yellow->system->get("mastodonapiLimit"));
if ( empty($instanceUrl) || empty($accountId) ) return false;
$apiUrl = rtrim($instanceUrl, "/") . "/api/v1/accounts/" . $accountId . "/statuses?limit=" . $limit; $apiUrl = rtrim($instanceUrl, "/") . "/api/v1/accounts/" . $accountId . "/statuses?limit=" . $limit;
$headers = ["User-Agent: YellowMastodonAPI"]; $headers = array("User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) YellowMastodonapi/" . self::VERSION);
if (!empty($accessToken)) { if ( !empty($accessToken) ) $headers[] = "Authorization: Bearer " . $accessToken;
$headers[] = "Authorization: Bearer " . $accessToken;
}
$ch = curl_init($apiUrl); $ch = curl_init($apiUrl);
curl_setopt_array($ch, [ curl_setopt_array($ch, array(
CURLOPT_RETURNTRANSFER => true, CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true, CURLOPT_FOLLOWLOCATION => true,
CURLOPT_TIMEOUT => 30, CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => $headers, CURLOPT_HTTPHEADER => $headers,
CURLOPT_SSL_VERIFYPEER => true, CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => 2 CURLOPT_SSL_VERIFYHOST => 0
]); ));
$json = curl_exec($ch); $json = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch); curl_close($ch);
if ($json === false || $httpCode < 200 || $httpCode >= 300) { if ( $json===false || $httpCode < 200 || $httpCode >= 300 ) return false;
return false;
}
$posts = json_decode($json, true); $posts = json_decode($json, true);
if (!is_array($posts)) { if ( !is_array($posts) ) return false;
return false;
} echo "DEBUG: " . count($posts) . " Posts von API empfangen.\n";
$config = $this->getYellowConfig();
$postsCreated = 0; $postsCreated = 0;
foreach ( $posts as $index => $post ) {
// Snac-Verschachtelung auflösen: Wenn ein echtes 'reblog'-Objekt von jemand anderem drinsteckt
if ( !empty($post["reblog"]) && is_array($post["reblog"]) ) {
// Nur überspringen, wenn es wirklich der Post eines ANDEREN Nutzers ist, den du geteilt hast
if ( !empty($post["reblog"]["account"]["id"]) && $post["reblog"]["account"]["id"] != $accountId ) {
echo "DEBUG [$index]: Übersprungen (Echter Reblog eines fremden Beitrags)\n";
continue;
}
// Wenn es dein eigener ist, nutzen wir die inneren Daten
$post = $post["reblog"];
}
foreach ($posts as $post) { $contentHtml = $post["content"] ?? "";
if (!empty($post['reblog']) || (!empty($post['reblogged']) && $post['reblogged'] === true)) continue; $createdAt = $post["created_at"] ?? "";
if (!is_null($post['in_reply_to_id'])) continue; $shortText = mb_substr(strip_tags($contentHtml), 0, 40) . "...";
$contentHtml = $post['content'] ?? ''; // Reblogged-Flag nur werten, wenn es kein Eigen-Boost ist
$createdAt = $post['created_at'] ?? ''; if ( (isset($post["reblogged"]) && $post["reblogged"]===true) && empty($contentHtml) ) {
$tags = array_column($post['tags'] ?? [], 'name'); echo "DEBUG [$index]: Übersprungen (Leerer Boost): $shortText\n";
continue;
}
if (!empty($hashtag) && !in_array(strtolower($hashtag), array_map('strtolower', $tags))) { // REPLY CHECK (Snac sendet leere Strings oder null)
if ( !empty($post["in_reply_to_id"]) ) {
echo "DEBUG [$index]: Übersprungen (Antwort - Reply-ID: " . $post["in_reply_to_id"] . "): $shortText\n";
continue;
}
// ALTER CHECK
if ( $maxAgeHours > 0 ) {
if ( strtotime($createdAt) < ( time() - ( $maxAgeHours * 3600 ) ) ) {
echo "DEBUG [$index]: Übersprungen (Zu alt - Datum: $createdAt): $shortText\n";
continue;
}
}
// HASHTAG CHECK
$tags = array_column($post["tags"] ?? array(), "name");
if ( !empty($hashtag) && !in_array(strtolower($hashtag), array_map("strtolower", $tags)) ) {
echo "DEBUG [$index]: Übersprungen (Hashtag #$hashtag fehlt): $shortText\n";
continue; continue;
} }
$title = $this->generateTitle($contentHtml); $title = $this->generateTitle($contentHtml);
$titleSlug = $this->generateTitleSlug($title); $titleSlug = $this->generateTitleSlug($title);
$datePrefix = date('Y-m-d', strtotime($createdAt)); $fileName = date("Y-m-d", strtotime($createdAt)) . "-" . $titleSlug . ".md";
$fileName = $datePrefix . '-' . $titleSlug . '.md'; $fullPath = $this->yellow->system->get("coreServerDocument") . $targetFolder . $fileName;
$fullPath = $config->get("coreServerDocument") . $targetFolder . $fileName;
if (file_exists($fullPath)) continue; // EXISTENZ CHECK
if (!is_dir(dirname($fullPath))) mkdir(dirname($fullPath), 0755, true); if ( file_exists($fullPath) ) {
echo "DEBUG [$index]: Übersprungen (Datei existiert bereits: $fileName): $shortText\n";
continue;
}
$authorName = $post['account']['display_name'] ?: $defaultAuthor; if ( !is_dir(dirname($fullPath)) ) {
$authorUrl = $post['account']['url'] ?: "#"; mkdir(dirname($fullPath), 0777, true);
chmod(dirname($fullPath), 0777);
}
$imageFilenames = []; $imageFilenames = array();
$imageAltTexts = []; $imageAltTexts = array();
foreach ( $post["media_attachments"] ?? array() as $media ) {
foreach ($post['media_attachments'] ?? [] as $media) { if ( ( $media["type"] ?? "" )==="image" ) {
if (($media['type'] ?? '') === 'image') { $filename = $this->downloadAndSaveImage($media, $this->yellow->system->get("coreServerDocument") . "media/images/");
$filename = $this->downloadAndSaveImage($media, $config->get("coreServerDocument") . 'media/images/'); if ( $filename ) {
if ($filename) {
$imageFilenames[] = $filename; $imageFilenames[] = $filename;
$imageAltTexts[] = $media['description'] ?? ''; $imageAltTexts[] = $media["description"] ?? "";
} }
} }
} }
$authorName = !empty($post["account"]["display_name"]) ? $post["account"]["display_name"] : $defaultAuthor;
$authorUrl = !empty($post["account"]["url"]) ? $post["account"]["url"] : "#";
$markdownContent = $this->generateMarkdown( $markdownContent = $this->generateMarkdown(
$title, $title, $titleSlug, $createdAt, $contentHtml,
$titleSlug, $authorName, $authorUrl,
$createdAt, $defaultAuthor, $defaultTag, $imageFilenames, $imageAltTexts, $statusSetting
$contentHtml,
$authorName,
$authorUrl,
$defaultAuthor,
$defaultTag,
$imageFilenames,
$imageAltTexts
); );
file_put_contents($fullPath, $markdownContent); file_put_contents($fullPath, $markdownContent);
chmod($fullPath, 0666);
echo "-> ERSTELLT [$index]: $fileName ($shortText)\n";
$postsCreated++; $postsCreated++;
} }
return $postsCreated; return $postsCreated;
} }
// Download and save image
private function downloadAndSaveImage($media, $dirPath) { private function downloadAndSaveImage($media, $dirPath) {
$imageUrl = $media['remote_url'] $imageUrl = $media['remote_url']
?? $media['url'] ?? $media['url']
@ -156,30 +199,37 @@ class YellowMastodonAPI {
?? ($media['meta']['original']['url'] ?? null) ?? ($media['meta']['original']['url'] ?? null)
?? ($media['meta']['small']['url'] ?? null); ?? ($media['meta']['small']['url'] ?? null);
if (empty($imageUrl)) { if (empty($imageUrl)) return false;
return false;
}
if (!is_dir($dirPath)) mkdir($dirPath, 0755, true); if (!is_dir($dirPath)) mkdir($dirPath, 0755, true);
$fileName = basename(parse_url($imageUrl, PHP_URL_PATH)); $fileName = basename(parse_url($imageUrl, PHP_URL_PATH));
if (!strpos($fileName, '.')) {
$fileName .= ".jpg";
}
$fullPath = $dirPath . $fileName; $fullPath = $dirPath . $fileName;
if (file_exists($fullPath)) return $fileName;
if (file_exists($fullPath) && filesize($fullPath) > 0) return $fileName;
$ch = curl_init($imageUrl); $ch = curl_init($imageUrl);
$headers = ["User-Agent: YellowMastodonAPI"]; $headers = ["User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) YellowMastodonAPI"];
$accessToken = $this->yellow->system->get("mastodonapiAccessToken"); $accessToken = $this->yellow->system->get("mastodonapiAccessToken");
if (!empty($accessToken)) { if (!empty($accessToken)) {
$headers[] = "Authorization: Bearer " . $accessToken; $headers[] = "Authorization: Bearer " . $accessToken;
} }
curl_setopt_array($ch, [ curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true, CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true, CURLOPT_FOLLOWLOCATION => true,
CURLOPT_TIMEOUT => 30, CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => $headers, CURLOPT_HTTPHEADER => $headers,
CURLOPT_SSL_VERIFYPEER => true, CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => 2, CURLOPT_SSL_VERIFYHOST => 0
]); ]);
$imgData = curl_exec($ch); $imgData = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch); curl_close($ch);
@ -192,105 +242,55 @@ class YellowMastodonAPI {
return $fileName; return $fileName;
} }
// Generate title from content
private function generateTitle($content) { private function generateTitle($content) {
$text = strip_tags($content); $text = trim(strip_tags($content));
$text = preg_replace('/https?:\/\/[^\s]+|#\w+/u', '', $text); $text = preg_replace("/https?:\/\/[^\s]+|#\w+/u", "", $text);
$text = preg_replace('/[^\p{L}\p{N}\s-]/u', '', $text); $words = explode(" ", $text);
$text = trim(preg_replace('/\s+/', ' ', $text)); return trim(mb_substr(implode(" ", array_slice($words, 0, 7)), 0, 100, "UTF-8")) ?: "Mastodon Post";
$words = explode(' ', $text);
return trim(mb_substr(implode(' ', array_slice($words, 0, 7)), 0, 100, 'UTF-8')) ?: "Mastodon Post";
} }
// Generate slug from title
private function generateTitleSlug($title) { private function generateTitleSlug($title) {
$slug = mb_strtolower($title, 'UTF-8'); $slug = mb_strtolower($title, "UTF-8");
$slug = str_replace(['ä','ö','ü','Ä','Ö','Ü','ß',' '], ['ae','oe','ue','ae','oe','ue','ss','-'], $slug); $slug = str_replace(array("ä","ö","ü","ß"," "), array("ae","oe","ue","ss","-"), $slug);
return trim(preg_replace('/[^a-z0-9-]+/', '', $slug), '-'); return trim(preg_replace("/[^a-z0-9-]+/", "", $slug), "-");
} }
private function generateMarkdown($title, $slug, $dateTime, $html, $origAuthor, $origUrl, $yellowAuthor, $yellowTag, $images = [], $alts = []) { // Generate markdown content
private function generateMarkdown($title, $slug, $dateTime, $html, $origAuthor, $origUrl, $yellowAuthor, $yellowTag, $images, $alts, $status) {
$date = new DateTime($dateTime); $date = new DateTime($dateTime);
$formattedDate = $date->format('Y-m-d'); $pub = $date->format("Y-m-d H:i:s");
$formattedTime = $date->format('H:i:s'); $content = trim(html_entity_decode(strip_tags(str_replace(array("<br>", "</p>"), array("\n", "</p>\n"), $html)), ENT_QUOTES | ENT_HTML5, "UTF-8"));
$content = str_replace(array("\n", "#"), array("\n> ", "&#35;"), $content);
$content = strip_tags($html); $imageMarkdown = "";
$content = html_entity_decode($content, ENT_QUOTES | ENT_HTML5, 'UTF-8'); $featuredImage = $featuredImageAlt = "";
foreach ( $images as $i => $filename ) {
$hashtagString = ''; $alt = isset($alts[$i]) ? htmlspecialchars($alts[$i], ENT_QUOTES) : "";
if (preg_match('/(\s*(#\w+))+$/u', $content, $matches)) { $imageMarkdown .= "\n<img src=\"/media/images/$filename\" alt=\"$alt\"/>\n";
$content = substr($content, 0, -strlen($matches[0])); if ( $i===0 ) {
if (preg_match_all('/#(\w+)/u', $matches[0], $tags)) { $featuredImage = "Image: $filename\n";
$safeHashtags = array_map(function($tag) { $featuredImageAlt = "ImageAlt: $alt\n";
return str_replace('#', '&num;', $tag);
}, $tags[0]);
$hashtagString = implode(' ', $safeHashtags);
} }
} }
$authorSafe = str_replace("@", "&#64;", $origAuthor);
$content = trim(preg_replace('/\s+/', ' ', $content)); return "---\n" .
"Title: $title\n" .
$imageMarkdown = ''; "TitleSlug: $slug\n" .
foreach ($images as $i => $filename) { "Published: $pub\n" .
$alt = isset($alts[$i]) ? htmlspecialchars($alts[$i], ENT_QUOTES) : ''; "Author: $yellowAuthor\n" .
$imageMarkdown .= "\n<img src=\"/media/images/" . $filename . "\" alt=\"" . $alt . "\"/>\n"; "Layout: blog\n" .
} "Tag: $yellowTag\n" .
"Status: $status\n" .
$featuredImage = ''; $featuredImage . $featuredImageAlt .
$featuredImageAlt = ''; "---\n\n" .
if (!empty($images)) { $imageMarkdown . "\n" .
$featuredImage = "Image: " . $images[0] . "\n"; "> " . $content . "\n>\n" .
if (isset($alts[0]) && !empty($alts[0])) { "> — <a target=\"_blank\" href=\"$origUrl\">$authorSafe</a>";
$featuredImageAlt = "ImageAlt: " . htmlspecialchars($alts[0], ENT_QUOTES) . "\n";
}
}
$htmlSafeAuthorName = str_replace('@', '&#64;', $origAuthor);
$blockquote = "> \"$content\"";
if (!empty($hashtagString)) {
$blockquote .= "\n>\n> " . $hashtagString;
}
$blockquote .= "\n>\n> — <a target=\"_blank\" href=\"$origUrl\">$htmlSafeAuthorName</a>";
return <<<MD
---
Title: $title
TitleSlug: $slug
Published: $formattedDate $formattedTime
Author: $yellowAuthor
Layout: blog
Tag: $yellowTag
$featuredImage$featuredImageAlt---
$imageMarkdown
$blockquote
MD;
} }
private function getYellowConfig() { // Return status file path
return $this->yellow ? $this->yellow->system : null; private function getStatusFile() {
} return $this->yellow->system->get("coreWorkerDirectory") . "mastodonapi.status";
private function sendResponse($message, $statusCode = 200) {
if (!headers_sent()) {
header("HTTP/1.1 $statusCode");
header("Content-Type: text/html; charset=UTF-8");
}
// Basis-URL aus der aktuellen Anfrage bestimmen
$fullUrl = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http")
. "://{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}";
// Trigger-Pfad aus der Yellow-Konfiguration holen
$triggerPath = $this->yellow->system->get("mastodonapiTriggerPath");
// Ziel-URL: Alles vor dem Trigger-Pfad abschneiden
$redirectUrl = str_replace($triggerPath, "/", $fullUrl);
echo "<!DOCTYPE html><html><head>";
echo "<meta http-equiv='refresh' content='5;url={$redirectUrl}'>";
echo "<title>Mastodon/GoToSocial API</title></head><body>";
echo "<p>" . htmlspecialchars($message) . "</p>";
echo "<p>You will be redirected in 5 seconds...</p>";
echo "</body></html>";
exit;
} }
} }

1
mastodonapi.status Normal file
View file

@ -0,0 +1 @@
0000000000

52
readme-de.md Normal file
View file

@ -0,0 +1,52 @@
<p align="right"><a href="https://git.thepipes.ch/simon/yellow-mastodonapi/src/branch/main/readme-de.md">Deutsch</a> &nbsp; <a href="https://git.thepipes.ch/simon/yellow-mastodonapi/src/branch/main/readme.md">English</a></p>
# Mastodonapi 0.9.9
Importiere deine Toots in deinen Blog. Getestet mit <a href="https://comam.es/what-is-snac">Snac</a>.
## Installation
<a href="https://git.thepipes.ch/simon/yellow-mastodonapi/archive/main.zip">Lade die ZIP-Datei herunter</a> und kopiere sie in deinen system/extensions Ordner. <a target="blank_" href="https://github.com/annaesvensson/yellow-update">Erfahre mehr über Erweiterungen</a>.
## Funktionsweise
Das Plugin arbeitet vollautomatisch. Es prüft im Hintergrund regelmäßig, ob neue Beiträge vorhanden sind.
Wenn du die Seite besuchst, fragt es deine Mastodon-API ab und erstellt automatisch Blog-Beiträge aus deinen Toots. Optional kannst du einen #Hashtag angeben, um nur bestimmte Beiträge zu importieren.
Es gibt drei Möglichkeiten, den Import auszulösen:
1. **Automatisch (Lazy Cron):** Sobald ein Besucher deine Website aufruft, prüft das Plugin, ob das Update-Intervall abgelaufen ist und lädt bei Bedarf neue Toots.
2. **Über das Terminal:** Du kannst den Import manuell auf dem Server starten mit: php yellow.php mastodonapi
3. **Über den System-Cronjob:** Falls dein Host Cronjobs unterstützt, kannst du den Befehl php yellow.php mastodonapi regelmäßig ausführen lassen (z. B. alle 30 Minuten).
## Einstellungen
Alle Einstellungen befinden sich in `system/extensions/yellow-system.ini`:
`MastodonapiInstanceUrl` = deine Mastodon Instanz-URL (z. B. https://mastodon.social)
`MastodonapiAccountId` = deine Mastodon User-ID (numerisch, z. B. 1234567890)
*Finde die ID eines Snac oder Mastodon Accounts: Gib "https://DEINE_INSTANZ_URL/api/v1/accounts/lookup?acct=PROFILNAME" in deinen Browser ein.*
*Finde die ID eines GoToSocial-Accounts <a href="https://git.thepipes.ch/simon/yellow-mastodonapi/src/branch/main/help-de.md">(siehe hier)</a>*
`MastodonapiAccessToken` = optional für einen Mastodon-Account, zwingend für einen GoToSocial-Account <a href="https://git.thepipes.ch/simon/yellow-mastodonapi/src/branch/main/help-de.md">(Wie komme ich zu einem Token?)</a>
`MastodonapiUpdateInterval` = Zeitintervall zwischen automatischen Updates in Minuten (Standard: 30)
`MastodonapiLimit` = Anzahl der Toots, die pro Durchgang abgerufen werden (Standard: 20)
`MastodonapiHashtag` = leer lassen für alle Beiträge; oder mit #hashtag filtern
`MastodonapiAuthor` = Name, unter dem die Blog-Beiträge erscheinen sollen
`MastodonapiTag` = Tag für die Blog-Beiträge (Standard: Fediverse)
`MastodonapiFolder` = Pfad zum Blog-Ordner (Standard: content/2-blog/)
`MastodonapiMaxAge` = Alter der Toots in Stunden, die noch importiert werden sollen. 0 = alle verfügbaren Toots
`MastodonapiStatus` = Seitenstatus, Standardwert ist public
Die folgenden Status-Werte werden unterstützt:
`public` = Seite ist eine normale Seite
`draft` = Seite ist nicht sichtbar, Benutzer muss eingeloggt sein, erfordert die <a target="blank_" href="https://github.com/annaesvensson/yellow-draft">Draft-Erweiterung</a>
`unlisted` = Seite ist nicht sichtbar, kann aber mit dem richtigen Link aufgerufen werden
## Entwickler
Simon Rohr
*Fediverse: <a href="https://snac.thepipes.ch/simon">@simon@snac.thepipes.ch</a>*

View file

@ -1,42 +0,0 @@
<p align="right"><a href="https://codeberg.org/simonpipe/yellow-mastodonapi/src/branch/main/readme.md">Deutsch</a> &nbsp; <a href="https://codeberg.org/simonpipe/yellow-mastodonapi/src/branch/main/readme-en.md">English</a></p>
# MastodonAPI
A plugin to import your public Toots via the Mastodon API into your Yellow Blog. The plugin works with Mastodon and with GoToSocial.
## Installation
1. Download the ZIP file
2. Copy it into the `/system/extensions` directory
3. Reload your website the plugin is now installed
## Usage
The plugin is triggered via a custom **webhook**.
When the webhook is called, it fetches your Toots from the Mastodon API and creates blog posts from them.
Optionally, you can specify a **#hashtag** to import only matching posts.
## Settings
All settings are in `system/extensions/yellow-system.ini`:
- **MastodonapiInstanceUrl** your Mastodon instance URL (e.g. `https://mastodon.social`)
- **MastodonapiAccountId** - your Mastodon user ID (numeric, e.g. 1234567890)
- Find the ID of a Mastodon account: Enter "https://YOUR_INSTANCE_URL/api/v1/accounts/lookup?acct=PROFILNAME" in your browser.
- Find the ID of a GoToSocial account <a href="https://codeberg.org/simonpipe/yellow-mastodonapi/src/branch/main/help-gotoso-en.md">(see here)</a>
- **MastodonapiAccessToken**
- Optional for a Mastodon account
- Mandatory for a GoToSocial account <a href="https://codeberg.org/simonpipe/yellow-mastodonapi/src/branch/main/help-gotoso-en.md">(see here)</a>
- **MastodonapiLimit** - Default value is 20
- **MastodonapiHashtag** leave empty to import all public posts; set to `#hashtag` to import only matching posts
- **MastodonapiAuthor** author name to use for imported blog posts
- **MastodonapiTag** tag to assign to imported blog posts
- **MastodonapiFolder** path to your blog folder (e.g. `content/1-blog/`)
- **MastodonapiTriggerPath** webhook path, e.g. `/mastodonapi-webhook-CHANGE_THIS_SECRET_KEY`
*(Be sure to change it! Anyone with this link can trigger the plugin.)*
💡 You can also call the webhook via a cron job to run the plugin automatically (e.g., every hour).
## Developer
Simon Pipe

View file

@ -1,42 +1,52 @@
<p align="right"><a href="https://codeberg.org/simonpipe/yellow-mastodonapi/src/branch/main/readme.md">Deutsch</a> &nbsp; <a href="https://codeberg.org/simonpipe/yellow-mastodonapi/src/branch/main/readme-en.md">English</a></p> <p align="right"><a href="https://git.thepipes.ch/simon/yellow-mastodonapi/src/branch/main/readme-de.md">Deutsch</a> &nbsp; <a href="https://git.thepipes.ch/simon/yellow-mastodonapi/src/branch/main/readme.md">English</a></p>
# MastodonAPI # Mastodonapi 0.9.9
Ein Plug-in, um deine öffentlichen Toots via Mastodon-API in deinen Yellow Blog zu importieren. Das Plugin funktiert mit Mastodon und mit GoToSocial. Import your toots into your blog. Tested with <a href="https://comam.es/what-is-snac">Snac</a>.
## Installation ## Installation
1. ZIP-Datei herunterladen <a href="https://git.thepipes.ch/simon/yellow-mastodonapi/archive/main.zip">Download ZIP file</a> and copy it into your `system/extensions` folder. <a target="blank_" href="https://github.com/annaesvensson/yellow-update">Learn more about extensions</a>.
2. In das Verzeichnis `/system/extensions` kopieren
3. Deine Website neu laden das Plug-in ist nun installiert
## Benutzung ## How to
Das Plug-in wird über einen individuellen **Webhook** aufgerufen. The plugin works fully automatically. It regularly checks in the background if there are new posts.
Beim Aufruf fragt es deine Mastodon-API ab und erstellt aus deinen Toots automatisch Blogbeiträge.
Optional kannst du einen **#Hashtag** angeben, um nur bestimmte Beiträge zu importieren.
## Einstellungen When you visit the site, it queries your Mastodon API and automatically creates blog posts from your Toots. Optionally, you can specify a #Hashtag to import only certain posts.
Alle Einstellungen findest du in `system/extensions/yellow-system.ini`: There are three ways to trigger the import:
- **MastodonapiInstanceUrl** URL deiner Mastodon-Instanz (z. B. `https://mastodon.social`) 1. **Automatic (Lazy Cron):** As soon as a visitor accesses your website, the plugin checks if the update interval has expired and loads new Toots if necessary.
- **MastodonapiAccountId** deine Mastodon-User-ID (numerisch, z. B. `1234567890`) 2. **From the terminal:** You can manually start the import on the server with: `php yellow.php mastodonapi`
- ID bei einem Mastodon-Account finden: Gib im Browser "https://DEINE_INSTANZ_URL/api/v1/accounts/lookup?acct=PROFILNAME" ein. 3. **From the system cronjob:** If your host supports cronjobs, you can have the command `php yellow.php mastodonapi` run regularly (e.g. every 30 minutes).
- ID bei einem GoToSocial-Account finden <a href="https://codeberg.org/simonpipe/yellow-mastodonapi/src/branch/main/help-gotoso-de.md">(siehe hier)</a>
- **MastodonapiAccessToken**
- Bei einem Mastodon-Account optional
- Bei einem GoToSocial-Account pflicht <a href="https://codeberg.org/simonpipe/yellow-mastodonapi/src/branch/main/help-gotoso-de.md">(siehe hier)</a>
- **MastodonapiLimit** - Standartwert ist 20
- **MastodonapiHashtag** leer lassen = alle öffentlichen Beiträge importieren; mit `#hashtag` = nur Beiträge mit diesem Tag
- **MastodonapiAuthor** Name, unter dem die Blogposts erscheinen sollen
- **MastodonapiTag** Tag, mit dem die Blogposts im Blog versehen werden
- **MastodonapiFolder** Pfad zum Blog-Ordner (z. B. `content/1-blog/`)
- **MastodonapiTriggerPath** Webhook-Pfad, z. B. `/mastodonapi-webhook-CHANGE_THIS_SECRET_KEY`
- Unbedingt anpassen! Wer diesen Link kennt, kann das Plug-in starten.
💡 Du kannst den Webhook auch per Cronjob regelmäßig aufrufen (z. B. stündlich). ## Settings
## Entwickler All settings are in `system/extensions/yellow-system.ini`:
Simon Pipe `MastodonapiInstanceUrl` = your Mastodon instance URL (e.g. https://mastodon.social)
`MastodonapiAccountId` = your Mastodon user ID (numeric, e.g. 1234567890)
*Find the ID of a Snac or Mastodon account: Enter "https://YOUR_INSTANCE_URL/api/v1/accounts/lookup?acct=PROFILNAME" in your browser.*
*Find the ID of a GoToSocial account <a href="https://git.thepipes.ch/simon/yellow-mastodonapi/src/branch/main/help-en.md">(see here)</a>*
`MastodonapiAccessToken` = optional for a Mastodon account, mandatory for a GoToSocial account <a href="https://git.thepipes.ch/simon/yellow-mastodonapi/src/branch/main/help-en.md">(How do I get a token?)</a>
`MastodonapiUpdateInterval` = time interval between automatic updates in minutes (default: 30)
`MastodonapiLimit` = number of Toots retrieved per run (default: 20)
`MastodonapiHashtag` = leave blank for all posts; or filter with #hashtag
`MastodonapiAuthor` = name under which the blog posts should appear
`MastodonapiTag` = tag for the blog posts (default: Fediverse)
`MastodonapiFolder` = path to the blog folder (default: content/2-blog/)
`MastodonapiMaxAge` = age of Toots in hours that should still be imported. 0 = all available Toots
`MastodonapiStatus` = page status, default value is public
The following status values are supported:
`public` = page is a normal page
`draft` = page is not visible, user needs to log in, requires <a target="blank_" href="https://github.com/annaesvensson/yellow-draft">draft extension</a>
`unlisted` = page is not visible, but can be accessed with the correct link
## Developer
Simon Rohr
*Fediverse: <a href="https://snac.thepipes.ch/simon">@simon@snac.thepipes.ch</a>*