Hive Developer Portal
Reblogging Post
How to reblog a post on Hive
Full, runnable src of Reblogging Post can be downloaded as part of: tutorials/ruby (or download just this tutorial: devportal-master-tutorials-ruby-14_reblogging_post.zip).
For this operation, we will use custom_json
and a properly formed id and payload so that follow_plugin
will pick up the reblog data and display the selected post in the feed of the account doing the reblog.
Also see:
Sections
- Making the api call - broadcasting the operation
- Example api call - make the call in code
- Example api call using script - using our tutorial script
- Example Output - output from a successful call
- Example Error - error output from a unsuccessful call
- Custom JSON Fields - understanding the result
- To Run - Running the example.
Making the api call
To broadcast the operation, we can use a Radiator::Transaction
instance:
tx = Radiator::Transaction.new
tx.process(true)
Passing true
to Radiator::Transaction#process
will broadcast the operations queued in the operations
array of the transaction.
Example api call
If we want to reblog, we need to form the json
properly, for example:
data = [
:reblog, {
account: reblogger,
author: author,
permlink: permlink
}
]
tx.operations << {
type: :custom_json,
id: 'follow',
required_auths: [],
required_posting_auths: [reblogger],
json: data.to_json
}
Example api call using script
And to do the same with our tutorial script:
ruby reblogging_post.rb https://hive.blog/@inertia/kinda-spooky
Example Output
From the example we get the following output from our script:
{
"jsonrpc": "2.0",
"result": {
"id": "0aa41e06b2612315d32cadeb671eb1201f266dd7",
"block_num": 24063620,
"trx_num": 19,
"expired": false
},
"id": 3
}
The response we get after broadcasting the transaction gives us the transaction id (0aa41e0...
), block number (24063620
), and the transaction number of that block (19
).
Example Error
If a post has already been reblogged by the account, some witnesses are configured to response with an error, if they have follow_evaluators
enabled (by soft-consensus):
{
"jsonrpc": "2.0",
"error": {
"code": -32000,
"message": "Assert Exception:blog_itr == blog_comment_idx.end(): Account has already reblogged this post",
"data": {
"code": 10,
"name": "assert_exception",
"message": "Assert Exception",
"stack": [
{
"context": {
"level": "error",
"file": "follow_evaluators.cpp",
"line": 143,
"method": "do_apply",
"hostname": "",
"timestamp": "2018-07-10T21:33:11"
},
"format": "blog_itr == blog_comment_idx.end(): Account has already reblogged this post",
"data": {
}
},
{
"context": {
"level": "warn",
"file": "follow_evaluators.cpp",
"line": 216,
"method": "do_apply",
"hostname": "",
"timestamp": "2018-07-10T21:33:11"
},
"format": "",
"data": {
"o": {
"account": "social",
"author": "inertia",
"permlink": "kinda-spooky"
}
}
},
{
"context": {
"level": "warn",
"file": "generic_custom_operation_interpreter.hpp",
"line": 195,
"method": "apply",
"hostname": "",
"timestamp": "2018-07-10T21:33:11"
},
"format": "",
"data": {
"outer_o": {
"required_auths": [
],
"required_posting_auths": [
"social"
],
"id": "follow",
"json": "[\"reblog\",{\"account\":\"social\",\"author\":\"inertia\",\"permlink\":\"kinda-spooky\"}]"
}
}
},
{
"context": {
"level": "warn",
"file": "database.cpp",
"line": 3221,
"method": "_apply_transaction",
"hostname": "",
"timestamp": "2018-07-10T21:33:11"
},
"format": "",
"data": {
"op": {
"type": "custom_json_operation",
"value": {
"required_auths": [
],
"required_posting_auths": [
"social"
],
"id": "follow",
"json": "[\"reblog\",{\"account\":\"social\",\"author\":\"inertia\",\"permlink\":\"kinda-spooky\"}]"
}
}
}
},
{
"context": {
"level": "warn",
"file": "database.cpp",
"line": 3227,
"method": "_apply_transaction",
"hostname": "",
"timestamp": "2018-07-10T21:33:11"
},
"format": "",
"data": {
"trx": {
"ref_block_num": 12404,
"ref_block_prefix": 1445149887,
"expiration": "2018-07-10T21:43:09",
"operations": [
{
"type": "custom_json_operation",
"value": {
"required_auths": [
],
"required_posting_auths": [
"social"
],
"id": "follow",
"json": "[\"reblog\",{\"account\":\"social\",\"author\":\"inertia\",\"permlink\":\"kinda-spooky\"}]"
}
}
],
"extensions": [
],
"signatures": [
"1c063e22868f107dbafaa0452d86cfe19894f2f7fc3ea46b5c73dc7906edcd88244548f001c1d128aa07f862819e80e2f46b6cd74c6769d1d48ef4ad1f147b4dab"
]
}
}
},
{
"context": {
"level": "warn",
"file": "database.cpp",
"line": 788,
"method": "push_transaction",
"hostname": "",
"timestamp": "2018-07-10T21:33:11"
},
"format": "",
"data": {
"trx": {
"ref_block_num": 12404,
"ref_block_prefix": 1445149887,
"expiration": "2018-07-10T21:43:09",
"operations": [
{
"type": "custom_json_operation",
"value": {
"required_auths": [
],
"required_posting_auths": [
"social"
],
"id": "follow",
"json": "[\"reblog\",{\"account\":\"social\",\"author\":\"inertia\",\"permlink\":\"kinda-spooky\"}]"
}
}
],
"extensions": [
],
"signatures": [
"1c063e22868f107dbafaa0452d86cfe19894f2f7fc3ea46b5c73dc7906edcd88244548f001c1d128aa07f862819e80e2f46b6cd74c6769d1d48ef4ad1f147b4dab"
]
}
}
}
]
}
},
"id": 3
}
This indicates that the operation was not included in the blockchain because it was already reblogged in the past. If a witness accepts the erroneous reblog operation, because they do not have follow_evaluators
enabled, there will be no error.
Custom JSON Fields
Broadcasting a custom_json
operation will require the following fields:
id
- set tofollow
to indicate that this operation is handled by thefollow_plugin
required_auths
- leave this as an empty JSON Array, we only need the posting authorityrequired_posting_auths
- JSON Array containing the account name with the posting authorityjson
- the actual payload of the operation, containing a JSON Array:- First element -
reblog
- Second element - JSON Object containing:
account
- account that is doing the reblog opauthor
- author of the post being rebloggedpermlink
- permlink of the post being reblogged
- First element -
Final code:
require 'rubygems'
require 'bundler/setup'
Bundler.require
url = ARGV[0]
slug = url.split('@').last
author = slug.split('/')[0]
permlink = slug.split('/')[1..-1].join('/')
reblogger = 'social'
posting_wif = '5JrvPrQeBBvCRdjv29iDvkwn3EQYZ9jqfAHzrCyUvfbEbRkrYFC'
options = {
url: 'https://testnet.openhive.network',
wif: posting_wif
}
tx = Radiator::Transaction.new(options)
data = [
:reblog, {
account: reblogger,
author: author,
permlink: permlink
}
]
tx.operations << {
type: :custom_json,
id: 'follow',
required_auths: [],
required_posting_auths: [reblogger],
json: data.to_json
}
puts JSON.pretty_generate tx.process(true)
To Run
First, set up your workstation using the steps provided in Getting Started. Then you can create and execute the script (or clone from this repository):
You can launch a local testnet, with port 8090 mapped locally to the docker container:
docker run -d -p 8090:8090 inertia/tintoy:latest
For details on running a local testnet, see: Setting Up a Testnet
git clone https://gitlab.syncad.com/hive/devportal.git
cd devportal/tutorials/ruby/14_reblogging_post
bundle install
ruby reblogging_post.rb <url>