Sync read/marked status of entries between elfeed and tt-rss. Supports elfeed-summary.
DISCLAIMER: It’s still an alpha version of the package, so you may want to backup your elfeed index and tt-rss database.
The project consists of the tt-rss plugin and the Emacs package.
If you are using the tt-rss docker setup, the steps are as follows. Change them accordingly if you are not.
- Mount the
/var/www/html
directory from the container somewhere to the filesystem as described here. - Put the repository to the
tt-rss/plugins.local/elfeed_sync
folder:cd ./html/tt-rss/plugins.local/ git clone https://github.com/SqrtMinusOne/elfeed-sync.git elfeed_sync
- Add
elfeed_sync
to theTTRSS_PLUGINS
environment variable.TTRSS_PLUGINS=auth_internal, auth_remote, nginx_xaccel, elfeed_sync
- Allow larger request body sizes in nginx. Add the following to the
server
directive:client_max_body_size 10M;
For me, the sync payload is around 3M.
- Increase the read timeout in nginx. Add the following to the php location directive:
fastcgi_read_timeout 600;
Syncing the entries is usually pretty fast, but the first feed sync takes a while.
- Then restart tt-rss. Check if the plugin appears in the Preferences > Plugins section.
- Enable “Allows accessing this account through the API” in the Preferences > Preferences. You also may want to disable “Purge unread articles”, because elfeed doesn’t do that.
Install the Emacs package however you normally install packages, I prefer use-package and straight.el. Make sure to enable elfeed-sync-mode
.
(use-package elfeed-sync
:straight (:host github :repo "SqrtMinusOne/elfeed-sync")
:after elfeed
:config
(elfeed-sync-mode))
Then set up the following variables:
elfeed-sync-tt-rss-instance
- point that to your tt-rss instance, e.g.https://example.com/tt-rss
(No trailing slash)
elfeed-sync-tt-rss-login
elfeed-sync-tt-rss-password
elfeed-sync-unread-tag
- elfeed tag to map to read status in tt-rss.unread
by default.elfeed-sync-marked-tag
- elfeed tag to map to marked status in tt-rss.later
by default.
The first thing you probably want to do is to sync the feed list.
It makes little sense to sync tt-rss feeds to elfeed, because people often use projects like elfeed-org. But it’s possible to sync elfeed feeds to tt-rss.
The function M-x elfeed-sync-feeds
does exactly that. If you have elfeed-summary installed and tt-rss categories enabled, the function will recreate the elfeed-summary tree in tt-rss.
The first run of the function takes a while because tt-rss has to fetch the feed at the moment of the first subscription. Which is why increasing the timeout may be necessary.
However, running the function multiple times until it succeeds should also work.
To sync the entry list, run M-x elfeed-sync
. The sync usually takes a couple of seconds.
The sync finishes at the “Sync complete!” message. Check the *elfeed-log*
buffer for statistics.
Occasionally, some entries do not match. Here are the possible cases:
- Entry exists in the elfeed database, but not in tt-rss.
Run
M-x elfeed-sync-search-missing
to display such entries. - Entry exists in the tt-rss database, but not in elfeed:
- Entry appeared in the feed after the last
elfeed-update
. RunM-x elfeed-update
and thenM-x elfeed-sync
. - Entry appeared and disappeared in the feed after the last
elfeed-update
. Such an entry will never get to the elfeed database. If you want to, runM-x elfeed-sync
and thenM-x elfeed-sync-read-ttrss-missing
to mark all such entries as read.
- Entry appeared in the feed after the last
- Entry appeared in the feed before
elfeed-sync-look-back
. Such an entry will never be matched. This is an inconvenience if you have just set up tt-rss, it fetched old entries from the feeds and such entries remain permanently unread because they are untouched by theM-x elfeed-sync
. To mark such entries as read, runM-x elfeed-sync-read-ttrss-old
.
The heavy-lifting is done on the elisp side because I ran into strange performance issues with associative arrays in PHP.
Check the elfeed-sync--do-sync
function for the description of the synchronization algorithm. The tl;dr is to download all entries from tt-rss and match each entry against the elfeed database. In the case of discrepancy update whichever entry has the lower priority.