Liking cljdoc? Tell your friends :D


Clojars Project

Warning This is very much a work-in-progress. Only a tiny bit of the ActivityPub spec is implemented, and it definitely does not conform to all of the nuances expected yet.

clj-activitypub is a set of utilities that can be combined together to create a fully-functional ActivityPub server.


Docs are available at


  • activitypub-core — The base functionality for generating HTTP headers (i.e. Signature, Digest), building ActivityPub activities and objects, and sending requests to remote servers.
  • activitypub-ring — A Ring-specific implementation that builds on activitypub-core, providing default routes and handlers for making an ActivityPub-compliant server.


;; ActivityPub object handling
(require '[clj-activitypub.core :as activitypub])
;; Translate account handles into ActivityPub URL-based IDs
(require '[clj-activitypub.webfinger :as webfinger])
;; Build and perform network requests
(require '[ :as activitypub-net])

Reading remote data

;; Fetching user account on remote server

(require '[clojure.pprint :refer [pprint]])

;;; Use any ActivityPub account handle you like
(def account-handle "")

;;; Retrieve the account details from its home server
(def account
 (-> account-handle
     (select-keys [:name :preferredUsername :summary])))

;;; Examine what you got back!
(pprint account) ;; => ({:name "Jahfer",
                 ;;      :preferredUsername "jahfer",
                 ;;      :summary "<p>Hello world!</p>"})
;; Fetching a list of users from multiple servers
(-> ""
    (count)) ;; => 80

Pushing data to remote servers

Before POSTing data to a remote server, you'll want to create a local key/value pair in the /keys directory. You'll also need a corresponding HTTP endpoint to serve the actor data, which is used to verify the signature of the message by the remote server.

$ openssl genrsa -out keys/private.pem 2048
$ openssl rsa -in keys/private.pem -outform PEM -pubout -out keys/public.pem
;; Submitting a Create activity for an Object to remote server
(require '[clj-http.client :as client])
(require '[ :as json])

(def activity
  (->> {:id 2
        :type :note
        :cc ""
        :content "<p>Hello world!</p>"}
       (activitypub/obj activity-config)
       (activitypub/activity activity-config :create)))

;;; Fetch the inboxes connected to the :cc addresses
(let [targets (activitypub-net/delivery-targets! activity)]
  (doseq [inbox targets]
    ;;; At minimum, the Host is required to build the authentication headers
    (let [request {:headers {"Host" (.getHost (URI. inbox))}
                   :body (json/write-str activity)}]
      ;;; Submit request to remote inboxes
        (assoc request
               :headers (activitypub-net/auth-headers activity-config request)
               :throw-exceptions false)))))

Running tests

There are two libraries within this package: activitypub-core and activitypub-ring. In order to run tests, the following command must be run from inside either of those directories:

# clj-activitypub/activitypub_core
$ clj -X:test


Can you improve this documentation? These fine people already did:
Jahfer Husain & Simon Brooke
Edit on GitHub

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close