diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..c181cf5 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +# CHANGELOG + +## v0.1.0 + +First release \ No newline at end of file diff --git a/README.md b/README.md index 70b5ec1..651eca7 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,22 @@ # gotosocial -A library for building GoToSocial bots +A couple of small Python libraries for registering and running bots on a [GoToSocial](https://gotosocial.org/) ActivityPub server. -## client +I wrote these to make it easier for me to port [my bots](https://bots.mikelynch.org) to my bot server, [llull.club](https://llull.club). It's all a bit basic and there are no tests or anything fancy like that. -This is a variant on my Mastodon bot code and hasn't been properly tested yet: I'll document it when I've done that. +## Installation + +This project is maintained with [uv](https://docs.astral.sh/uv/): install it, check out this repo, cd into the directory and then you can run the registration script with the uv commands below and it should take care of dependencies. + +To use the client library you'll have to fiddle around with making it available to whatever Python you're using to run your bots. + +Before you can make a bot which posts to your instance you need to register an app and get an access token with the `register` script. ## register A utility for making it easier to register an app and get an access token for a GoToSocial account - it's a Python script which automates as much of [the client API instructions](https://docs.gotosocial.org/en/latest/api/authentication/) as possible. There's still some manual stuff required for authenticating. -This project is maintained with [uv](https://docs.astral.sh/uv/): install it, check out this repo and then you can run the script with the uv commands below and it should take care of dependencies. - To register an app, you first need to give it an identity on the server - in the examples I've called the server `https://your.server/` and the app `mybot` uv run register -u https://your.server/ -n mybot @@ -29,7 +33,7 @@ Once you authenticate, you should be taken to a page which has a message like: ABIGLONGSTRINGOFLETTERSANDNUMBERS -Copy the out-of-band token and do the third step straight away, as the token will expire. +Copy the out-of-band token and do the third step straight away, as the token will expire fairly quickly. The third step exchanges the above token for a permanent access token, by running the script again in the same directory, passing the OOB token with the -t flag: @@ -38,3 +42,24 @@ The third step exchanges the above token for a permanent access token, by runnin If this is successful, your access token - another, different string of letters and numbers - will be printed to the command prompt. The access token is also written out as a json file with the name `mybot_at.json`. You should now be able to use the access token to post to your GoToSocial account. + +## client + +I don't use this version of the client for my own bots - I use it as one +component of [botclient](https://github.com/spikelynch/botclient) which can +also work against the Mastodon API. + +I have tested this version and provided a couple of example scripts - one for +text posts and one for posts with a single image. Note that the GoToSocial +API allows up to six images - at some point I'll upgrade this to allow +multiple image posts. + +The client is a Python class, GoToSocialBot, which needs the URL of your instance +and the access token generated as per the instructions above. + + bot = GoToSocialBot() + bot.auth({ "base_url": "https://llull.club", "access_token": "..." }) + bot.post("This is an automated post!", { "spoiler_text": "bot post" }) + bot.post_image("myimage.png", "This is an automated image!", { "spoiler_text": "bot post" }) + +The second argument to post() and third argument to post_imate() is a dict of options which are passed straight through to the API - details available [here](https://docs.gotosocial.org/en/latest/api/swagger/). \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 96a40d8..b52a645 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ version = "0.1.0" description = "A Python library for GoToSocial clients" readme = "README.md" authors = [ - { name = "Mike Lynch", email = "m.lynch@sydney.edu.au" } + { name = "Mike Lynch", email = "mike@llull.club" } ] requires-python = ">=3.9" dependencies = [ diff --git a/src/gotosocial/bot_example.py b/src/gotosocial/bot_example.py new file mode 100644 index 0000000..d66f5a4 --- /dev/null +++ b/src/gotosocial/bot_example.py @@ -0,0 +1,21 @@ +# example bot script + +from gotosocial.client import GoToSocialBot +import json + +CONFIG = "config.json" + +# the config file should look like +# +# { +# "base_url": "https://your.gts.instance.here", +# "access_token": "YOURACCESSTOKENGOESHERE" +# } +# + +if __name__ == "__main__": + with open(CONFIG, "r") as cfh: + cf = json.load(cfh) + bot = GoToSocialBot() + bot.auth(cf) + bot.post("A test post", {"spoiler_text": "test post"}) diff --git a/src/gotosocial/image_bot_example.py b/src/gotosocial/image_bot_example.py new file mode 100644 index 0000000..20d86c7 --- /dev/null +++ b/src/gotosocial/image_bot_example.py @@ -0,0 +1,21 @@ +# example bot script + +from gotosocial.client import GoToSocialBot +import json + +CONFIG = "config.json" + +# the config file should look like +# +# { +# "base_url": "https://your.gts.instance.here", +# "access_token": "YOURACCESSTOKENGOESHERE" +# } +# + +if __name__ == "__main__": + with open(CONFIG, "r") as cfh: + cf = json.load(cfh) + bot = GoToSocialBot() + bot.auth(cf) + bot.post_image("./my_image.png", "A test post", {"spoiler_text": "test post"}) diff --git a/src/gotosocial/register.py b/src/gotosocial/register.py index 77a9fac..a261e22 100644 --- a/src/gotosocial/register.py +++ b/src/gotosocial/register.py @@ -42,7 +42,9 @@ class Application: print("Visit this URL in a private browser window to authenticate:") print(auth_url) print("\nThen run this script again with the OOB token, like:") - print("> uv run register -u {self.base_ur} -n {self.name} -t OOB_TOKEB") + print( + "> uv run register -u {self.base_ur} -n {self.name} -t REPLACEMEWITHTOKEN" + ) return True except Exception as e: print("Something went wrong:")