TL;DR
Want to be able to have people subscribe to your blog via email? Check out the {blog2newsletter}
package on GitHub (Flight, n.d.).
The Power of R to the Rescue!
Now, I’ll admit, Google is another “platform”, but it’s one with a well known and documented API, with awesome R packages to interact with the APIs. For example, {gmailr}
lets us compose, draft, and send emails from our GMail accounts (Hester and Bryan, n.d.). {googlesheets4}
provides access to Google Sheets, like those used to store reponses to Google Forms (Bryan, n.d.).
With these packages, we can cobble together another package that provides functions to send blog posts as email newsletters! And thus my holiday break project was born!
Caveats, I don’t know the API limits for GMail, but I’m sure there isn’t really a limit to how many people can be bcc'ed
on a single email. Also, Google could theoretically shut down API access to GMail and Google Sheets tomorrow, but that seems really, really unlikely.
Example Script
Here I’m going to break down the example script _blog2newsletter.R
from the README. In a real directory / project being used to manage this, this is what we would run using b2n_run()
.
At the top, we load the needed packages, and set a bunch of variables, including where the Google project secrets are stored, and where {gargle}
should be putting the oauth tokens, and then loading the authorization tokens:
library(gmailr)
library(googlesheets4)
library(blog2newsletter)
= "secrets/client_secret_file_googleusercontent.com.json"
secrets_path = "secrets/gargle_cache/"
oauth_cache
# don't forget to use your actual email
= "my-gmail@gmail.com"
my_gmail
options(
gargle_oauth_cache = oauth_cache,
gargle_oauth_email = secrets_path
)
gm_auth_configure(path = secrets_path)
gm_auth(scopes = c("compose", "send"),
email = my_gmail)
gs4_auth_configure(path = secrets_path)
gs4_auth(
scopes = "https://www.googleapis.com/auth/spreadsheets.readonly",
email = my_gmail)
The bottom half starts with setting a variable for the blog directory (for {quarto}
blogs) or alternatively where to find the RSS file directly. Then setting the Google Sheet id and grabbing the subscribers. Finally, what should be pre-pended to the email subject before the blog post title.
# switch from directory, full path to index.xml, or url as needed
= "blog/directory"
blog_dir
= "your-sheet-id"
subscribers_id = b2n_fetch_subscribers(subscribers_id)
subscriber_data
# newsletter subject
= "my newsletter"
extra_subject
|>
blog_dir b2n_post_to_email() |>
b2n_add_subscribers(subscriber_data) |>
b2n_from(my_gmail) |>
b2n_add_subject(extra_subject) |>
b2n_send_newsletter()
If you want to see what the composed email looks like before sending it, then you can use the b2n_draft_email
instead of b2n_send_newsletter
, and if you’ve got the right authorizations setup, then the email will show up in your GMail drafts.
Semi-Automatic
Finally, something like this would be a pain to type all that out everytime you wanted to send a new newsletter. This is part of the reason the default post to grab is the latest post that is available in the RSS feed. With that, it’s trivial to have a single script that is run each time you want to send out your latest available blog post. To help with this, there is the b2n_run
function, that by default looks for _blog2newsletter.R
, and source
’s it.
Therefore, you just need a project / directory for the subscription management, with the cache and the above script, and when you have a new blog post up, just do blog2newsletter::b2n_run()
, and the post will be sent out if there are subscribers with matching categories.
References
Reuse
Citation
@online{mflight2023,
author = {Robert M Flight},
title = {Blog {Posts} as {Email} {Newsletters}},
date = {2023-01-19},
url = {https://rmflight.github.io/posts/2023-01-19-blog-posts-as-email-newsletters},
langid = {en}
}