An RSS feed aggregator that notifies you of new posts via email.

Overview

Rss2Email

Build & Tests Crates.io docs.rs Minimum Supported Rust Version GitHub milestone

A small program capable of aggregating content from multiple RSS/Atom feeds and mailing them to you in a practical summary email. Keep track of your favorite blogs that don't feature an update newsletter or similar service.

Example

Dependencies

You'll need Rust or Docker installed to compile this software.

Installation

Each release automatically publishes Docker images for x86 and arm on DockerHub. Note that these can only run on AWS Lambda. If you want to run them elsewhere through Docker, read here.

Alternatively, you can build this from source. Clone this repository and run:

cargo build --release

Check out the build from source section of the wiki for more information.

Configuration

Rss2email requires some environment variables to work. These can be provided either in your shell or as entries in a .env file.

  • EMAIL_ADDRESS: the mail address you will receive the feed content

  • DAYS: this value indicates up to how many days in the past we go to search for entries

  • FEEDS: a list of semicolon-separated feed URLs.
    eg: "https://blog.rust-lang.org/feed.xml;https://www.linux.org/articles/index.rss"

  • EMAIL (optional, defaults to SendGrid): Which provider to use to send the email.
    Can be set to EMAIL_COMMAND as an alternative if you have mail or sendmail installed in your system

  • API_KEY (optional): Your SendGrid authentication key.

More details are available in the Running the code wiki section.

Usage

Running the code in debug mode won't send any emails and will instead output the generated HTML in the console.

cargo run

It is recommended to try this out first and make sure that all your feeds and config variables are correctly set up.

Running the project in release mode will send the emails

./target/release/Rss2email
# or
cargo run --release

Contributing

Thanks for considering contributing!

Read this.

Thanks to all Contributors!

Comments
  • Made download_blogs requests async

    Made download_blogs requests async

    Hello, I saw your message about issue #18 on Hacktoberfest's Discord. I have tried to address it, I have set tokio as a non optional dependency.

    Using this feeds.txt:

    https://antoniosbarotsis.github.io/index.xml
    https://blog.rust-lang.org/feed.xml
    https://blog.rust-lang.org/inside-rust/feed.xml
    https://github.blog/feed
    

    This is the output of hyperfine:

    • With the synchronous requests:

    image

    • New asynchronous requests:

    image

    Please feel free to correct anything, this is my first time working with async and tokio in rust.

    It would be helpful if you posted your feeds.txt, so i could test it more thoroughly. Thanks.

    hacktoberfest-accepted 
    opened by cantudo 58
  • feat: add performance investigation

    feat: add performance investigation

    closes #8

    details

    Implemented a benchmark for the map_to_html function, to do it, i moved the content from src/util.rs to src/lib.rs (see library crate)

    I also tried to add a benchmark the download_blogs function, but the 100 iterations would take a lot of time:

    Warning: Unable to complete 100 samples in 5.0s. You may wish to increase target time to 1603.1s, or reduce sample count to 10.
    Benchmarking map to html: Collecting 100 samples in estimated 1603.1 s (100 iterations)
    

    I can reduce the iterations or try to figure out another solution, what do you think fits better?

    hacktoberfest 
    opened by ddanielsantos 13
  • Added local `mail` command support

    Added local `mail` command support

    Greetings! Found your great project in Hacktoberfest discord: sorry for not contacting you first, I wanted to assemble a working example before proposing.

    I'll be glad if you could evaluate this implementation proposal, including the followings:

    • Implementation for running a local mail command, in case you're running the project where postfix or mailutils is configured

    Small refactors

    • Error/default handling for DAYS env variable.
    • EmailProviders has a tested path and should permit easier implementation of new backends

    Breaking changes

    • Trait function EmailProvider::send_email() no longer requires api_key parameter
    • EmailProviders is now implemented with TryFrom, since Provider setup might fail for missing configurations.

    Possible future improvements

    • Having a better parameterized interface as command line, using clap
    • Fail MailCommand creation when there is not an actual mail command available
    • Support other mail-providers at commandline ( sendmail, mutt, etc. )

    I'll be glad to hear your feedback, also I understand this might take a path that wasn't intended in the original design. Thanks you very much for your work.

    enhancement hacktoberfest 
    opened by giulio-Joshi 11
  • Writing tests [Rust]

    Writing tests [Rust]

    There are currently no tests present in the project. While it is very easy to test manually, automated tests are definitely quite handy.

    I'm interested in testing that downloading and parsing (separately) RSS feeds are working properly. There should be a way to define a list of feeds to be used in these tests.

    Feel free to make any additional tests!

    Adding automated code coverage reports would also be a very much welcome addition.

    hacktoberfest 
    opened by AntoniosBarotsis 9
  • Read `feeds` from environment variables [Rust]

    Read `feeds` from environment variables [Rust]

    Currently, the feeds are being read from a local text file here. This is a rather bad design choice as you might want to add new feeds quite often. It is especially annoying if you have deployed this as a docker image since you need to rebuild it (even though that is fast because of caching).

    A new function should be created that first attempts to read the feeds from an environment variable. If that is not found or is empty, it should try to read from the file as it is doing now.

    The format of the env variable contents is up for discussion but I feel like a line of semicolon-delimited links would suffice (so [link];[other link].

    hacktoberfest 
    opened by AntoniosBarotsis 6
  • Add tests for `get_page`.

    Add tests for `get_page`.

    This writes one basic test for get_page, using a valid URL. In addition, to add some security because the reader expects XML, I added some validition on the content type returned along the body. This created additional tests regarding downloading another type of text (html) and non-text (image).

    Tell me if you need more on this particular function.


    Related to #9

    hacktoberfest-accepted 
    opened by Kineolyan 5
  • Added env variable use if feeds.txt not specified.

    Added env variable use if feeds.txt not specified.

    Note: to run with environment variables, use the following command: cargo run -- link1*link2*linkn where each link has the format https://website.com/file.xml

    Each link is delimited by a * which can easily be changed if needed. I tried using ; but had some issues with it being read correctly. I've tested the code passing the same feed links from feeds.txt as env variables and the output matched the same as when using the feeds.txt file (cargo run is used).

    enhancement hacktoberfest-accepted 
    opened by oliviacarino 3
  • Configurable docker image for Rss2Email

    Configurable docker image for Rss2Email

    This PR offers an alternative approach to #7.

    While it is still interesting to read configuration from env vars, as suggested by the 12 Factors approach, we can easily move all files to a dedicated directory and rebind it when running the container. This is what this PR offers.

    Assuming that the image is named rss2email:

    • docker run rss2email runs the process with the default config, shipped in the image
    • docker run -v path/to/config:/opt/rss2email/config rss2email runs the process with the config files located in path/to/config.

    Bonus, you can also avoid shipping your credentials from the .env file in your Docker image.

    opened by Kineolyan 3
  • Added simple prototype for HTML/CSS styling.

    Added simple prototype for HTML/CSS styling.

    I plan on diving deeper into this in a separate PR, but figured I could submit what I have now before it's too late to have this PR count towards Hacktoberfest!

    It currently outputs the raw HTML to the console.

    opened by oliviacarino 2
  • Readme.md, a little restyling.

    Readme.md, a little restyling.

    This PR contains a proposal of restyle for the documentation part, as per issue #21. I ended up preparing a practical example instead of exchanging generic guidance.
    As before: its perfectly OK to discard this proposal as not-fitting.

    This has been prepared taking consideration of the followings:

    • Mature projects tend to touch all essential in README.md and provide link with details, your doc was already ahead on this.
    • The environment variables sections covers 90% of the software usage, will be the first high step for users.

    Some smaller/trivial matters

    I used a README.md template that's commonly used.

    Link to documentation are clearer when using the destination link title (or usage), like [how to build](#) instead of follow [this](#) for more details

    opened by giulio-Joshi 2
  • Replace ureq with reqwest

    Replace ureq with reqwest

    Happy Hacktoberfest!

    A couple things to note:

    • I went with the blocking call as noted in the issue
    • I didn't touch the existing async functions

    Fixes #28

    enhancement hacktoberfest-accepted 
    opened by Celeo 2
  • Add summary if available for each post

    Add summary if available for each post

    This has been sort of mentioned in #6 but since the issue is taking a long time I made a separate one.

    Description

    The post struct has a description field which is currently not present in the generated HTML.

    A config parameter could be added for the preferred max length of a description.

    Notes

    Some feeds seem to be using a description tag instead of the official summary tag so might as well try and parse both.

    enhancement 
    opened by AntoniosBarotsis 2
  • Style HTML output [HTML, CSS]

    Style HTML output [HTML, CSS]

    The HTML output is generated by this function which currently does not include any CSS. Making some basic stylistic changes would be pretty cool.

    Changes in the HTML itself are also welcome (such as including the post's description), the data you have available for each blog can be found here.

    I don't have a very clear idea of what I'd want this to look like other than it being in dark mode, I like how Darkreader makes it look for instance. It would be nice to have a back-and-forth conversation about how this could look before you start implementing it!

    Testing

    Running cargo run should dump the generated HTML in the terminal which you can either save to a file and open in your browser or (if you are lazy like me) paste in something like https://html.onlineviewer.net/.

    Edit: I might keep this open even after #37 is merged because I want to explore the idea of letting the user inject their own CSS through environment variables and/or predefined "themes".

    enhancement good first issue hacktoberfest 
    opened by AntoniosBarotsis 7
Releases(v1.0.1)
  • v1.0.1(Jan 7, 2023)

  • v1.0.0(Dec 6, 2022)

    What's Changed

    • Add performance investigation by @ddanielsantos in https://github.com/AntoniosBarotsis/Rss2Email/pull/14
    • Add tests for get_page. by @Kineolyan in https://github.com/AntoniosBarotsis/Rss2Email/pull/15
    • Added env variable use if feeds.txt not specified. by @oliviacarino in https://github.com/AntoniosBarotsis/Rss2Email/pull/16
    • Some pipeline improvements by @AntoniosBarotsis in https://github.com/AntoniosBarotsis/Rss2Email/pull/17
    • Workflow improvements by @AntoniosBarotsis in https://github.com/AntoniosBarotsis/Rss2Email/pull/23
    • Made download_blogs requests async by @cantudo in https://github.com/AntoniosBarotsis/Rss2Email/pull/19
    • Add tests for parsing. by @Kineolyan in https://github.com/AntoniosBarotsis/Rss2Email/pull/25
    • Added local mail command support by @giulio-Joshi in https://github.com/AntoniosBarotsis/Rss2Email/pull/27
    • Replace ureq with reqwest by @Celeo in https://github.com/AntoniosBarotsis/Rss2Email/pull/30
    • Readme.md, a little restyling. by @giulio-Joshi in https://github.com/AntoniosBarotsis/Rss2Email/pull/31
    • A lot of workflow stuff by @AntoniosBarotsis in https://github.com/AntoniosBarotsis/Rss2Email/pull/32

    New Contributors

    • @ddanielsantos made their first contribution in https://github.com/AntoniosBarotsis/Rss2Email/pull/14
    • @Kineolyan made their first contribution in https://github.com/AntoniosBarotsis/Rss2Email/pull/15
    • @oliviacarino made their first contribution in https://github.com/AntoniosBarotsis/Rss2Email/pull/16
    • @cantudo made their first contribution in https://github.com/AntoniosBarotsis/Rss2Email/pull/19
    • @giulio-Joshi made their first contribution in https://github.com/AntoniosBarotsis/Rss2Email/pull/27
    • @Celeo made their first contribution in https://github.com/AntoniosBarotsis/Rss2Email/pull/30

    Full Changelog: https://github.com/AntoniosBarotsis/Rss2Email/commits/v1.0.0

    Source code(tar.gz)
    Source code(zip)
Owner
Tony
Second-year Computer Science & Engineering student at TU Delft.
Tony
A federated forum / link aggregator using ActivityPub.

lotide A federated forum / link aggregator using ActivityPub. To track progress and report issues, visit the issue tracker. Submit patches on the mail

null 9 Oct 16, 2022
Searchbuddy is a browser extension that lets you chat with people that are searching for what you're searching for.

searchbuddy Make friends while searching! Searchbuddy is a browser extension that lets you chat with people that are searching for what you're searchi

Joseph Gerber 14 May 23, 2022
Flexcord! A custom Discord client to allow you to do what you want!

Disclaimer Flexcord is NO WHERE near done. Flexcord What is it? Flexcord is a Discord client that flexes for your needs, it allows you to do exactly w

null 2 Dec 5, 2022
Bongo Copy Cat wants to be involved in everything you do but instead just imitates you hitting your keyboard all day. After all it's just a cat.

Bongo Copy Cat Introduction Bongo Copy Cat wants to be involved in everything you do but instead just imitates you hitting your keyboard all day. Afte

Abhijeet Singh 4 Jan 23, 2023
notify Node.js binding via napi-rs.

@napi-rs/notify notify Node.js binding via napi-rs. Install this package yarn add

LongYinan 9 Jun 6, 2022
Membrane is an opinionated crate that generates a Dart package from a Rust library. Extremely fast performance with strict typing and zero copy returns over the FFI boundary via bincode.

Membrane is an opinionated crate that generates a Dart package from a Rust library. Extremely fast performance with strict typing and zero copy returns over the FFI boundary via bincode.

Jerel Unruh 70 Dec 13, 2022
Trigger sounds via RFID tags or barcodes

Reads codes via RFID or 1D/2D barcode USB scanners and plays soundfiles mapped to them.

Jochen Kupperschmidt 3 Mar 12, 2022
The axiom profiler for exploring and visualizing SMT solver quantifier instantiations (made via E-matching).

Axiom Profiler A tool for visualising, analysing and understanding quantifier instantiations made via E-matching in a run of an SMT solver (at present

Viper Project 18 Oct 18, 2022
Code for connecting an RP2040 to a Bosch BNO055 IMU and having the realtime orientation data be sent to the host machine via serial USB

Code for connecting an RP2040 (via Raspberry Pi Pico) to a Bosch BNO055 IMU (via an Adafruit breakout board) and having the realtime orientation data be sent to the host machine via serial USB.

Gerald Nash 3 Nov 4, 2022
esp-serial-dbg - debugging of esp-hal based applications via serial

esp-serial-dbg - debugging of esp-hal based applications via serial About This is still work in progress! At least the contained examples should work

Björn Quentin 3 Aug 23, 2022
Adapter plugin to use Ruff in dprint's CLI and with JavaScript via Wasm

dprint-plugin-ruff Adapter for Ruff for use as a formatting plugin in dprint. Formats .py and .pyi files. Note: For formatting .ipynb files, use the J

null 3 Nov 28, 2023
A new comfortable back end framework for rustaceans.

Black Tea is a new Rust back end framework based on hyper. We are enthusiastic to provide developers some enhanced features and comfortable coding experience.

Rui Li 10 Dec 13, 2021
Fegeya Gretea (aka green tea), new generation programming language.

Fegeya Gretea Gretea (aka green tea), new generation programming language. A taste of Gretea's syntax: import tea.green.fmt module hello { fn hel

Ferhat Geçdoğan 13 Sep 28, 2022
A lightweight new Bing (AI chat) desktop application which based on Tauri.

Bing Lite A lightweight new Bing (AI chat) desktop application which based on Tauri. No more Microsoft Edge, no more Chromium/Electron! Download The l

a.e. 6 Apr 5, 2023
A W.I.P desktop application for a new typesetting language, typst.

[WIP] typstudio A W.I.P desktop application for a new markup-based typesetting language, typst. Typstudio is built using Tauri. Features Syntax highli

Cubxity 40 Apr 25, 2023
Select any exported function in a dll as the new dll's entry point.

Description This tool will patch the entry point of the input dll and replace it with the RVA of another exported function in that same dll. This allo

Kurosh Dabbagh Escalante 43 Jun 7, 2023
Check Have I Been Pwned and see if it's time for you to change passwords.

checkpwn Check Have I Been Pwned and see if it's time for you to change passwords. Getting started Install: cargo install checkpwn Update: cargo inst

Johannes 93 Dec 13, 2022
bevy_blender is a Bevy library that allows you to use assets created in Blender directly from the .blend file

bevy_blender bevy_blender is a Bevy library that allows you to use assets created in Blender directly from the .blend file.

Jerald Thomas 45 Jan 4, 2023
miette is a diagnostic library for Rust. It includes a series of traits/protocols that allow you to hook into its error reporting facilities, and even write your own error reports!

miette is a diagnostic library for Rust. It includes a series of traits/protocols that allow you to hook into its error reporting facilities, and even write your own error reports!

Kat Marchán 1.2k Jan 1, 2023