| Title: | Utilities for Promoting rOpenSci on Social Media |
|---|---|
| Description: | Utility functions for accessing GitHub and social media data. |
| Authors: | Steffi LaZerte [aut, cre] (ORCID: <https://orcid.org/0000-0002-7690-8360>) |
| Maintainer: | Steffi LaZerte <[email protected]> |
| License: | GPL (>= 3) |
| Version: | 0.6.0 |
| Built: | 2026-05-15 10:23:42 UTC |
| Source: | https://github.com/ropensci-org/promoutils |
Create a cached version of the GH api calls
.gh_cache(..., .token = key("github"), .max_rate = NULL).gh_cache(..., .token = key("github"), .max_rate = NULL)
... |
Arguments passed on to
|
.token |
Authentication token. Defaults to |
.max_rate |
Maximum request rate in requests per second. Set this to automatically throttle requests. |
memoise::memoise(gh::gh)
Arranges data in long by platform (linkedin and mastodon).
by_platform(df)by_platform(df)
df |
Data frame. Formatted data including social media handles. |
Data frame arranged by platform on which to advertise.
u <- uc_fetch() |> uc_fmt("2025-01-01") |> uc_handles() |> by_platform()u <- uc_fetch() |> uc_fmt("2025-01-01") |> uc_handles() |> by_platform()
The week before, prepare the slides and coworking document, then use this draft text to invite the cohost(s) to review via Slack or Email.
cw_checkin(which = "next", names = NULL, print = FALSE)cw_checkin(which = "next", names = NULL, print = FALSE)
which |
Character/Date. "next" to fetch details on the next coworking session, "last" to fetch details on the last scheduled (in future) coworking session, or a Date fetch details for a specific coworking session. |
names |
Character. Names of cohost if overriding those in the event listing. |
print |
Logical. Whether to simply print the text to console instead of copying to the clipboard. |
When an event has been drafted use this draft text to invite the cohost(s) to review via Slack or Email.
cw_checkin_event(which = "next", names = NULL, print = FALSE)cw_checkin_event(which = "next", names = NULL, print = FALSE)
which |
Character/Date. "next" to fetch details on the next coworking session, "last" to fetch details on the last scheduled (in future) coworking session, or a Date fetch details for a specific coworking session. |
names |
Character. Names of cohost if overriding those in the event listing. |
print |
Logical. Whether to print the copied text to the console. |
cw_checkin_event("2026-04-07")cw_checkin_event("2026-04-07")
Fetch details about coworking sessions
cw_details(which = "next")cw_details(which = "next")
which |
Character/Date. "next" to fetch details on the next coworking session, "last" to fetch details on the last scheduled (in future) coworking session, or a Date fetch details for a specific coworking session. |
Data frame with coworking event details
cw_details() # cw_details("2023-11") # Only works for events in the futurecw_details() # cw_details("2023-11") # Only works for events in the future
Creates the coworking doc if it doesn't exist and returns a link either way. Optionally creates PR adds link to event page.
cw_docs_link(which = "next", open_sites = TRUE, add = FALSE)cw_docs_link(which = "next", open_sites = TRUE, add = FALSE)
which |
Character/Date. "next" to fetch details on the next coworking session, "last" to fetch details on the last scheduled (in future) coworking session, or a Date fetch details for a specific coworking session. |
open_sites |
Logical. Open websites with relevant details? |
add |
Logical. Whether to initialize a PR and add the link to the events file. |
Google Docs link
Creates a draft coworking event for the roweb3 website. All details pulled
from the coworking todo list issue in rosadmin/comms. See cw_issue().
cw_event(date, dry_run = FALSE)cw_event(date, dry_run = FALSE)
date |
Character/Date. Date of the coworking event to create |
dry_run |
Logical. Whether to really create the event or just return the text. |
Create a GitHub issue in a repository listing the Coworking ToDos. If no date or timezone, picks the next appropriate date (first Tuesday of the month following an existing coworking issue) and next appropriate timezone (cycling through America, Europe, and Australia) automatically.
cw_issue( date = NULL, tz = NULL, theme = "XXXX", cohost = "XXXX", repo = "rosadmin/comms", dry_run = FALSE )cw_issue( date = NULL, tz = NULL, theme = "XXXX", cohost = "XXXX", repo = "rosadmin/comms", dry_run = FALSE )
date |
Character. Date of next event (if NULL picks next first Tuesday). |
tz |
Character. Timezone of next event (if NULL picks next in order). |
theme |
Character. Name of theme, if unknown, uses XXXX placeholder |
cohost |
Character. Name of cohost, if unknown, uses XXXX placeholder |
repo |
Character. GitHub repository including owner (e.g.,
|
dry_run |
Logical. Whether to really create the issue or just return the text. |
Nothing
cw_issue(dry_run = TRUE)cw_issue(dry_run = TRUE)
Will only work if running between the time that the 1-week message was posted and the start of the coworking.
cw_slack_hour( user = "UNRAUCMTK", test_run = FALSE, dry_run = FALSE, print = FALSE, call = rlang::caller_env() )cw_slack_hour( user = "UNRAUCMTK", test_run = FALSE, dry_run = FALSE, print = FALSE, call = rlang::caller_env() )
user |
Character. Slack user id. |
test_run |
Logical. Whether to run a test of this message posting to the test channel. |
dry_run |
Logical. Whether to do a dry run, print the message only. |
print |
Logical. Whether to simply print the text to console instead of copying to the clipboard. |
call |
Environment. Parent environment for messaging. |
Nothing
cw_slack_hour(test_run = TRUE) cw_slack_hour(dry_run = TRUE)cw_slack_hour(test_run = TRUE) cw_slack_hour(dry_run = TRUE)
Open and fetch link to coworking slides
cw_slides_link(open_site = TRUE)cw_slides_link(open_site = TRUE)
open_site |
Logical. Open slides in browser? |
Link to slides
Creates draft posts for Mastodon and LinkedIn (by opening issues on rosadmin/scheduled_socials) and Slack (by printing the post text and schedule).
cw_socials( date, who_masto, who_slack, who_linkedin, who_main_masto = "@[email protected]", who_main_slack = "<@UNRAUCMTK>", who_main_linkedin = "Steffi LaZerte", posters_tz = "America/Winnipeg", test_run = FALSE, dry_run = FALSE, print = TRUE, branch = NULL )cw_socials( date, who_masto, who_slack, who_linkedin, who_main_masto = "@[email protected]", who_main_slack = "<@UNRAUCMTK>", who_main_linkedin = "Steffi LaZerte", posters_tz = "America/Winnipeg", test_run = FALSE, dry_run = FALSE, print = TRUE, branch = NULL )
date |
Character/Date. Date of the coworking event (local) |
who_masto |
Character. The full mastodon handle for the cohost (i.e. |
who_slack |
Character. The full API Slack id for the cohost (i.e. |
who_linkedin |
Character. The full LinkedIn handle for the cohost (i.e. |
who_main_masto |
Character. The full mastodon handle for the rOpenSci staff organizer. |
who_main_slack |
Character. The Slack id for the rOpenSci staff
organizer (i.e., |
who_main_linkedin |
Character. The full LinkedIn handle for the rOpenSci staff organizer. |
posters_tz |
Character. Timezone of poster. Required for getting the time at which to post Slack messages as these are posted in the local timezone |
test_run |
Logical. Whether to do a test run (i.e. post to a test area) |
dry_run |
Logical. Whether to do a dry run (i.e. don't post) |
print |
Logical. Whether to simply print the text to console instead of copying to the clipboard. |
branch |
Character. Branch name if not on main. |
cw_socials("2023-07-04", who_masto = "@[email protected]", who_linkedin = "Cohost the Best", who_slack = "<UXXXXXXX>", dry_run = TRUE) ## Not run: cw_socials("2023-07-04", who_masto = "@[email protected]", who_slack = "<UXXXXXXX>") ## End(Not run)cw_socials("2023-07-04", who_masto = "@[email protected]", who_linkedin = "Cohost the Best", who_slack = "<UXXXXXXX>", dry_run = TRUE) ## Not run: cw_socials("2023-07-04", who_masto = "@[email protected]", who_slack = "<UXXXXXXX>") ## End(Not run)
Creates a data frame dictionary of different versions of wording to use in help-wanted posts depending on the language of the post.
dict_helpwanted()dict_helpwanted()
Data frame.
dict_helpwanted()dict_helpwanted()
Creates a data frame dictionary of different versions of wording to use in usecase posts depending on the language of the post.
dict_usecases()dict_usecases()
Data frame.
dict_usecases()dict_usecases()
Fetch help wanted issues
help_fetch(min_date, json = "/repos/rosadmin/help-wanted/contents/issues.json")help_fetch(min_date, json = "/repos/rosadmin/help-wanted/contents/issues.json")
min_date |
Character/Date. Earliest date a help-wanted label was added to an issue to be included. |
json |
Character. Location of the issues.json file to use. |
Data frame of help wanted issues
h <- help_fetch("2025-01-01")h <- help_fetch("2025-01-01")
Get social media handles for helpwanted issues
help_handles(help, force_masto = FALSE)help_handles(help, force_masto = FALSE)
help |
Data frame of help wanted issues. |
force_masto |
Logical. Passed to |
Data frame of help wanted issues with social median handles added
h <- help_fetch("2025-01-01") |> help_handles()h <- help_fetch("2025-01-01") |> help_handles()
socials_post_issue() commandCreate help-wanted socials_post_issue() command
help_post(help, date_time = NULL, dry_run = FALSE, print = FALSE)help_post(help, date_time = NULL, dry_run = FALSE, print = FALSE)
help |
Data frame. Formatted help-wanted issues including social media
handles and arranged by platform upon which to post, output of
|
date_time |
Character/Date. When to post. Defaults to next Thursday if |
dry_run |
Logical. Whether to do a dry run (i.e. don't post) |
print |
Logical. Whether to simply print the text to console instead of copying to the clipboard. |
Copies commands to clipboard, optionally prints if (print = TRUE).
h <- help_fetch("2025-05-23") |> help_handles() |> by_platform() help_post(h, print = TRUE) # For non-interactive examplesh <- help_fetch("2025-05-23") |> help_handles() |> by_platform() help_post(h, print = TRUE) # For non-interactive examples
Function created for rosadmin/help-wanted. Fetches ropensci repos with issues labelled help-wanted. Saves output to issues.json for use by helpwanted workflows including https://ropensci.org/help-wanted.
help_wanted_json()help_wanted_json()
Creates/updates issues.json
Check to see if you have set up all the keys required by promoutils.
keys_check()keys_check()
Message informing of status
keys_check()keys_check()
This function guides uses through the finding and setting tokens so that promoutils can find them.
keys_set(type = NULL)keys_set(type = NULL)
type |
Character Vector. Keys/tokens to set ("slack", "matomo", "linkedin", "github"). |
Nothing, side effect of setting token credentials in the keyring or
via gitcreds::gitcres_set() for GitHub tokens.
This authorizes the rOpenSci client with your credentials (and you must be part of the rOpenSci organization as an admin). Make sure to take note of the 'refresh_token' as that is what you'll add to your .Renviron file for local work, or the GitHub secrets for the comms/scheduled_socials workflow.
li_auth()li_auth()
This function authorizes with a redirect url of "http://localhost:1444/", this must be the same as that listed in the LinkedIn Developer App, https://www.linkedin.com/developers/apps.
If you retrieve a new token, you will have to put it in the .Renviron and the re-start your R session to continue
This function authorizes with the scopes:
w_member_social (default)
w_organization_social (special request)
r_organization_social (special request)
r_organization_admin (special request)
httr2 authorization
Refresh tokens API: https://learn.microsoft.com/en-us/linkedin/shared/authentication/programmatic-refresh-tokens
## Not run: # Only run if you need to update the scopes or get a new token (otherwise # you'll have to replace all your tokens) t <- li_auth() t$refresh_token ## End(Not run)## Not run: # Only run if you need to update the scopes or get a new token (otherwise # you'll have to replace all your tokens) t <- li_auth() t$refresh_token ## End(Not run)
Get a list of recent posts by rOpenSci
li_posts_read(author)li_posts_read(author)
author |
Character. LinkedIn URN id (e.g., rOpenSci's is "urn:li:organization:77132573") |
list of posts
https://learn.microsoft.com/en-us/linkedin/shared/api-guide/concepts/urns
https://learn.microsoft.com/en-us/linkedin/marketing/integrations/community-management/shares/posts-api
li_posts_read(ro_urn)$elements[[1]]$commentary |> cat()li_posts_read(ro_urn)$elements[[1]]$commentary |> cat()
Post to LinkedIn
li_posts_write(author, body, dry_run = FALSE)li_posts_write(author, body, dry_run = FALSE)
author |
Character. URN. Either yours (see |
body |
Character. The body of the post as you would like it to appear. |
dry_run |
Logical. TRUE to show what would be sent to the server without actually sending it. |
A string of the URN for the post id.
# Dry-run id <- li_posts_write( author = ro_urn, # Post on behalf of rOpenSci body = "Testing out the LinkedIn API via R and httr2!", dry_run = TRUE) ## Not run: # Real post id <- li_posts_write( author = ro_urn, # Post on behalf of rOpenSci body = "Testing out the LinkedIn API via R and httr2!") ## End(Not run)# Dry-run id <- li_posts_write( author = ro_urn, # Post on behalf of rOpenSci body = "Testing out the LinkedIn API via R and httr2!", dry_run = TRUE) ## Not run: # Real post id <- li_posts_write( author = ro_urn, # Post on behalf of rOpenSci body = "Testing out the LinkedIn API via R and httr2!") ## End(Not run)
This is required to post on LinkedIn to your personal account (for rOpenSci, use the organization urn, "urn:li:organization:77132573"
li_urn_me()li_urn_me()
A string with your URN in the format of "urn:li:person:XXXX"
## Not run: li_urn_me() ## End(Not run)## Not run: li_urn_me() ## End(Not run)
Downloads all views from a specific year range (2010-2024 by defautl).
Views can be read with matomo_read().
matomo_all(year_range = 2010:2024, host = "https://ropensci.matomo.cloud")matomo_all(year_range = 2010:2024, host = "https://ropensci.matomo.cloud")
year_range |
Numeric vector. Years to download views for. |
host |
Character. URL for the Matomo host to collect views for. Defaults to that of rOpenSci. |
Requires a Renviron "MATOMO_TOKEN" key representing your token for Matomo for the host you'd like to fetch data for.
Nothing. Writes views to disk.
Formats and filter Matomo views to blogposts
matomo_blogposts(views)matomo_blogposts(views)
views |
Data frame from |
Data frame of blog post views
matomo_read() |> matomo_blogposts()matomo_read() |> matomo_blogposts()
Cache folder to store matomo views
matomo_dir()matomo_dir()
Character file path
matomo_dir()matomo_dir()
Reads a saved set of views.
matomo_read()matomo_read()
Data frame of view data.
matomo_read()matomo_read()
Update a specific year of Matomo blog views. Defaults to current year.
Views can be read with matomo_read().
matomo_update( year = lubridate::year(Sys.Date()), host = "https://ropensci.matomo.cloud" )matomo_update( year = lubridate::year(Sys.Date()), host = "https://ropensci.matomo.cloud" )
year |
Numeric. Year to update |
host |
Character. URL for the Matomo host to collect views for. Defaults to that of rOpenSci. |
Requires a .Renviron "MATOMO_TOKEN" key representing your token for Matomo for the host you'd like to fetch data for.
Nothing. Updates views to disk.
Given a date and a day of the week, Given a date return the next month's first Tuesday
next_date(month, which = "Tues", n = 1, call = rlang::caller_env())next_date(month, which = "Tues", n = 1, call = rlang::caller_env())
month |
Character/Date. The current month. Date returned is the next month. |
which |
Character/Numeric. Which week day to return. Either number or abbreviated English weekday. |
n |
Numeric. The nth week to return (i.e. the 1st Tuesday if |
call |
Environment. Calling environment for appropriate messages if used within another function. |
A date
# Get the next first Tuesday next_date("2023-11-01") next_date("2023-11-30") # Get the next 3rd Tuesday next_date("2023-11-01", n = 3) # Oops ## Not run: next_date("2023-11-01", n = 5) ## End(Not run)# Get the next first Tuesday next_date("2023-11-01") next_date("2023-11-30") # Get the next 3rd Tuesday next_date("2023-11-01", n = 3) # Oops ## Not run: next_date("2023-11-01", n = 5) ## End(Not run)
Get package author names
pkg_authors(package, pkgs)pkg_authors(package, pkgs)
package |
Character. Package name |
pkgs |
Data frame. Packages returned by |
Character name of maintainer
pkg_authors("weathercan", pkgs_ru())pkg_authors("weathercan", pkgs_ru())
List of packages and details from R-Universe API
pkgs_ru(universe = "ropensci")pkgs_ru(universe = "ropensci")
universe |
Character. Universe to collect details from. |
Data frame of package details
pkgs_ru()pkgs_ru()
Finds the next date/time to post by day of the week and hour.
post_time(day, hour)post_time(day, hour)
day |
Character. Day of the week (e.g., "Monday") |
hour |
Numeric. Hour at which to post (e.g., 8) |
Date time as character (without timezone)
post_time("Wednesday", 8)post_time("Wednesday", 8)
List open PRs by url, title and number, optionally matching to a title or branch name (ref)
prs_list(match = NULL, owner = "ropensci", repo = "roweb3")prs_list(match = NULL, owner = "ropensci", repo = "roweb3")
match |
Character. String to match in the title or branch name |
owner |
Character. GitHub owner of the repository (defaults to 'ropensci') |
repo |
Character. GitHub repository name (defaults to 'roweb3') |
Data frame with PR url, number, title, and branch name ('ref')
prs_list("coworking") # List all coworking related (open) PRsprs_list("coworking") # List all coworking related (open) PRs
Replaces emoji codes like :tada: with unicode like 🎉.
replace_emoji(x)replace_emoji(x)
x |
Character. Text string within which to replace codes |
Text string with emoji unicodes
replace_emoji("hi :tada: testing \n\n\n Whow ! 🔗 \n\n\n :smile:") replace_emoji(":link:")replace_emoji("hi :tada: testing \n\n\n Whow ! 🔗 \n\n\n :smile:") replace_emoji(":link:")
rOpenSci linkedin organization URN
ro_urnro_urn
An object of class character of length 1.
List channels and their ids
slack_channels(channel = NULL, types = c("public_channel", "private_channel"))slack_channels(channel = NULL, types = c("public_channel", "private_channel"))
channel |
Character. Channel Name. |
types |
Character. Type of channels, one or both of "public_channel" or "private_channel" |
Data frame of channel names and ids, or if channel provided, a
single channel id.
slack_channels() slack_channels("general") chn <- slack_channels(types = "private_channel")slack_channels() slack_channels("general") chn <- slack_channels(types = "private_channel")
Removes previously scheduled messages from #admin-scheduled if after the
posting date.
slack_cleanup()slack_cleanup()
Nothing
slack_posts_write("testing cleanup", when = Sys.time() + lubridate::seconds(600), tz = Sys.timezone()) slack_scheduled_list() slack_cleanup()slack_posts_write("testing cleanup", when = Sys.time() + lubridate::seconds(600), tz = Sys.timezone()) slack_scheduled_list() slack_cleanup()
Use with caution!
slack_message_rm(msg = NULL, channel = NULL, channel_id = NULL, ts)slack_message_rm(msg = NULL, channel = NULL, channel_id = NULL, ts)
msg |
Data frame. Output of |
channel |
Character. Channel Name. Not required if channel_id supplied. |
channel_id |
Character. Channel id. |
ts |
Numeric. Timestamp to identify message to remove |
Nothing. Side effect of removing message from channel
Requires one of channel OR channel_id
slack_messages(channel = NULL, channel_id = NULL)slack_messages(channel = NULL, channel_id = NULL)
channel |
Character. Channel Name. Not required if channel_id supplied. |
channel_id |
Character. Channel id. |
Data frame. Messages and details
slack_messages(channel_id = "C026GCWKA") # General slack_messages(channel = "General")slack_messages(channel_id = "C026GCWKA") # General slack_messages(channel = "General")
Write a Slack message for posting now or later.
slack_posts_write( body, when = "now", tz = "America/Winnipeg", channel = "#testing-api", dry_run = FALSE )slack_posts_write( body, when = "now", tz = "America/Winnipeg", channel = "#testing-api", dry_run = FALSE )
body |
Character. Text of message to post. |
when |
Character or Date/time. When to post message (timezone is
ignored, see |
tz |
Character. Timezone of |
channel |
Character. Channel to post message to. |
dry_run |
Logical. Test run? |
See https://docs.slack.dev/messaging/formatting-message-text#special-mentions https://docs.slack.dev/messaging/formatting-message-text#mentioning-users
Success message
https://docs.slack.dev/messaging/sending-and-scheduling-messages
https://docs.slack.dev/messaging/sending-and-scheduling-messages#scheduling
slack_posts_write("testing on Tuesday") slack_posts_write("testing more and more", when = Sys.time() + 3600, tz = "Europe/Paris") slack_posts_write( paste( "Join us for Social Coworking and office hours next week!", "", ":grey_exclamation: Theme: TESTING", ":hourglass_flowing_sand: When: TODAY!", ":cookie: Hosted by: USER! and cohost HOST", "", "You can use this time for...", "- General coworking", sep = "\n"), when = "now") # Dry runs slack_posts_write("testing on Tuesday", dry_run = TRUE) slack_posts_write( "testing [this cool link](https://mycoolsite.com)", dry_run = TRUE )slack_posts_write("testing on Tuesday") slack_posts_write("testing more and more", when = Sys.time() + 3600, tz = "Europe/Paris") slack_posts_write( paste( "Join us for Social Coworking and office hours next week!", "", ":grey_exclamation: Theme: TESTING", ":hourglass_flowing_sand: When: TODAY!", ":cookie: Hosted by: USER! and cohost HOST", "", "You can use this time for...", "- General coworking", sep = "\n"), when = "now") # Dry runs slack_posts_write("testing on Tuesday", dry_run = TRUE) slack_posts_write( "testing [this cool link](https://mycoolsite.com)", dry_run = TRUE )
Returns the currently scheduled messages with added details regarding timezones, etc.
slack_scheduled_list()slack_scheduled_list()
Data frame of currently scheduled messages
slack_scheduled_list()slack_scheduled_list()
Removes a currently scheduled messages.
slack_scheduled_rm(msg = NULL, channel = NULL, id = NULL)slack_scheduled_rm(msg = NULL, channel = NULL, id = NULL)
msg |
Data frame. Output of |
channel |
Character. If no msg, the Channel of the message to be deleted. |
id |
Character. If no msg, the ID of the message to be deleted. |
Nothing
# Schedule message slack_posts_write("Testing delete msg", when = (Sys.Date() + lubridate::days(2))) # Confirm scheduled slack_scheduled_list() # Remove message slack_scheduled_list() |> dplyr::filter(text == "Testing delete msg") |> slack_scheduled_rm() # Confirm that removed slack_scheduled_list() ## Not run: slack_scheduled_rm(channel = "#testing-api", id = "Q08U4S3J6QG") ## End(Not run)# Schedule message slack_posts_write("Testing delete msg", when = (Sys.Date() + lubridate::days(2))) # Confirm scheduled slack_scheduled_list() # Remove message slack_scheduled_list() |> dplyr::filter(text == "Testing delete msg") |> slack_scheduled_rm() # Confirm that removed slack_scheduled_list() ## Not run: slack_scheduled_rm(channel = "#testing-api", id = "Q08U4S3J6QG") ## End(Not run)
Fetch details on a specific user
slack_user(name, users = NULL)slack_user(name, users = NULL)
name |
Character. String to match real name to |
users |
Data frame. Data frame of users from |
Data frame
slack_user("Steffi")slack_user("Steffi")
Fetch a list of Slack users
slack_users()slack_users()
Data frame of Slack users including names and ids
u <- slack_users()u <- slack_users()
socials_post_issue() commandCreate Throwback Thursday socials_post_issue() command
tt_post( date, title, url, blurb = "<-- Interesting description/blurb mentioning the author -->", dry_run = FALSE, print = FALSE )tt_post( date, title, url, blurb = "<-- Interesting description/blurb mentioning the author -->", dry_run = FALSE, print = FALSE )
date |
YMD Character. Date of the original post. |
title |
Character. Title of the original post. |
url |
Character. URL to original blog post |
blurb |
Character. Interesting bit to describe post (optional). |
dry_run |
Logical. Whether to do a dry run (i.e. don't post) |
print |
Logical. Whether to simply print the text to console instead of copying to the clipboard. |
Character string of R functions with relevant details (normally pasted into a POSTS_TT.R script file and tweaked as necessary before being executed).
# Standard tt_post( "2019-05-14", "POWER to the People", "https://ropensci.org/blog/2019/05/14/nasapower/", print = TRUE ) # Double throwback tt_post( c("2017-08-22", "2017-08-22"), c("So you (don’t) think you can review a package", "Onboarding visdat, a tool for preliminary visualisation of whole dataframes" ), url = c( "https://ropensci.org/blog/2017/08/22/first-package-review/", "https://ropensci.org/blog/2017/08/22/visdat/" ), print = TRUE ) # Slug only tt_post("2019-05-14", "POWER to the People", "nasapower", print = TRUE)# Standard tt_post( "2019-05-14", "POWER to the People", "https://ropensci.org/blog/2019/05/14/nasapower/", print = TRUE ) # Double throwback tt_post( c("2017-08-22", "2017-08-22"), c("So you (don’t) think you can review a package", "Onboarding visdat, a tool for preliminary visualisation of whole dataframes" ), url = c( "https://ropensci.org/blog/2017/08/22/first-package-review/", "https://ropensci.org/blog/2017/08/22/visdat/" ), print = TRUE ) # Slug only tt_post("2019-05-14", "POWER to the People", "nasapower", print = TRUE)
Use matomo_update() and friends to download and update blog post view data.
tt_review() summarizes the posts by view and optionally filters to a
specific month.
tt_review(which_month = NULL)tt_review(which_month = NULL)
which_month |
Numeric. Which month to return? Numeric 1-12 for month.
Default |
Data frame of posts by views with urls
tt_review(11)tt_review(11)
Fetch and format use cases from a GitHub Discussion board
uc_fetch(owner = "ropensci", name = "discussions")uc_fetch(owner = "ropensci", name = "discussions")
owner |
Character. Repository owner. |
name |
Character. Repository for discussions |
Data frame of usecases
u <- uc_fetch() uu <- uc_fetch() u
Extract out resource information
uc_fmt(uc, min_date, pkgs = NULL)uc_fmt(uc, min_date, pkgs = NULL)
uc |
Data frame. Data frame of usecases from |
min_date |
Character/Date. Minimum date of usecases to retain. |
pkgs |
Data frame. Optional data frame of package details (defaults to |
Data frame of formatted use cases.
u <- uc_fetch() |> uc_fmt("2025-01-01") uu <- uc_fetch() |> uc_fmt("2025-01-01") u
Add social media handles
uc_handles(uc, force_masto = FALSE)uc_handles(uc, force_masto = FALSE)
uc |
Data frame. Formatted use cases output of |
force_masto |
Logical. Passed to |
Data frame with social media handles appended/filled in
u <- uc_fetch() |> uc_fmt("2025-01-01") |> uc_handles()u <- uc_fetch() |> uc_fmt("2025-01-01") |> uc_handles()
socials_post_issue() commandCreate use case socials_post_issue() command
uc_post(uc, date_time = NULL, dry_run = FALSE, print = FALSE)uc_post(uc, date_time = NULL, dry_run = FALSE, print = FALSE)
uc |
Data frame. Formatted use cases including social media handles
and arranged by platform upon which to post, output of |
date_time |
Character/Date. When to post. Defaults to next Wednesday if |
dry_run |
Logical. Whether to do a dry run (i.e. don't post) |
print |
Logical. Whether to simply print the text to console instead of copying to the clipboard. |
Copies commands to clipboard, optionally prints if (print = TRUE).
u <- uc_fetch() |> uc_fmt("2025-01-01") |> uc_handles() |> by_platform() uc_post(u, dry_run = TRUE,print = TRUE)u <- uc_fetch() |> uc_fmt("2025-01-01") |> uc_handles() |> by_platform() uc_post(u, dry_run = TRUE,print = TRUE)
Create url from content date and slug
url_from_path( path, date = NULL, lang = NULL, where = "blog", base_url = "https://ropensci.org" )url_from_path( path, date = NULL, lang = NULL, where = "blog", base_url = "https://ropensci.org" )
path |
Character. Slug, URL, or path to file in repository |
date |
Character. Date for event, used to create link (otherwise extracted from slug) |
lang |
Character. Language of blogpost (i.e., |
where |
Character. 'blog' or 'event' depending on the content type. |
base_url |
Character. Base url of blog posts. |
Full url
url_from_path("my-post", date = "2025-01-01") url_from_path("2025-01-01-my-post/index.es.md") url_from_path("content/blog/2025-09-29-news-september-2025/index.md") url_from_path("content/blog/2025-09-29-news-september-2025/index.Rmd") url_from_path("content/blog/2025-09-29-news-september-2025/")url_from_path("my-post", date = "2025-01-01") url_from_path("2025-01-01-my-post/index.es.md") url_from_path("content/blog/2025-09-29-news-september-2025/index.md") url_from_path("content/blog/2025-09-29-news-september-2025/index.Rmd") url_from_path("content/blog/2025-09-29-news-september-2025/")
Extract YAML keys from block
yaml_extract(yaml, trim = "~~~")yaml_extract(yaml, trim = "~~~")
yaml |
Character. String from which to extract YAML keys |
trim |
Character. Text to remove from the YAML block before processing. Usually the text that defines the block. |
data frame of yaml keys
yaml_extract("~~~start: 2023-11-12\nauthor: Steffi\n~~~")yaml_extract("~~~start: 2023-11-12\nauthor: Steffi\n~~~")
Create a draft issue to post to Mastodon and LinkedIn
Description
Formats the body and title of an issue and posts it on "rosadmin/scheduled_socials". The issue will bed opened in a browser for editing and confirmation. Note that issues will not be posted until the labels "draft" and "needs-review" have been removed.
Usage
Arguments
timeDate/time. Date and time at which the post should be made
tzCharacter. Timezone (from
OlsonNames()) in which to posttitleCharacter. Title of the post (
[Post]and the date will be prepended and appendedbodyCharacter. Text to be posted (omit the YAML for posting info; #RStats and @[email protected] will be appended for Mastodon, #RStats for LinkedIn), or link to text file with both Mastodon and LinkedIn body text, headed by by —- Mastodon —– and — LinkedIn —–.
whereCharacter vector. Either
mastodonand/orlinkedinto specify which platforms this should be posted on.avoid_dupsLogical. Don't post an issue if any open issue has the same title.
add_hashLogical. Whether to automatically add the RStats hashtags.
dry_runLogical. Whether to perform a dry run (do not post, but display draft if
verbose = TRUE).open_browserLogical. Whether to open the issue in the browser.
over_char_limitFunction. Error or warn if over the character limit?
verboseLogical. Show extra informative messages.
Examples