{"id":16572307,"url":"https://github.com/jonocarroll/ntfy","last_synced_at":"2025-04-05T08:07:16.575Z","repository":{"id":71014071,"uuid":"563839643","full_name":"jonocarroll/ntfy","owner":"jonocarroll","description":"Lightweight Wrapper to the ntfy.sh Service","archived":false,"fork":false,"pushed_at":"2025-03-28T04:38:47.000Z","size":313,"stargazers_count":76,"open_issues_count":3,"forks_count":4,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-29T07:05:51.832Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jonocarroll.png","metadata":{"files":{"readme":"README.Rmd","changelog":"NEWS.md","contributing":null,"funding":".github/FUNDING.yml","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},"funding":{"github":"jonocarroll","patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"lfx_crowdfunding":null,"polar":null,"buy_me_a_coffee":null,"custom":null}},"created_at":"2022-11-09T12:57:31.000Z","updated_at":"2025-03-28T06:57:39.000Z","dependencies_parsed_at":"2024-02-28T11:48:16.319Z","dependency_job_id":"801ba179-6aad-4a97-9bb9-33b4d9e9d7a4","html_url":"https://github.com/jonocarroll/ntfy","commit_stats":{"total_commits":35,"total_committers":3,"mean_commits":"11.666666666666666","dds":0.3142857142857143,"last_synced_commit":"125a3bf40d9d482efbe8d5fe19f2300a71f478d5"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonocarroll%2Fntfy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonocarroll%2Fntfy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonocarroll%2Fntfy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonocarroll%2Fntfy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jonocarroll","download_url":"https://codeload.github.com/jonocarroll/ntfy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247305934,"owners_count":20917208,"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":[],"created_at":"2024-10-11T21:27:07.207Z","updated_at":"2025-04-05T08:07:16.519Z","avatar_url":"https://github.com/jonocarroll.png","language":"JavaScript","funding_links":["https://github.com/sponsors/jonocarroll","https://github.com/sponsors/binwiederhier"],"categories":["JavaScript"],"sub_categories":[],"readme":"---\noutput: github_document\neditor_options: \n  chunk_output_type: console\n---\n\n\u003c!-- README.md is generated from README.Rmd. Please edit that file --\u003e\n\n```{r, include = FALSE}\nknitr::opts_chunk$set(\n  collapse = TRUE,\n  comment = \"#\u003e\",\n  fig.path = \"man/figures/README-\"\n)\nlibrary(ntfy)\n```\n\n# ntfy \u003cimg src=\"man/figures/logo.png\" align=\"right\" height=\"102\" /\u003e\n\n\u003c!-- badges: start --\u003e\n\u003c!-- badges: end --\u003e\n\n**ntfy** (pronounce: *notify*) is a simple HTTP-based pub-sub notification service. \nIt allows you to send notifications to your phone or desktop via scripts from \nany computer, entirely without signup, cost or setup. It's also [open source][ntfy_gh] if \nyou want to run your own. Visit [ntfy.sh][ntfy] for more details.\n\n{ntfy} is a lightweight R wrapper for this service. The magic sauce is just \n`POST` and `GET` calls equivalent to \n\n```\ncurl -d \"Process Complete 😀\" ntfy.sh/yourSecretTopic \n```\n  \nbut made to work nicely in an R workflow.\n\n## Installation\n\nYou can install the released version of {ntfy} from CRAN\n\n```r\ninstall.packages(\"ntfy\")\n```\n\nYou can install the development version of {ntfy} from GitHub:\n\n```r\n# install.packages(\"remotes\")\nremotes::install_github(\"jonocarroll/ntfy\")\n```\n\n## Functionality\n\nFollow the instructions at [ntfy.sh][ntfy] to install any of the \nmobile apps or use the web app. No sign-up or account is necessary.\n\nChoose a topic (note: this isn't a password-protected service, so choose something \nobscure) and subscribe to it on your device.\n\nAdd the topic as an environment variable, e.g.\n\n```r\nusethis::edit_r_environ()\n\n[...]\n\nNTFY_TOPIC='yourSecretTopic'\n#NTFY_SERVER='https://ntfy.sh'\n```\n\nThe server will automatically be set to https://ntfy.sh unless you specify another.\n\nThis can be confirmed with \n\n```{r server}\nntfy_server()\n```\n\nWith the package loaded, you can now send notifications which should appear on \nyour device\n\n```{r ntfy}\nlibrary(ntfy)\nntfy_send(\"test from R!\")\n```\n\nThis returns the {httr2} response object invisibly, or errors if it was \nunsuccessful.\n\n{ntfy} can be used in many ways. One would be to notify the completion of a process. \nThe `ntfy_done()` function sends a notification with the (default) body\n\n```\nProcess completed at \u003cSys.time()\u003e\n```\n\n```{r done}\nslow_process \u003c- function(x) {\n  Sys.sleep(8) # sleep for 8 seconds\n  x\n}\n\nmtcars |\u003e \n  head() |\u003e \n  slow_process() |\u003e \n  ntfy_done()\n```\n\nwhich results in a notification on subscribed devices\n\n```\nProcess completed at 2025-03-27 08:32:04.644186\n```\n\nWhen using the base R pipe `|\u003e` the piped commands are composed together by the \nparser, so \n\n```\nf() |\u003e \n  g() |\u003e \n    h()\n```\n\nbecomes\n\n```\nh(g(f()))\n```\n\nWe can use this fact to time the running of a process if the last function \n(above, `h()`) is `system.time()`. The `ntfy_done_with_timing()` function does exactly \nthis\n\n```{r done_with_timing}\nmtcars |\u003e \n  head() |\u003e \n  slow_process() |\u003e \n  ntfy_done_with_timing()\n```\n\nwhich sends the notification\n\n```\nProcess completed in 8.003s\n```\n\nThis service can also be used as a progress indicator via the \n[{progressr}][progressr] package - see \n`help(\"handler_ntfy\", package = \"progressr\")` or \nhttps://progressr.futureverse.org/reference/handler_ntfy.html for more \ndetails.\n\nIf you're using a topic on a server that requires authentication, you can pass `auth = TRUE`, along with a username and password:\n\n```r\nntfy_send(\n  \"test from R!\", \n  auth = TRUE, \n  username = \"example\", \n  password = \"super-secret-password\"\n)\n```\n\nAlternatively, you can set these as environment variables and they'll get used \nby `ntfy_send()` automatically:\n\n```r\nusethis::edit_r_environ()\n\n[...]\n\nNTFY_AUTH='TRUE'\nNTFY_USERNAME='example'\nNTFY_PASSWORD='super-secret-password'\n```\n\n```r\nntfy_send(\"test from R!\")\n```\n\nThe history of the notifications sent can be retrieved as well, with control \nover how far back to search (example output shown)\n\n```{r history, eval = FALSE}\nntfy_history(since = \"1h\")\n```\n```{r, echo = FALSE}\nstructure(list(id = c(\"0oDpk4oisfNO\", \"4Fcy9kIL0m6Z\", \"AGXn4q0CirFT\"\n), time = c(1667988383L, 1667988413L, 1667990983L), event = c(\"message\", \n\"message\", \"message\"), topic = c(\"yourSecretTopic\", \"yourSecretTopic\", \"yourSecretTopic\"\n), message = c(\"test from R!\", \"Process completed at 2025-03-27 08:12:15.50997\", \"Process completed in 8.003s\")),\nrow.names = c(NA, -3L\n), class = \"data.frame\")\n```\n\n\n## API\n\nThe full ntfy.sh API should be supported, including sending a title and [tags](https://docs.ntfy.sh/publish/#tags-emojis)\n\n![](man/figures/notification1.png){width=300}\n\n![](man/figures/notification2.png){width=300}\n\n## Images\n\nImages can be sent within notifications by specifying as `image` either the \nfilename or a `ggplot2` object (which will be saved to a temporary file)\n\n```{r}\nlibrary(ggplot2)\np \u003c- ggplot(mtcars, (aes(mpg, wt))) + \n  geom_point() + \n  geom_smooth() + \n  labs(title = \"ggplot images in {ntfy}\")\nntfy_send(\"ggplot2 images in notifications!\", \n          tags = c(\"tada\", \"chart\"),\n          image = p)\n```\n\n## Emoji\n\nSupported tags (emoji) can be sent with the `tags` argument (one or more). These can be searched or shown with `show_emoji()` which will look for a given name in the compatible values, or search for it in the compatible metadata.\n\nThe compatible data is stored as `emoji` \n\n```{r}\ndata(\"emoji\")\nhead(emoji)\n```\n\nwith the tags stored as `tags` for easy auto-complete\n\n```{r}\nntfy_send(message = \"sending with tags!\", \n          tags = c(tags$cat, tags$dog)\n)\n```\n\nThe compatible emoji can be shown with\n\n```{r}\nshow_emoji(\"rofl\")\n```\n\nIf the name is not found in `aliases` (the compatible names) it will\nbe searched in `tags`\n\n```{r}\nshow_emoji(\"lol\")\n\nshow_emoji(\"pet\")\n```\n\nYou can force this behaviour with\n\n```{r}\nshow_emoji(\"dog\", search = TRUE)\n```\n\n## Similar Services\n\n* [{Rpushbullet}][rpushbullet] offers similar functionality, but requires sign-up / an API key\n* [{beepr}][beepr] can play a sound when a process completes\n* [IFTTT][ifttt] has an API and can be configured to send messages with e.g. [nifffty][nifffty]\n* [This blog post][rviews] details many ways to send notifications, via email, text, Slack, and MS Teams\n\n## Privacy\n\nQ: *\"Will you know what topics exist, can you spy on me?\"*\n\nA: Refer to the [FAQ][privacy]\n\n## Contributing\n\nIf this service is useful to you, consider donating to [the developer][ntfy_dev_sp] via GitHub sponsors.\nIf this package is useful to you, [I also accept donations][jonocarroll_sp] via GitHub sponsors.\n\n[ntfy]:https://ntfy.sh\n[ntfy_gh]:https://github.com/binwiederhier/ntfy\n[rpushbullet]:https://cran.r-project.org/package=RPushbullet\n[beepr]:https://cran.r-project.org/package=beepr\n[ifttt]:https://ifttt.com/docs/connect_api\n[rviews]:https://rviews.rstudio.com/2020/06/18/how-to-have-r-notify-you/\n[nifffty]:https://github.com/hrbrmstr/nifffty\n[privacy]:https://ntfy.sh/docs/faq/#will-you-know-what-topics-exist-can-you-spy-on-me\n[ntfy_dev_sp]:https://github.com/sponsors/binwiederhier\n[progressr]:https://github.com/futureverse/progressr\n[jonocarroll_sp]:https://github.com/sponsors/jonocarroll\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjonocarroll%2Fntfy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjonocarroll%2Fntfy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjonocarroll%2Fntfy/lists"}