mastodon.el: Copy toot URL after posting; also, copying just this post with 11ty
| mastodon, emacs, 11tyI often want to copy the toot URL after posting a new toot about a blog post so that I can update the blog post with it. Since I post from Emacs using mastodon.el, I can probably figure out how to get the URL after tooting. A quick-and-dirty way is to retrieve the latest status.
(defvar my-mastodon-toot-posted-hook nil "Called with the item.") (defun my-mastodon-copy-toot-url (toot) (interactive (list (my-mastodon-latest-toot))) (kill-new (alist-get 'url toot))) (add-hook 'my-mastodon-toot-posted-hook #'my-mastodon-copy-toot-url) (defun my-mastodon-latest-toot () (interactive) (require 'mastodon-http) (let* ((json-array-type 'list) (json-object-type 'alist)) (car (mastodon-http--get-json (mastodon-http--api (format "accounts/%s/statuses?count=1&limit=1&exclude_reblogs=t" (mastodon-auth--get-account-id))) nil :silent)))) (with-eval-after-load 'mastodon-toot (when (functionp 'mastodon-toot-send) (advice-add #'mastodon-toot-send :after (lambda (&rest _) (run-hook-with-args 'my-mastodon-toot-posted-hook (my-mastodon-latest-toot))))) (when (functionp 'mastodon-toot--send) (advice-add #'mastodon-toot--send :after (lambda (&rest _) (run-hook-with-args 'my-mastodon-toot-posted-hook (my-mastodon-latest-toot))))))
I considered overriding the keybinding in
mastodon-toot-mode-map
, but I figured using
advice would mean I can copy things even after
automated toots.
A more elegant way to do this might be to modify
mastodon-toot-send
to run-hook-with-args
a
variable with the response
as an argument, but
this will do for now.
I used a hook in my advice so that I can change the behaviour from other functions. For example, I have some code to compose a toot with a link to the current post. After I send a toot, I want to check if the toot contains the current entry's permalink. If it has and I don't have a Mastodon toot field yet, maybe I can automatically set that property, assuming I end up back in the Org Mode file I started it from.
(defun my-mastodon-org-maybe-set-toot-url (toot) (when (derived-mode-p 'org-mode) (let ((permalink (org-entry-get-with-inheritance "EXPORT_ELEVENTY_PERMALINK"))) (when (and permalink (string-match (regexp-quote permalink) (alist-get 'content toot)) (not (org-entry-get-with-inheritance "MASTODON"))) (save-excursion (goto-char (org-find-property "EXPORT_ELEVENTY_PERMALINK" permalink)) (org-entry-put (point) "EXPORT_MASTODON" (alist-get 'url toot)) (message "Toot URL set: %s, republish if needed" toot)))))) (add-hook 'my-mastodon-toot-posted-hook #'my-mastodon-org-maybe-set-toot-url)
If I combine that with a development copy of my blog that ignores most of my posts so it compiles faster and a function that copies just the current post's files over, I can quickly make a post available at its permalink (which means the link in the toot will work) before I recompile the rest of the blog, which takes a number of minutes.
(defun my-org-11ty-copy-just-this-post () (interactive) (when (derived-mode-p 'org-mode) (let ((file (org-entry-get-with-inheritance "EXPORT_ELEVENTY_FILE_NAME")) (path my-11ty-base-dir)) (call-process "chmod" nil nil nil "ugo+rwX" "-R" (expand-file-name file (expand-file-name "_local" path))) (call-process "rsync" nil (get-buffer-create "*rsync*") nil "-avze" "ssh" (expand-file-name file (expand-file-name "_local" path)) (concat "web:/var/www/static-blog/" file)) (browse-url (concat my-blog-base-url (org-entry-get-with-inheritance "EXPORT_ELEVENTY_PERMALINK"))))))
The proper blog updates (index page, RSS/ATOM feeds, category pages, prev/next links, etc.) can happen when the publishing is finished.
So my draft workflow is:
- Write the post.
- Export it to the local
NODE_ENV=dev npx eleventy --serve --quiet
with ox-11ty. - Check that it looks okay locally.
- Use
my-org-11ty-copy-just-this-post
and confirm that it looks fine. - Compose a toot with my-mastodon-11ty-toot-post and check if sending it updates the Mastodon toot.
- Re-export the post.
- Run my blog publishing process.
NODE_ENV=production npx eleventy --quiet
and then rsync.
Let's see if this works…