{"id":17024050,"url":"https://github.com/mackuba/minisky","last_synced_at":"2025-04-07T15:10:05.629Z","repository":{"id":191734744,"uuid":"685191208","full_name":"mackuba/minisky","owner":"mackuba","description":"A minimal client of Bluesky/ATProto API","archived":false,"fork":false,"pushed_at":"2024-12-27T16:17:38.000Z","size":94,"stargazers_count":42,"open_issues_count":3,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-02T23:39:46.545Z","etag":null,"topics":["atproto","atprotocol","bluesky","xrpc"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"zlib","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mackuba.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-08-30T17:47:52.000Z","updated_at":"2025-04-01T08:56:50.000Z","dependencies_parsed_at":"2023-08-31T12:00:52.846Z","dependency_job_id":"6992f599-d938-4c5a-ba30-b5eaf36bb464","html_url":"https://github.com/mackuba/minisky","commit_stats":null,"previous_names":["mackuba/minisky"],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mackuba%2Fminisky","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mackuba%2Fminisky/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mackuba%2Fminisky/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mackuba%2Fminisky/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mackuba","download_url":"https://codeload.github.com/mackuba/minisky/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247675607,"owners_count":20977378,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["atproto","atprotocol","bluesky","xrpc"],"created_at":"2024-10-14T07:24:15.753Z","updated_at":"2025-04-07T15:10:05.568Z","avatar_url":"https://github.com/mackuba.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Minisky 🌤\n\nMinisky is a minimal client of the Bluesky (ATProto) API. It provides a simple API client class that you can use to log in to the Bluesky API and make any GET and POST requests there. It's meant to be an easy way to start playing and experimenting with the AT Protocol API.\n\nThis is designed as a low-level XRPC client library - it purposefully does not include any convenience methods like \"get posts\" or \"get profile\" etc., it only provides base components that you could use to build a higher level API.\n\n\u003e [!NOTE]\n\u003e ATProto Ruby gems collection: [skyfall](https://github.com/mackuba/skyfall) | [blue_factory](https://github.com/mackuba/blue_factory) | [minisky](https://github.com/mackuba/minisky) | [didkit](https://github.com/mackuba/didkit)\n\n\n## Installation\n\nTo use Minisky, you need a reasonably new version of Ruby (2.6+). Such version should be preinstalled on macOS Big Sur and above and some Linux systems. Otherwise, you can install one using tools such as [RVM](https://rvm.io), [asdf](https://asdf-vm.com), [ruby-install](https://github.com/postmodern/ruby-install) or [ruby-build](https://github.com/rbenv/ruby-build), or `rpm` or `apt-get` on Linux.\n\nTo install the Minisky gem, run the command:\n\n    [sudo] gem install minisky\n\nOr alternatively, add it to the `Gemfile` file for Bundler:\n\n    gem 'minisky', '~\u003e 0.5'\n\n\n## Usage\n\nAll calls to the XRPC API are made through an instance of the `Minisky` class. There are two ways to use the library: with or without authentication.\n\n\n### Unauthenticated access\n\nYou can access parts of the API anonymously without any authentication. This currently includes: read-only `com.atproto.*` routes on the PDS (user's data server) and most read-only `app.bsky.*` routes on the AppView server.\n\nThis allows you to do things like:\n\n- look up specific records or lists of all records of a given type in any account (in their raw form)\n- look up profile information about any account\n- load complete threads or users' profile feeds from the AppView\n\nTo use Minisky this way, create a `Minisky` instance, passing the API hostname string and `nil` as the configuration in the arguments. Use the hostname `api.bsky.app` or `public.api.bsky.app` for the AppView, or a PDS hostname for the `com.atproto.*` raw data endpoints:\n\n```rb\nrequire 'minisky'\n\nbsky = Minisky.new('api.bsky.app', nil)\n```\n\n\u003e [!NOTE]\n\u003e To call PDS endpoints like `getRecord` or `listRecords`, you need to connect to the PDS of the user whose data you're loading, not to yours (unless it's the same one). Alternatively, you can use the `bsky.social` \"entryway\" PDS hostname for any Bluesky-hosted accounts, but this will not work for self-hosted accounts.\n\u003e\n\u003e To look up the PDS hostname of a user given their handle or DID, you can use the [didkit](https://github.com/mackuba/didkit) library.\n\u003e\n\u003e For the AppView, `api.bsky.app` connects directly to Bluesky's AppView, and `public.api.bsky.app` to a version with extra caching that will usually be faster.\n\n\n### Authenticated access\n\nTo use the complete API including posting or reading your home feed, you need to log in using your account info and get an access token which will be added as an authentication header to all requests.\n\nFirst, you need to create a `.yml` config file with the authentication data, e.g. `bluesky.yml`. It should look like this:\n\n```yaml\nid: my.bsky.username\npass: very-secret-password\n```\n\nThe `id` can be either your handle, or your DID, or the email you've used to sign up. It's recommended that you use the \"app password\" that you can create in the settings instead of your main account password.\n\n\u003e [!NOTE]\n\u003e Bluesky has recently implemented OAuth, but Minisky doesn't support it yet - it will be added in a future version. App passwords should still be supported for a fairly long time.\n\nAfter you log in, this file will also be used to store your access \u0026 request tokens and DID. The data in the config file can be accessed through a `user` wrapper property that exposes them as methods, e.g. the password is available as `user.pass` and the DID as `user.did`.\n\nNext, create the Minisky client instance, passing your PDS hostname (for Bluesky-hosted PDSes, you can use either `bsky.social` or your specific PDS like `amanita.us-east.host.bsky.network`) and the name of the config file:\n\n```rb\nrequire 'minisky'\n\nbsky = Minisky.new('bsky.social', 'bluesky.yml')\n```\n\nMinisky automatically manages your access and refresh tokens - it will first log you in using the login \u0026 password, and then use the refresh token to update the access token before the request when it expires.\n\n\n### Making requests\n\nWith a `Minisky` client instance, you can make requests to the Bluesky API using `get_request` and `post_request`:\n\n```rb\njson = bsky.get_request('com.atproto.repo.listRecords', {\n  repo: bsky.user.did,\n  collection: 'app.bsky.feed.like'\n})\n\njson['records'].each do |r|\n  puts r['value']['subject']['uri']\nend\n\nbsky.post_request('com.atproto.repo.createRecord', {\n  repo: bsky.user.did,\n  collection: 'app.bsky.feed.post',\n  record: {\n    text: \"Hello world!\",\n    createdAt: Time.now.iso8601,\n    langs: [\"en\"]\n  }\n})\n```\n\nIn authenticated mode, the requests use the saved access token for auth headers automatically. You can also pass `auth: false` or `auth: nil` to not send any authentication headers for a given request, or `auth: sometoken` to use a specific other token. In unauthenticated mode, sending of auth headers is disabled.\n\nThe third useful method you can use is `#fetch_all`, which loads multiple paginated responses and collects all returned items on a single list (you need to pass the name of the field that contains the items in the response). Optionally, you can also specify a limit of pages to load as `max_pages: n`, or a break condition `break_when` to stop fetching when any item matches it. You can use it to e.g. to fetch all of your posts from the last 30 days but not earlier:\n\n```rb\ntime_limit = Time.now - 86400 * 30\n\nposts = bsky.fetch_all('com.atproto.repo.listRecords',\n  { repo: bsky.user.did, collection: 'app.bsky.feed.post' },\n  field: 'records',\n  max_pages: 10,\n  break_when: -\u003e(x) { Time.parse(x['value']['createdAt']) \u003c time_limit })\n```\n\nThere is also a `progress` option you can use to print some kind of character for every page load. E.g. pass `progress: '.'` to print dots as the pages are loading:\n\n```rb\nlikes = bsky.fetch_all('com.atproto.repo.listRecords',\n  { repo: bsky.user.did, collection: 'app.bsky.feed.like' },\n  field: 'records',\n  progress: '.')\n```\n\nThis will output a line like this:\n\n```\n.................\n```\n\nYou can find more examples in the [example](https://github.com/mackuba/minisky/tree/master/example) directory.\n\n\n## Customization\n\nThe `Minisky` client currently supports such configuration options:\n\n- `default_progress` - a progress character to automatically use for `#fetch_all` calls (default: `.` when in an interactive console, `nil` otherwise)\n- `send_auth_headers` - whether auth headers should be added by default (default: `true` in authenticated mode)\n- `auto_manage_tokens` - whether access tokens should be generated and refreshed automatically when needed (default: `true` in authenticated mode)\n\nIn authenticated mode, you can disable the `send_auth_headers` option and then explicitly add `auth: true` to specific requests to include a header there.\n\nYou can also disable the `auto_manage_tokens` option - in this case you will need to call the `#check_access` method before a request to refresh a token if needed, or alternatively, call either `#login` or `#perform_token_refresh`.\n\n\n### Using your own class\n\nInstead of using the `Minisky` class, you can also make your own class that includes the `Minisky::Requests` module and provides a different way to load \u0026 save the config, e.g. from a JSON file:\n\n```rb\nclass BlueskyClient\n  include Minisky::Requests\n\n  attr_reader :config\n\n  def initialize(config_file)\n    @config_file = config_file\n    @config = JSON.parse(File.read(@config_file))\n  end\n\n  def host\n    'bsky.social'\n  end\n\n  def save_config\n    File.write(@config_file, JSON.pretty_generate(@config))\n  end\nend\n```\n\nIt can then be used just like the `Minisky` class:\n\n```rb\nbsky = BlueskyClient.new('config/access.json')\nbsky.get_request(...)\n```\n\nThe class needs to provide:\n\n- a `host` method or property that returns the hostname of the server\n- a `config` property which returns a hash or a hash-like object with the configuration and user data - it needs to support reading and writing arbitrary key-value pairs with string keys\n- a `save_config` method which persists the config object to the chosen storage\n\n\n## Credits\n\nCopyright © 2024 Kuba Suder ([@mackuba.eu](https://bsky.app/profile/mackuba.eu)).\n\nThe code is available under the terms of the [zlib license](https://choosealicense.com/licenses/zlib/) (permissive, similar to MIT).\n\nBug reports and pull requests are welcome 😎\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmackuba%2Fminisky","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmackuba%2Fminisky","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmackuba%2Fminisky/lists"}