-
-
Save vanangamudi/644c0494100528c3b88ad5ffc59c55cf to your computer and use it in GitHub Desktop.
Common lisp Mastodon bot
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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