-
Notifications
You must be signed in to change notification settings - Fork 19
Description
OBIP-0004: Posts
Proposal: https://github.com/OpenBazaar/obips/blob/master/obip-0004.md
Author: @drwasho
OBIP: 4 Title: Posts Author: Dr Washington Y. Sanchez Status: Draft Type: Standards Track Created: 2017-08-27
Abstract
- This OBIP describes the addition of a new type of content that can be published and shared on the network by users:
posts - Posts enable a user to publish written content that can be viewed by other users visiting their store or via third party search
- Posts can be used for market-related activities such as: advertising listings, announce store updates, publish a new coupon for a special offer etc
- Moreover, posts can also be used for non-market activities and serve as a platform for censorship-resistant expression on the network, encouraging non-vendors to regularly use the network
Motivation
OpenBazaar has limited tools for Vendors to engage with potential customers. Engagement can be in the form of advertising a listing, announcing a store update, brand-building, announcing special offers or coupons for a sale to name a few. Users in general can also benefit from these tools by blogging interesting items they have seen on the network, and driving sales for Vendors (i.e. OB influencers).
Aside from side-channels (i.e. off the OpenBazaar network), Vendors can only communicate to potential buyers via the About section of their profile, or via direct message. The About section is limited in form and function, and its history is not traversable. Direct message is excellent for one-on-one communication, but it can only be initiated by a user visiting the store.
What is required is a means for Vendors to publish a blog-style post that users can view when visiting their store.
Requirements
Posts allow a Vendor to upload a message or image in a dedicate space in their store. Posts have traversable history, designed for one-way communication from the Vendor to users. The purpose of posts is to inform visitors of any content they feel necessary to drive sales and/or engage with users (i.e. announcements, brand building, promotions, coupons etc).
User Stories
Role: Publisher
A 'publisher' is a vendor or user that is publishing a post on their node for other users to consume.
- As a Publisher, I can post a message {text, image} that is displayed in my store.
- As a Publisher, I can edit a message that is displayed in my store.
- As a Publisher, I can delete a message this is displayed in my store.
- As a Publisher, I can traverse a history of messages in my store.
Role: User
- As a user, I can read a message {text and/or image} posted by a Publisher.
- As a user, I can traverse a history of messages {text and/or image} posted by a Publisher.
Specification
A post should allow the publisher to include:
- A short title (max. 280 characters)
- The title field can be used as a title for a long-form post, or as a microblog post in itself (i.e. tweet-style).
- A long-form post (max. 50,000 characters)
- This field is used for blog-style posts
- Images
- An array of up to 30 images can be attached to the post
- Tags
- An array of up to 40 tags
- A timestamp
All posts need to be digitally signed to establish authenticity, and will include a slug for IPNS resolution so the publisher can edit their post.
Protobuf
The protobuf spec:
syntax = "proto3";
option go_package = "pb";
import "google/protobuf/timestamp.proto";
import "contracts.proto";
message Post {
string slug = 1;
ID vendorID = 2;
string title = 3;
string longForm = 4;
repeated Image images = 5;
repeated string tags = 6;
google.protobuf.Timestamp timestamp = 7;
message Image {
string filename = 1;
string original = 2;
string large = 3;
string medium = 4;
string small = 5;
string tiny = 6;
}
}
message SignedPost {
Post post = 1;
string hash = 2;
bytes signature = 3;
}
API
We propose that OpenBazaar server-node implementations support the following endpoints:
- GET
/ob/posts - GET
/ob/post - POST
/ob/post - PUT
/ob/post - DELETE
/ob/post
GET ob/posts
Returns an array of posts from the user or a peer (i.e. /ob/posts/:peerId):
[
{
"hash": "zb2rhdrJUgp17bvjnEW98s9C2eToZHep1eh5i7SBp9jhBpREA",
"images": [
{
"medium": "zb2rhaFhqziCWk1zo5tMRxQEUchfvJFaGG4DY1anEoR4GnYrN",
"small": "zb2rhbDCeEiTTunugWPaRRKFCfNKUaB7aCR53nrPnMa9usZXY",
"tiny": "zb2rhgqJDbshwAgPjs7X2h4mDm3V3BpLbp4tFGqkg1LNkg9yV"
},
{
"medium": "zb2rhY4sqZehNgKD7ehxHiG7z3wnpKZEeNccWxrfx1GmAckxy",
"small": "zb2rhhMRWCb5ozMdez8JePnZnh9WRxyTCJVNk7CfLNVVaUmhz",
"tiny": "zb2rhmxApBVCHh426vnYSJGSDH4KpKpqKyvY2CAWmaiuHd8tZ"
}
],
"slug": "multiimagetest",
"tags": [
"zb2rhXoKEJtXxB5pcxhmcLu1aCCY3MRHR1Vc4tSJMyzPy8KJv",
"#freeWynona"
],
"timestamp": "2017-10-05T00:13:53.892275067Z",
"title": "multiimagetest"
}
]GET ob/post
Returns an individual post from the user or a peer (i.e. /ob/post/:peerId/:slug_or_hash):
{
"post": {
"slug": "multiimagetest",
"vendorID": {
"peerID": "QmVdst57mJuW8Tr9owADqWmirY5Gao9zZMnbbL4WavKJvB",
"handle": "",
"pubkeys": {
"identity": "CAESIEokc1r9Wfe4IyqA9P/56dO+5W1Hv9eOi2PXdUBDUf5X",
"bitcoin": "AjjghznFUNeAkgmEdKYOESzj+PXFvVHUv+jbNWWQKkwG"
},
"bitcoinSig": "MEQCIAaKg1Cr676NVo7dz1KibSvvhjyrAXQceYakKwYR13+oAiBmAWqIyTWMuMPeVItwPzS1N2SDYeR5H4cD+uxGv1AghQ=="
},
"title": "multiimagetest",
"longForm": "This is a test post dawg.",
"images": [
{
"filename": "cat",
"original": "zb2rhe2o6WbHqcER5VUKsMUbQrmpCC6ihg8qZ4JS9wVgKz9wm",
"large": "zb2rhmBUB9i7UkfmeD3obJYK3FFS5K8N8QHaUanG8UWLVBHiY",
"medium": "zb2rhaFhqziCWk1zo5tMRxQEUchfvJFaGG4DY1anEoR4GnYrN",
"small": "zb2rhbDCeEiTTunugWPaRRKFCfNKUaB7aCR53nrPnMa9usZXY",
"tiny": "zb2rhgqJDbshwAgPjs7X2h4mDm3V3BpLbp4tFGqkg1LNkg9yV"
},
{
"filename": "random",
"original": "zdj7Wazpqc5dGZ9yyKweKGjkGF3mAj5cjrWSV3QisHU34UsaQ",
"large": "zb2rhemVicsnTAo454S6Cdq2Ct677B47ArbQ7AqNtWYWUbvBQ",
"medium": "zb2rhY4sqZehNgKD7ehxHiG7z3wnpKZEeNccWxrfx1GmAckxy",
"small": "zb2rhhMRWCb5ozMdez8JePnZnh9WRxyTCJVNk7CfLNVVaUmhz",
"tiny": "zb2rhmxApBVCHh426vnYSJGSDH4KpKpqKyvY2CAWmaiuHd8tZ"
}
],
"tags": [
"zb2rhXoKEJtXxB5pcxhmcLu1aCCY3MRHR1Vc4tSJMyzPy8KJv",
"#freeWynona"
],
"timestamp": "2017-10-05T00:13:53.892275067Z"
},
"hash": "zb2rhdrJUgp17bvjnEW98s9C2eToZHep1eh5i7SBp9jhBpREA",
"signature": "evhmoAw3S/Qx3lmTStd0esnhPjwgWCfRncpGltyLjW3wPG7Gh8kd4uRSsS+LwoPMpVVvibLuIDi0WwyfsrkODA=="
}POST /ob/post
Creates a new post:
{
"title": "multiimagetest-4",
"longForm": "This is a test post dawg.",
"images": [{
"filename": "cat",
"large": "zb2rhmBUB9i7UkfmeD3obJYK3FFS5K8N8QHaUanG8UWLVBHiY",
"medium": "zb2rhaFhqziCWk1zo5tMRxQEUchfvJFaGG4DY1anEoR4GnYrN",
"original": "zb2rhe2o6WbHqcER5VUKsMUbQrmpCC6ihg8qZ4JS9wVgKz9wm",
"small": "zb2rhbDCeEiTTunugWPaRRKFCfNKUaB7aCR53nrPnMa9usZXY",
"tiny": "zb2rhgqJDbshwAgPjs7X2h4mDm3V3BpLbp4tFGqkg1LNkg9yV"
},
{
"filename": "random",
"tiny": "zb2rhmxApBVCHh426vnYSJGSDH4KpKpqKyvY2CAWmaiuHd8tZ",
"small": "zb2rhhMRWCb5ozMdez8JePnZnh9WRxyTCJVNk7CfLNVVaUmhz",
"medium": "zb2rhY4sqZehNgKD7ehxHiG7z3wnpKZEeNccWxrfx1GmAckxy",
"original": "zdj7Wazpqc5dGZ9yyKweKGjkGF3mAj5cjrWSV3QisHU34UsaQ",
"large": "zb2rhemVicsnTAo454S6Cdq2Ct677B47ArbQ7AqNtWYWUbvBQ"
}
],
"tags": [
"zb2rhXoKEJtXxB5pcxhmcLu1aCCY3MRHR1Vc4tSJMyzPy8KJv",
"#freeWynona"
]
}PUT /ob/post
Edits an existing post:
{
"slug": "multiimagetest4",
"title": "multiimagetest-4",
"longForm": "This is a test post yo.",
"images": [{
"filename": "cat",
"large": "zb2rhmBUB9i7UkfmeD3obJYK3FFS5K8N8QHaUanG8UWLVBHiY",
"medium": "zb2rhaFhqziCWk1zo5tMRxQEUchfvJFaGG4DY1anEoR4GnYrN",
"original": "zb2rhe2o6WbHqcER5VUKsMUbQrmpCC6ihg8qZ4JS9wVgKz9wm",
"small": "zb2rhbDCeEiTTunugWPaRRKFCfNKUaB7aCR53nrPnMa9usZXY",
"tiny": "zb2rhgqJDbshwAgPjs7X2h4mDm3V3BpLbp4tFGqkg1LNkg9yV"
},
{
"filename": "random",
"tiny": "zb2rhmxApBVCHh426vnYSJGSDH4KpKpqKyvY2CAWmaiuHd8tZ",
"small": "zb2rhhMRWCb5ozMdez8JePnZnh9WRxyTCJVNk7CfLNVVaUmhz",
"medium": "zb2rhY4sqZehNgKD7ehxHiG7z3wnpKZEeNccWxrfx1GmAckxy",
"original": "zdj7Wazpqc5dGZ9yyKweKGjkGF3mAj5cjrWSV3QisHU34UsaQ",
"large": "zb2rhemVicsnTAo454S6Cdq2Ct677B47ArbQ7AqNtWYWUbvBQ"
}
],
"tags": [
"zb2rhXoKEJtXxB5pcxhmcLu1aCCY3MRHR1Vc4tSJMyzPy8KJv",
"#freeWynona"
]
}DELETE /ob/post
Deletes an existing post: /ob/posts/:slug_or_hash
Rationale
Advantages
- Allows for users to engage with visitors and promote sales
- Creates basic tools for an influencer and affiliate program
- It is a platform for censorship-resistant expression
Disadvantages
index.jsonfile can get bloated if there are a lot of posts- This could potentially be mitigated by only storing hashes of the post in an array
Backwards Compatibility
This OBIP extends the protocol and creates a collection of new APIs, as well as a new directory to store posts. This means that non-upgraded nodes will not be able to fulfil API calls for posts if requested. The server will return a standard error for unrecognised API calls.
Posts do not alter the existing database or API calls, so disruption to clients should be minimal. As a result, clients can choose to support this feature - if at all - at their leisure.