Skip to content

Instantly share code, notes, and snippets.

@priyadarshan
Forked from gkbrk/lobsters-mastodon.lisp
Created August 22, 2018 14:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save priyadarshan/8ad035ba21975a8eb322661af97b2436 to your computer and use it in GitHub Desktop.
Save priyadarshan/8ad035ba21975a8eb322661af97b2436 to your computer and use it in GitHub Desktop.
Common lisp Mastodon bot
(ql:quickload :drakma)
(ql:quickload :cl-json)
(ql:quickload :plump)
(ql:quickload :babel)
(ql:quickload :tooter)
(ql:quickload :split-sequence)
(defvar *feed-path* "https://lobste.rs/rss")
(setf drakma:*drakma-default-external-format* :UTF-8)
(defstruct lobsters-post
title
url
guid
)
(defun get-first-text (tag node)
"Search the XML node for the given tag name and return the text of the first one"
(plump:render-text (car (plump:get-elements-by-tag-name node tag)))
)
(defun parse-rss-item (item)
"Parse an RSS item into a lobsters-post"
(let* ((post (make-lobsters-post))
)
(setf (lobsters-post-title post) (get-first-text "title" item))
(setf (lobsters-post-url post) (get-first-text "link" item))
(setf (lobsters-post-guid post) (get-first-text "guid" item))
post
))
(defun get-rss-feed ()
"Gets rss feed of Lobste.rs"
(let* ((xml-text (babel:octets-to-string (drakma:http-request *feed-path*)))
(plump:*tag-dispatchers* plump:*xml-tags*)
(xml-tree (plump:parse xml-text))
(items (plump:get-elements-by-tag-name xml-tree "item"))
)
(reverse (map 'list #'parse-rss-item items))
))
(defun get-mastodon-client ()
(make-instance 'tooter:client
:base "https://botsin.space"
:name "lobsterbot"
:key "secret"
:secret "secret"
:access-token "secret")
)
(defun send-toot (item)
"Takes a lobsters-post and posts it on Mastodon"
(tooter:make-status (get-mastodon-client) (format nil "~a - ~a ~a"
(lobsters-post-title item)
(lobsters-post-guid item)
(lobsters-post-url item)))
)
(defun is-link-seen (item)
"Returns if we have processed a link before"
(with-open-file (stream "links.txt"
:if-does-not-exist :create)
(loop for line = (read-line stream nil)
while line
when (string= line (lobsters-post-guid item)) return t))
)
(defun record-link-seen (item)
"Writes a link to the links file to keep track of it"
(with-open-file (stream "links.txt"
:direction :output
:if-exists :append
:if-does-not-exist :create)
(format stream "~a~%" (lobsters-post-guid item)))
)
(defun run-mastodon-bot ()
(let* ((first-ten (subseq (get-rss-feed) 0 10))
(new-links (remove-if #'is-link-seen first-ten))
)
(loop for item in new-links do
(send-toot item)
(record-link-seen item))
))
(run-mastodon-bot)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment