For emacs lovers: I extended @dgold’s code to post to micro.blog from emacs. Now you can include images in the markdown buffer to be posted to micro.blog, and they will be uploaded and linked properly in your published post!

Emacs image

And here’s the code (or, alternatively, see gist):

(require 'request)

(setq mb-emacs-app-token "123456789") ;; create this in account -> app tokens -> edit apps
(setq mb-micropub-endpoint "https://micro.blog/micropub")
(setq mb-destination-address "https://your.micro.blog")
(setq mb-image-upload-timeout 20)  ;; seconds

(defun mb-get-media-endpoint ()
  (cdr (assoc "media-endpoint"
              (let (result)
                (request
                  mb-micropub-endpoint
                  :params '(("q" . "config"))
                  :type "GET"
                  :sync t
                  :timeout: 10
                  :parser 'json-read
                  :headers  `(("Content-Type" . "application/json")
                              ("Authorization".,(format "Bearer %s" mb-emacs-app-token)))
                  :complete (cl-function
                             (lambda (&key data &allow-other-keys)
                               (setq result data)))) 
                (if result 
                    result
                  (error "Can't get media endpoint")))
              #'string=)))

(defun mb-upload-image (img-path media-endpoint)
  "Post inline images."
  (cdr (assoc "url"
              (let ((result))
                (request
                  (concat media-endpoint 
                          (if (boundp 'mb-destination-address) (concat "?mp-destination=" mb-destination-address)))
                  :type "POST"
                  :files `(("file" . ,img-path))
                  :headers  `(("Content-Type" . "multipart/form-data")
                              ("Authorization".,(format "Bearer %s" mb-emacs-app-token)))
                  :sync t
                  :timeout mb-image-upload-timeout
                  :parser 'json-read
                  :success (cl-function 
                            (lambda (&key data &allow-other-keys)
                              (setq result data))))
                (if result 
                    result
                  (error "Error in  uploading.")))
              #'string=)))

(defun mb-markdown-upload-images-substitute-links ()
  "Upload images to micro.blog and substitute their local links with the upload locations."
  (interactive)
  (save-excursion
    (save-restriction
      (let ((media-endpoint (mb-get-media-endpoint)))
        (widen)
        (goto-char (point-min))
        (while (re-search-forward markdown-regex-link-inline nil t)
          (let ((start (match-beginning 0))
                (imagep (match-beginning 1))
                (end (match-end 0))
                (file (match-string-no-properties 6)))
            (when (and imagep
                       (not (zerop (length file))))
              (when (file-exists-p file)
                (let* ((abspath (if (file-name-absolute-p file)
                                    file
                                  (concat default-directory file)))
                       (img-upload-url (save-match-data (mb-upload-image abspath media-endpoint))))
                  (replace-match img-upload-url t t nil 6))))))))))

(defun mb-post-buffer ()
  "Post current buffer to micro.blog (possibly as draft)."
  (interactive)
  (if (yes-or-no-p "Are you sure you want to post this?")
      (save-restriction
        (widen)
        (let ((buffer-contents (buffer-substring-no-properties (point-min) (point-max)))
              (mb-post-name (read-string "Enter post name (leave empty if none):"))
              (mb-post-status `(post-status . [,(if (yes-or-no-p "Post as draft?") "draft" "published")])))
          ;; copy content of current buffer to new buffer,
          ;; then upload eventual linked images, substitute links with the upload locations, send buffer to microblog
          (with-current-buffer (generate-new-buffer "post2mb")
            (goto-char (point-min))
            (insert buffer-contents)
            (goto-char (point-min))
            (mb-markdown-upload-images-substitute-links)
            (request
              (concat mb-micropub-endpoint
                      (if (boundp 'mb-destination-address) (concat "?mp-destination=" mb-destination-address)))
              :type "POST"
              :data (json-encode `((type . ["h-entry"])
                                   (properties
                                    (content . [,(buffer-substring-no-properties (point-min) (point-max))])
                                    (name . [,mb-post-name]) ,mb-post-status)))
              :headers  `(("Content-Type" . "application/json")
                          ("Authorization".,(format "Bearer %s" mb-emacs-app-token)))
              :success (cl-function 
                        (lambda (&key data &allow-other-keys)
                          (message "Success.")))))))))

If you have enjoyed this post, and you are looking for experts in the field of Machine Learning for the Internet of Things, check us out at foldAI, drop me an email, or contact me on LinkedIn