nhoizey / github-action-feed-to-mastodon

A GitHub Action to create toots on Mastodon from a JSON Feed
MIT License
22 stars 3 forks source link

GitHub Action: Any feed to Mastodon

GitHub stars Follow @nhoizey@mamot.fr

A GitHub Action that creates messages (toots) on your Mastodon account from a RSS/Atom/JSON feed's items.

This should be a simple way to POSSE — Publish (on your) Own Site, Syndicate Elsewhere — content from your blog to your Mastodon account.

[!NOTE] It currently supports JSON Feed, with support for RSS and Atom planned.

Example usage

I recommend to try first with an action requiring a manual action with the workflow_dispatch event, and set testMode: true, to test the settings.

Here's a minimal version, with only required inputs:

name: Create toots from feed items
on:
  workflow_dispatch:

jobs:
  Feed2Mastodon:
    runs-on: ubuntu-latest

    steps:
      # Checkout the repository to restore previous cache
      - name: Checkout
        uses: actions/checkout@v3

      # Look for new toots to create from items in the JSON feed
      - name: Feed to Mastodon
        uses: nhoizey/github-action-feed-to-mastodon@v2
        with:
          feedUrl: "https://example.com/feed.json"
          mastodonInstance: "https://mastodon.social"
          mastodonToken: ${{ secrets.MASTODON_TOKEN }}
          testMode: true

      # Make sure files are up to date if other commits have been pushed in the mean time
      - name: Pull any changes from Git
        run: git pull

      # Push changes in the cache files to the repository
      # See https://github.com/stefanzweifel/git-auto-commit-action#readme
      - name: Commit and push
        uses: stefanzweifel/git-auto-commit-action@v4

You can then enhance your action with the schedule event, for example to automate creation of a toot every Monday at 8am (Crontab Guru: https://crontab.guru/#0_8_*_*_1).

Replace:

on:
  workflow_dispatch:

With:

on:
  schedule:
    - cron: "0 8 * * 1"

When everything works perfectly, you can remove the testMode input, or set it to false.

Settings ("Inputs" in GitHub Action language)

There are 3 required inputs, used in the examples above, but also some optional inputs — with default values — to fine tune when and how toots are created:

input required? default description
feedUrl Yes URL of the feed to fetch
mastodonInstance Yes The root URL of the Mastodon instance where the toot should be created
mastodonToken Yes Your access token for the Mastodon API, get it from /settings/applications/new on your instance, and use an encrypted secrets to hide it
nbTootsPerItem No 1 Number of toots that can be created from the same item
itemChoiceStrategy No "random" Strategy to choose the item to toot when multiple are available in the list of least tooted items. The following values can be used: "random", "newest" (the most recent item), "oldest" (the oldest item)
globalDelayToots No 1440 (1 day) Delay (in minutes) between any toot from this feed
delayTootsSameItem No 129600 (90 days) Delay (in minutes) between any toot for the same item from this feed (used only if nbTootsPerItem > 1)
cacheDirectory No "cache" Path to the directory where cache files are stored
cacheFile No "feed-to-mastodon.json" Name of the JSON file caching data from the feed and toots
cacheTimestampFile No "feed-to-mastodon-timestamp.json" Name of the JSON file caching the timestamp of the last toot
ignoreFirstRun No true Items collected when the feed is fetched the first time won't be used as toots. This aims to prevent flooding Mastodon, as these items may have already been shared another way, manual or automated. If nbTootsPerItem is set to more than 1, only the first toot is ignored.
testMode No false Activates a mode for tests, where mentions are removed (@ replaced by $)
tootVisibility No "public" Toot visibility. The following values can be used: "public" (visible for all), "unlisted" (opted-out of discovery features), "private" (followers only), "direct" (visible only for mentioned users)
logFeedItemContent No false Log the content of the feed item that will be used to create the toot
instanceType No "mastodon" Type of instance, to adapt API calls (values: "mastodon" or "pixelfed")

Outputs

The action sets an output that you can use in following steps of your own action:

output description
tootUrl URL of the toot that was created

Cache usage

There are 2 JSON files in the cache:

Warning Make sure to have steps "Checkout", "Pull" and "Commit and push" in your action, this is how the cache files are synchronized each time the action runs.

The cache prevents creating the same toot multiple times if you set nbTootsPerItem to 1 (which is the default).

If you set nbTootsPerItem to a value larger than 1, the action will chose an item among the ones that have the least toots. The choice is based on the itemChoiceStrategy input.

[!TIP] Once issue #7 fixed, you'll be able to set nbTootsPerItem to -1 to remove any limit.

In particular, any new item in the feed won't have existing toots, so it will be tooted first when the action runs, if all previous items already have at least one toot.

[!CAUTION] If you use this action in multiple actions in the same repository, make sure you set different cache files.

[!TIP] Once issue #9 fixed, the cache file default name will be based on the feed's URL.

Required and optional feed content

JSON Feed

The properties this action uses from a JSON Feed item are:

Here's an example JSON feed with one single item, with only the properties that are either required by the JSON Feed 1.1 specification, or useful for this action:

{
  "version": "https://jsonfeed.org/version/1.1",
  "title": "Photos - Nicolas Hoizey",
  "items": [
    {
      "id": "https://nicolas-hoizey.photo/galleries/travels/europe/the-netherlands/arnhem/the-blacksmith/",
      "url": "https://nicolas-hoizey.photo/galleries/travels/europe/the-netherlands/arnhem/the-blacksmith/",
      "language": "en",
      "date_published": "2014-07-12T13:07:00Z",
      "content_text": "“The Blacksmith”\n\nShot in the amazing Openluchtmuseum (Open Air Museum) near Arnhem, in The Netherlands.\n\n📅 12th July 2014\n\n📸 Sony RX100 Mark III\n🎞️ ISO 3200, ƒ/2.8, 1/80s\n\n#Travels #Europe #TheNetherlands #Arnhem #Photo #Photography #PhotoOfTheDay #DailyPhoto\n\n🔎 https://nicolas-hoizey.photo/galleries/travels/europe/the-netherlands/arnhem/the-blacksmith/",
      "attachments": [
        {
          "url": "https://nicolas-hoizey.photo/photos/the-blacksmith/small.jpg",
          "mime_type": "image/jpeg",
          "title": "The blacksmith",
          "_alt_text": "A blacksmith in his workshop, working with his anvil"
        }
      ]
    }
  ]
}

Usage with Pixelfed

Pixelfed v1 API is based on the mastodon v1 API, with a few differences listed in the documentation

An (undocumentated) difference is that the visibility option is not supported, and trying to create a toot with a visibility option generates an error.

If you want to use this action with a Pixelfed instance, you have to set the optional instanceType input to "pixelfed".

Usage with WordPress

Read the dedicated docs.

Debugging

If you want to see what's happening in the action, you can enable additional debug logs: Enabling step debug logging

License

The scripts and documentation in this project are released under the MIT License.