Skip to content

Instantly share code, notes, and snippets.

@33mhz
Last active January 4, 2021 02:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 33mhz/eee360e4ff9c45c4e9e7ae9ce1d447d1 to your computer and use it in GitHub Desktop.
Save 33mhz/eee360e4ff9c45c4e9e7ae9ce1d447d1 to your computer and use it in GitHub Desktop.
pnut v1.0 release notes

v0.9.6 will continue to be supported as-is until further notice except that user streams and app streams are no longer supported for v0.9.6. Streams will only work on v1 going forward.

All items below affect v1.0.0, and most do not affect v0.9.6. If it also affects v0.9.6, it will be marked with v0.9.6+.

Features

New Channel Fields

  • recent_deleted_message

Previously, channel.recent_message_id referenced the last message in a channel.

Now, recent_message_id will always reference the last non-deleted message in the channel. If there are no messages or only deleted messages in a channel, this field will not be set.

An additional field has been added to channels, called recent_deleted_message_id. This will only be included if the last message in a channel is a deleted message.

When handling stream markers for channels, you will generally not need to mind deleted messages more recent than the recent_message_id in a channel. If you make no change to your app, you will simply never have a recent_message or recent_message_id that is deleted.

  • created_at

Channels now include a created_at field like other objects. Because the date wasn't collected before now, previously created channels will have created_at retroactively set to the date when the first message was created in the channel. Channels without messages will have it set to "now".

GET /channels/search can now be searched by created_before and created_after.

  • has_sticky_messages

Channels now include has_sticky_messages boolean, indicating if there are sticky messages in the channel.

Chat Room Name on Messages in Streams

App and User streams now include the field meta.channel_name when messages are sent from channels of io.pnut.core.chat type.

Chat Room Rich Text Description

Chat room description is now handled similarly to Post, Message, and User content objects. Instead of a plain text string, io.pnut.core.chat-settings-type raw items now have a parsed string for the room description; a whole content-like object will be embedded, with entities and rendered HTML alongside.

NSFW Reposts

When reposting a post, the repost can be marked as NSFW even when the original was not. Simply including JSON with is_nsfw: true when reposting will do.

Search Improvements

  • by Attached File or Poll

Posts, messages, polls, and channels can be searched by what files or polls are attached to them. This way, for example, when you are looking at a file, you can look up if there are any posts that reference the file in their raw data.

file_id and poll_id have been added as filters on various searches.

Additionally, file_kinds has been added as a search filter for messages and posts, to only return ones with an oEmbed-attached file of the specified kinds.

  • by Created At

All search endpoints can now search by created_before and created_after.

Polls Added to App Streams

The polls app stream type is now functional. The stream sends updates on creation, deletion, every user's first response to a poll, and when the poll closes. Because poll results can only be seen after the poll ends, updates only include the poll object without current results unless it is closed.

RSS Feeds Include Media

Now RSS feeds include OEmbed pictures and audio files in the RSS stream. The feed item descriptions will include HTML, which means in particular they will now include HTML links.

Breaking Changes

User Streams and App Streams disabled for v0 v0.9.6

User and App streams no longer work on v0 of the API. They are only available on v1.

All of the other 1.0 breaking changes on the streamed objects will have to be handled for notification servers, bots, and other projects using streams.

file, token, and follow User Stream Events Include Data

file, token, and follow events previously only included the meta field identifying the ID of the object that had been acted against. Now User Streams include the actual data from these events.

Files and tokens are included as the data object. When someone follows or unfollows someone, both of their user streams would receive a follow-type event with data in this format:

{
  "data": {
    "followed_user": "...user object...",
    "user": "...user object..."
  }
}

Private Message ACL Changes

Private message channels no longer have an "owner" or "creator" of the channel. The owner used to be in its own owner field, and clients had to add that user to the list of users in the channel.acl.write.user_ids. Now all users in the channel will be included in channel.acl.write.user_ids, and the channel.user and channel.user_id will not be set at all.

This more accurately reflects the capabilities of the users in a private message, and removes a step or two from how clients parse them.

Poll Response Handling Changed

  1. The legacy poll response endpoint has been removed.

PUT /polls/{poll_id}/response/{position} has been removed in favor of PUT /polls/{poll_id}/response.

  1. Poll responses can be changed any time up until the poll closes.

An empty positions will indicate to clear any responses for the user, but they will still be notified by E-mail when the poll closes, if they have the option enabled on https://pnut.io.

  1. Poll responses cannot be viewed until after the poll closes.

  2. GET /users/me/polls/responses

This endpoint returns a list of limited poll objects embedded with the authenticated user's responses to the polls. This change is just aligning the embedded poll objects more with normal poll objects:

The field poll.poll_id has been renamed poll.id, and the field poll.created_at has been added in the response.

Raw Objects Reformatted

Raw objects had been a list of type-value pairs, like so:

[
  {
    "type": "io.pnut.core.oembed",
    "value": {}
  },
  {
    "type": "arbitrary_raw_type",
    "value": {}
  }
]

Now, there are lists of values for each type, like so:

{
  "io.pnut.core.oembed": [
    {},
    {}
  ],
  "arbitrary_raw_type": [
    {},
    {}
  ]
}

User Objects No Longer Overloaded

User objects are included on many objects. There are a handful of cases where the user will not be available to be included on an object. For example, if the user is deleted, blocked, or the call has specified not to include the user, with a ?include_user=0 parameter.

In most of these cases, the user field still exists on API v0, with a value of the user's ID, instead of including the whole user object.

On v1 of the API, when a user is not included, the user field will be absent and a separate user_id field will be included.

Inversely, when ?include_limited_user=1 is set on channel calls, the user_ids field will remain a list of the user IDs, and a separate users field will be included.

User "users" Count Removed

User objects no longer include counts.users.

Channel Owner Renamed

The channel owner field is now user, to be in line with all other API objects.

Message is_sticky Always Present

The field is_sticky is now always present on messages, even when false.

References to "link" Now "url"

These fields in the API have been changed from link to url:

  • source.link on posts, messages, files, polls
  • the link in a link entity is now url (but entities.links is still "links")
  • client.link
  • post and message search terms links and link_domains are now urls and url_domains

Users

  • verified.link
  • avatar_image.link
  • cover_image.link

Posts

  • GET /posts/explore link

Files (and derived_files)

  • link
  • link_short is now url_short
  • link_expires_at is now url_expires_at

Post Revision Now an Integer

post.revision, if included on the post, is now an integer instead of a string.

System Stats Endpoint Adjustment

  • GET /sys/stats

The data returned is no longer a child of a counts field.

counts.users.today has been replaced with users.active, listing the last 7 days' account totals that touched the API, not including the current day.

System Config Endpoint Adjustment

  • GET /sys/config

Removed:

  • post.repost_max_length

Added:

  • file.audio_max_size_bytes
  • file.max_size_bytes
  • post.seconds_for_revision
  • user.name_max_length
  • user.presence_max_length

Changed:

  • rate_limit.anonymous.seconds_between_reset is now "read_reset_seconds"
  • user.username_max_length was erroneously referring to the name max length, not username max length

Text Render Endpoint Adjustment

  • POST /text/process

The entities are now placed within an entities field, more like posts and other standard objects.

Search Changes

  • GET /channels/search

The field is_private has been removed from channel search, and instead is_public can be set to 1, 0, or not set at all.

  • GET /polls/search

The user_id field has been changed to creator_id on poll searches, to be consistent with other searches.

  • GET /posts/search

Searching posts without any parameters set will now return results. Previously, it would return an empty list, but now it is possible to effectively get a "Global" stream (with bot- and feed-type accounts included) from the search by not setting any filters or queries.

Also, if is_reply is set to 0 now, results will only include posts that are not replies. Previously, this only mattered if set to 1.

  • GET /users/search

The types field on user search has been renamed user_types like in other searches, for clarity and consistency.

User search no longer requires the q field, and can return unbounded results, then. For example, you can now look up "all bots" without a search term.

Minor Changes

"basic" Authentication Scope Always Included v0.9.6+

Whether your app requests the basic scope or not, it will now always be included if a user authorizes your app. This will not change what is actually allowed, but will add transparency around what your app can do when someone authorizes it.

Error Responses

Many endpoints' error messages have improved when a field is populated with the wrong type. Where previously it would simply say Wrong Type, now usually it will say which field and type was wrong. Additionally, some resources, such as GET posts/{id}, will now return a 400 error instead of a 404, if the wrong type is used for the lookup.

Accepted Actions Against Reposts

It used to be that reposting, replying to, or bookmarking a repost of a post would respond with a 400 error.

Now, these actions will automatically be done to the underlying post instead of erroring on the repost. It is still preferable for clients to act on the underlying post themselves, but this is smoothing out an issue newcomers may have to deal with.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment