Skip to content

Instantly share code, notes, and snippets.

@jakekara
Last active November 19, 2022 19:41
Show Gist options
  • Save jakekara/d973b283da32238e6df61a7f38b08035 to your computer and use it in GitHub Desktop.
Save jakekara/d973b283da32238e6df61a7f38b08035 to your computer and use it in GitHub Desktop.
deliver.py - send activitypub payload to mastodon server
"""
Deliver an ActivityPub message to an inbox
This is largely based on a ruby example `deliver.rb` from this blog post:
https://blog.joinmastodon.org/2018/06/how-to-implement-a-basic-activitypub-server/
"""
from datetime import datetime
from time import mktime
import base64
from hashlib import sha256
from wsgiref.handlers import format_date_time
from OpenSSL import crypto
import requests
def http_date_str():
now = datetime.now()
stamp = mktime(now.timetuple())
date_str = format_date_time(stamp)
return date_str
def deliver(
*,
document,
private_key_path,
inbox_url,
host
):
document_digest = "SHA-256=" + base64.b64encode(sha256(document.encode()).digest()).decode()
date_str = http_date_str()
signed_string = f"(request-target): post /inbox\nhost: {host}\ndate: {date_str}\ndigest: {document_digest}"
private_key = crypto.load_privatekey(crypto.FILETYPE_PEM, open(private_key_path).read())
signature = base64.b64encode(crypto.sign(private_key, signed_string.encode(), "sha256")).decode()
header = f'keyId="https://your-static-site.example.com/activitypub/actors/you.json#main-key",headers="(request-target) host date digest",signature="{signature}"'
response = requests.post(
inbox_url,
headers={ 'Host': host, 'Date': date_str, 'Signature': header, 'Digest': document_digest },
data=document
)
return response
response = deliver(
document=open("activitypub/activities/accept-follow.json").read(),
private_key_path="private.pem",
inbox_url=RECIPIENT_INBOX
host=HOST_SERVER
)
print(response.status_code)
print(response.content)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment