{"id":13862482,"url":"https://github.com/fasheng/elfeed-protocol","last_synced_at":"2025-07-14T12:30:53.359Z","repository":{"id":21096964,"uuid":"91764226","full_name":"fasheng/elfeed-protocol","owner":"fasheng","description":"Provide extra protocols to make like Fever, NewsBlur, Nextcloud/ownCloud News and Tiny Tiny RSS work with elfeed","archived":false,"fork":false,"pushed_at":"2024-08-22T08:05:56.000Z","size":364,"stargazers_count":95,"open_issues_count":2,"forks_count":18,"subscribers_count":7,"default_branch":"master","last_synced_at":"2024-08-22T09:27:00.194Z","etag":null,"topics":["elfeed","emacs-lisp","emacs-packages","fever","newsblur","nextcloud-news","owncloud-news","rss","ttrss"],"latest_commit_sha":null,"homepage":"","language":"Emacs Lisp","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fasheng.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-05-19T04:05:38.000Z","updated_at":"2024-08-22T08:05:59.000Z","dependencies_parsed_at":"2024-08-05T06:05:20.696Z","dependency_job_id":"efee9476-cb08-4cd7-b223-df69a4e57b16","html_url":"https://github.com/fasheng/elfeed-protocol","commit_stats":null,"previous_names":[],"tags_count":33,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fasheng%2Felfeed-protocol","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fasheng%2Felfeed-protocol/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fasheng%2Felfeed-protocol/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fasheng%2Felfeed-protocol/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fasheng","download_url":"https://codeload.github.com/fasheng/elfeed-protocol/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225974480,"owners_count":17553959,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["elfeed","emacs-lisp","emacs-packages","fever","newsblur","nextcloud-news","owncloud-news","rss","ttrss"],"created_at":"2024-08-05T06:01:45.469Z","updated_at":"2024-11-22T22:31:11.735Z","avatar_url":"https://github.com/fasheng.png","language":"Emacs Lisp","funding_links":[],"categories":["Emacs Lisp"],"sub_categories":[],"readme":"\u003e [!IMPORTANT]\n\u003e Since version `0.9.0` , elfeed-protocol use variable\n\u003e `elfeed-protocol-feeds` instead of `elfeed-feeds` to fix conflict\n\u003e issues to extensions that modify or require `elfeed-feeds`.  And\n\u003e elfeed-protocol could work together with elfeed-org and\n\u003e elfeed-autotag without any aditional setup now.\n\nelfeed-protocol\n==============\n[![MELPA](http://melpa.org/packages/elfeed-protocol-badge.svg)](http://melpa.org/#/elfeed-protocol) [![MELPA Stable](https://stable.melpa.org/packages/elfeed-protocol-badge.svg)](https://stable.melpa.org/#/elfeed-protocol)\n\nProvide extra protocols to make self-hosting RSS readers work\nwith [elfeed](https://github.com/skeeto/elfeed),\nincluding\n[Fever](https://feedafever.com/api),\n[NewsBlur](https://newsblur.com/),\n[Nextcloud/ownCloud News](https://nextcloud.com/),\n[Tiny Tiny RSS](https://tt-rss.org/fox/tt-rss) and even more.\n\n# Installation through MELPA\n\n```\n;; Install through package manager\nM-x package-install \u003cENTER\u003e\nelfeed-protocol \u003cENTER\u003e\n```\n\n# Initialization\nSetup elfeed-protocol, then switch to search view and and press G to update entries:\n\n```emacs-lisp\n;; curl recommend\n(setq elfeed-use-curl t)\n(elfeed-set-timeout 36000)\n(setq elfeed-curl-extra-arguments '(\"--insecure\")) ;necessary for https without a trust certificate\n\n;; setup feeds\n(setq elfeed-protocol-feeds '((\"owncloud+https://user@myhost.com\"\n                               :password \"my-password\")))\n\n;; enable elfeed-protocol\n(setq elfeed-protocol-enabled-protocols '(fever newsblur owncloud ttrss))\n(elfeed-protocol-enable)\n```\n\n# Protocol Details\n\n## fever (Fever)\n1. Fetch articles with the entry ID one by one by default. For some\n   service that don't provide valid entry ID like FressRSS, just set\n   `elfeed-protocol-fever-update-unread-only` to t as a workaround\n1. Fetch remote category as tag\n1. Support sync unread, starred(saved) tags, the starred tag name\n   defined in `elfeed-protocol-fever-star-tag` which default value is\n   `star`\n1. Support multiple fetching methods:\n   - `elfeed-protocol-fever-update-older`\n   - `elfeed-protocol-fever-update-star`\n\n**NOTE**: Many self-hosted RSS server provide Fever API, and user must\nprovide the URL manually. Here is a list of Fever API URLs I collected\nfor some popular RSS servers:\n\n- Tiny Tiny RSS's Fever plugin\n  ```\n  https://your-ttrss-server/plugins/fever/\n  ```\n- FreshRSS\n  ```\n  https://your-freshrss-server/api/fever.php\n  ```\n- miniflux\n  ```\n  https://your-miniflux-server/fever/\n  ```\n\nExample:\n```emacs-lisp\n(setq elfeed-protocol-fever-update-unread-only nil)\n(setq elfeed-protocol-fever-fetch-category-as-tag t)\n(setq elfeed-protocol-feeds '((\"fever+https://user@myhost.com\"\n                               :api-url \"https://myhost.com/plugins/fever/\"\n                               :password \"my-password\")))\n```\n\n## newsblur (NewsBlur)\n1. Fetch articles from recent pages\n1. Fetch articles for special feed\n1. Fetch remote category as tag\n1. Fetch tags in remote\n1. Support sync unread, starred(saved) tags, the starred tag name\n   defined in `elfeed-protocol-ttrss-star-tag` which default value is\n   `star`\n\n**NOTE**: A file for storing session cookies has to be specified via\n`elfeed-curl-extra-arguments` like in the following example.\n\nExample:\n```emacs-lisp\n(setq elfeed-protocol-newsblur-maxpages 20)\n(setq elfeed-protocol-newsblur-fetch-tags t)\n(setq elfeed-protocol-newsblur-fetch-category-as-tag t)\n(setq elfeed-protocol-newsblur-sub-category-separator \"/\")\n(setq elfeed-curl-extra-arguments '(\"--cookie-jar\" \"/tmp/newsblur-cookie\"\n                                    \"--cookie\" \"/tmp/newsblur-cookie\"))\n(setq elfeed-protocol-feeds '((\"newsblur+https://user@newsblur.com\"\n                               :password \"my-password\")))\n```\n\n## owncloud (ownCloud News)\n1. Fetch articles with the modified time by default\n1. Fetch articles for special feed\n1. Fetch remote category as tag\n1. Support sync unread and starred tags, the starred tag name defined\n   in `elfeed-protocol-owncloud-star-tag` which default value is `star`. For\n   example, if user add `star` tag to one article, the star stat will\n   be sync to server, too\n1. Support multiple fetching methods:\n   - `elfeed-protocol-owncloud-update-since-timestamp`\n   - `elfeed-protocol-owncloud-update-since-id`\n   - `elfeed-protocol-owncloud-update-older`\n\nExample:\n```emacs-lisp\n(setq elfeed-protocol-owncloud-maxsize 1000)\n(setq elfeed-protocol-owncloud-update-with-modified-time t)\n(setq elfeed-protocol-owncloud-fetch-category-as-tag t)\n(setq elfeed-protocol-feeds '((\"owncloud+https://user@myhost.com\"\n                               :password \"my-password\")))\n```\n\n## ttrss (Tiny Tiny RSS, requires version: 1.7.6)\n1. Fetch articles by the entry ID\n1. Fetch articles for special feed\n1. Fetch remote category as tag\n1. Support sync unread, starred and published tags, the starred tag\n   name defined in `elfeed-protocol-ttrss-star-tag` which default\n   value is `star`, and the published tag name defined in\n   `elfeed-protocol-ttrss-publish-tag` which default value is\n   `publish`\n1. Support multiple fetching methods:\n   - `elfeed-protocol-ttrss-update-older`\n   - `elfeed-protocol-ttrss-update-star`\n\n**NOTE**: For Tiny Tiny RSS only allow fetch Maximize 200 entries each\ntime, so if your own much more starred entries, just run\n`elfeed-protocol-ttrss-update-star` manually to fetch them all\n\nExample:\n```emacs-lisp\n(setq elfeed-protocol-ttrss-maxsize 200) ; bigger than 200 is invalid\n(setq elfeed-protocol-ttrss-fetch-category-as-tag t)\n(setq elfeed-protocol-feeds '((\"ttrss+https://user@myhost.com\"\n                               :password \"my-password\")))\n```\n\n# Extra settings\n\n## All example formats for elfeed-protocol-feeds\n\n```emacs-lisp\n(setq elfeed-protocol-feeds '(\n                              ;; same format with elfeed-feeds\n                              \"http://foo/\"\n                              (\"http://baz/\" comic)\n\n                              ;; format 1\n                              \"owncloud+https://user:pass@myhost.com\"\n\n                              ;; format 2, for username or password with special characters\n                              (\"owncloud+https://user@domain.com@myhost.com\"\n                               :password \"password/with|special@characters:\")\n\n                              ;; format 3, for password in file\n                              (\"owncloud+https://user@myhost.com\"\n                               :password-file \"~/.password\")\n\n                              ;; format 4, for password in .authinfo,\n                              ;; ensure (auth-source-search :host \"myhost.com\" :port \"443\" :user \"user4\") exists\n                              (\"owncloud+https://user@myhost.com\"\n                               :use-authinfo t)\n\n                              ;; format 5, for password in gnome-keyring\n                              (\"owncloud+https://user@myhost.com\"\n                               :password (shell-command-to-string \"echo -n `secret-tool lookup attribute value`\"))\n\n                              ;; format 6, for password in pass(1), using password-store.el\n                              (\"owncloud+https://user@myhost.com\"\n                               :password (password-store-get \"owncloud/app-pass\"))\n\n                              ;; use autotags\n                              (\"owncloud+https://user@myhost.com\"\n                               :password \"password\"\n                               :autotags ((\"example.com\" comic)))))\n```\n\n## Work with feeds and autotags that defined in original elfeed-feeds\n\n```emacs-lisp\n(setq elfeed-feeds '(\"http://foo/\" (\"http://baz/\" comic)))\n(setq elfeed-protocol-feeds '((\"owncloud+https://user@myhost.com\"\n                               :password \"my-password\")))\n(setq elfeed-protocol-feeds (append elfeed-protocol-feeds elfeed-feeds))\n```\n\n## Work with elfeed-org and elfeed-autotag\n\nSince version `0.9.0`, elfeed-protocol could work together with\nelfeed-org and elfeed-autotag without any aditional setup.\n\n## Work with elfeed-summary\n\nTo fix `0 / 0` zero count issue for all feeds, just active the\nfollowing advice for `rmh-elfeed-org-export-feed`:\n\n```emacs-lisp\n(defun elfeed-protocol-advice-rmh-elfeed-org-export-feed (headline)\n \"Advice for `rmh-elfeed-org-export-feed', add elfeed-protocol ID as suffix for each feed.\"\n  (let* ((url (car headline))\n         (proto-id (car (elfeed-protocol-feed-list))))\n    (when proto-id\n      (setcar headline (elfeed-protocol-format-subfeed-id proto-id url)))))\n(advice-add 'rmh-elfeed-org-export-feed :before #'elfeed-protocol-advice-rmh-elfeed-org-export-feed)\n```\n\nBesides, don't use `elfeed-summary-update` to fetach articles,\nuse `elfeed-update` instead, and press `r` to refresh UI manually:\n```emacs-lisp\n(define-key elfeed-summary-mode-map (kbd \"R\") #'elfeed-update)\n```\n\n# Run Unit-Tests\n\nInstall `cask` system package firstly, and then run following commands\n\n```shell\nmake init\nmake test\nmake checkdoc\nmake elint\nmake package-lint\n```\n\n# Deploy Services for Testing\n## Nextcloud/ownCloud News\n1.  Fetch docker image and run it\n\n        docker pull nextcloud\n        docker run --rm -p 80:80 nextcloud\n\n2.  Open \u003chttp://127.0.0.1\u003e in browser to setup Nextcloud\n    1.  Create admin user and select database to SQLite, then press \"Finish setup\"\n    2.  Press left top popup menu and select \"+Apps\", select\n        \"Multimedia\", and enable the \"News\" app\n    3.  Press left top popup menu and switch to \"News\" app, then\n        subscribe some feeds\n\n3.  Setup `elfeed-protocol`\n\n    ```emacs-lisp\n    (setq elfeed-protocol-feeds '(\"owncloud+http://\u003cadmin\u003e:\u003cpassword\u003e@localhost\"))\n    ```\n\n## Tiny Tiny RSS\n1.  Fetch related docker images and run them\n\n        docker pull clue/ttrss\n        docker pull nornagon/postgres\n        docker run --rm -d --name ttrssdb nornagon/postgres\n        docker run --rm --link ttrssdb:db -p 80:80 clue/ttrss\n\n2.  Open \u003chttp://127.0.0.1\u003e in browser to setup Tiny Tiny RSS\n    1. Use the default `admin:password` authorization info to login\n    2. Enter \"Preferences\" page to enable \"Enable API access\" and save configuration\n\n3.  Setup `elfeed-protocol`\n\n    ```emacs-lisp\n    (setq elfeed-protocol-feeds '(\"ttrss+http://admin:password@localhost\"))\n    ```\n\n# Report Issues\n\nPlease collect logs in buffer `*elfeed-log*` with the following config\nbefore reporting issues:\n\n```emacs-lisp\n(setq elfeed-log-level 'debug)\n(toggle-debug-on-error)\n\n;; for more logs\n(setq elfeed-protocol-log-trace t)\n(setq elfeed-protocol-fever-maxsize 10)\n(setq elfeed-protocol-newsblur-maxpages 1)\n(setq elfeed-protocol-owncloud-maxsize 10)\n(setq elfeed-protocol-ttrss-maxsize 10)\n```\n\n# Q\u0026A\n\n1. When I run elfeed-update I get the error: `elfeed-protocol-feeds malformed, bad entry`\n\n   Don't forget to enable elfeed-protocol at first:\n   ```emacs-lisp\n   (elfeed-protocol-enable)\n   ```\n\n1. Not working if my password contains special characters like `@#$/:`.\n\n   Use format 2 instead in previous example for complex password:\n   ```emacs-lisp\n   ;; format 2, for password with special characters\n   (\"owncloud+https://user@myhost.com\"\n    :password \"password/with|special@characters:\")\n   ```\n\n1. How to fetch my older headlines in server?\n\n   `fever`, `owncloud` and `ttrss` protocol provide method to fetch\n   older headlines. And the update operations could not executed in\n   the same time, so `run-at-time` with some delays(for example 15s)\n   will help you:\n   ```emacs-lisp\n   (setq my-elfeed-update-timer\n         (run-at-time 15 15\n                      (lambda () (when (= elfeed-curl-queue-active 0)\n                                   (elfeed-protocol-ttrss-update-older \"ttrss+https://user@host\")))))\n   (cancel-timer my-elfeed-update-timer)\n   ```\n\n1. Why the articles still are unread even they were mark read in other client?\n\n   Well, only ownCloud News API support two-way synchronization for it\n   fetch articles with modified time. And other API only fetch\n   articles id by id. So your issue just the desired result~\n\n   However here is a workaround. For example fever, you could reset\n   the update mark so it will re-fetch the last 1000 articles in\n   following updates and will sync the read state:\n\n   ```emacs-lisp\n   (let* ((proto-id \"fever+https://user@miniflux-host\")\n          (last-id (elfeed-protocol-fever-get-update-mark proto-id 'update)))\n     (elfeed-protocol-fever-set-update-mark  proto-id 'update (- last-id 1000)))\n   ```\n\n   And Fever limit 50 max size for per request, so update timer may help you:\n\n   ```emacs-lisp\n   (run-at-time 300 300\n                (lambda () (when (= elfeed-curl-queue-active 0)\n                             (elfeed-update))))\n   ```\n\n   Or you could use `elfeed-untag-1` mark all selected articles as\n   read(will not call curl process) then execute\n   `elfeed-protocol-fever-reinit` fetch all unread articles:\n\n   ```emacs-lisp\n   (cl-loop for entry in (elfeed-search-selected)\n            do (elfeed-untag-1 entry 'unread))\n   ```\n\n   Hope helps.\n\n1. Sometimes emacs may be blocked if the parsing downloaded articles\n   is too large, for example \u003e50MB.\n\n   This is caused by the known emacs bug that CPU will be in high\n   usage if a text line is too long. There three methods to workaround\n   this:\n   1. Method 1, limit the download size, for example:\n\n          (setq elfeed-protocol-owncloud-maxsize 1000)\n\n   1. Method 2, for ownCloud, just update articles since special entry\n      ID instead the modified time, this could run multiple times to\n      keep up to date to avoid download too large entries once time\n\n          M-x elfeed-protocol-owncloud-update-since-id\n\n   1. Method 3, some protocol provide update method to reset the last\n      modified time to skip some data, for example:\n\n          M-x elfeed-protocol-owncloud-update-since-timestamp\n\n# Donation\n\n- BTC [3DMLQ8f4Ui5Adka9Y44MVM2cKT6yBVZdY5](https://www.blockchain.com/btc/address/3DMLQ8f4Ui5Adka9Y44MVM2cKT6yBVZdY5)\n- ETH [0x561c694EF2bf32C23759c4Abd7D132161DaE13F8](https://www.blockchain.com/eth/address/0x561c694EF2bf32C23759c4Abd7D132161DaE13F8)\n\n# License\n\nReleased under the terms of the GNU GPLv3+.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffasheng%2Felfeed-protocol","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffasheng%2Felfeed-protocol","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffasheng%2Felfeed-protocol/lists"}