mirror of
https://github.com/LBRYFoundation/lbry-wunderbot.git
synced 2025-08-23 17:47:27 +00:00
247 lines
7.5 KiB
JavaScript
247 lines
7.5 KiB
JavaScript
"use strict";
|
|
|
|
let lbry;
|
|
let mongo;
|
|
let discordBot;
|
|
let moment = require("moment");
|
|
let request = require("request");
|
|
let sleep = require("sleep");
|
|
let config = require("config");
|
|
let channels = config.get("claimbot").channels;
|
|
const Discord = require("discord.js");
|
|
const rp = require("request-promise");
|
|
const jsonfile = require("jsonfile");
|
|
const path = require("path");
|
|
const fs = require("fs");
|
|
const appRoot = require("app-root-path");
|
|
const fileExists = require("file-exists");
|
|
module.exports = {
|
|
init: init
|
|
};
|
|
|
|
function init(discordBot_) {
|
|
if (lbry) {
|
|
throw new Error("init was already called once");
|
|
}
|
|
|
|
discordBot = discordBot_;
|
|
|
|
const MongoClient = require("mongodb").MongoClient;
|
|
MongoClient.connect(config.get("mongodb").url, function(err, db) {
|
|
if (err) {
|
|
throw err;
|
|
}
|
|
mongo = db;
|
|
|
|
console.log("Activating claimbot ");
|
|
discordBot.channels.get(channels[0]).send("activating claimbot");
|
|
|
|
// Check that our syncState file exist.
|
|
fileExists(path.join(appRoot.path, "syncState.json"), (err, exists) => {
|
|
if (err) {
|
|
throw err;
|
|
}
|
|
if (!exists) {
|
|
fs.writeFileSync(path.join(appRoot.path, "syncState.json"), "{}");
|
|
}
|
|
});
|
|
setInterval(function() {
|
|
announceClaims();
|
|
}, 60 * 1000);
|
|
announceClaims();
|
|
});
|
|
}
|
|
|
|
async function announceClaims() {
|
|
// get last block form the explorer API.
|
|
let lastBlockHeight = JSON.parse(
|
|
await rp("https://explorer.lbry.io/api/v1/status")
|
|
).status.height;
|
|
// get the latest claims from chainquery since last sync
|
|
let syncState = await getJSON(path.join(appRoot.path, "syncState.json")); // get our persisted state
|
|
if (!syncState.LastSyncTime) {
|
|
syncState.LastSyncTime = new Date()
|
|
.toISOString()
|
|
.slice(0, 19)
|
|
.replace("T", " ");
|
|
}
|
|
let claimsSince = JSON.parse(await getClaimsSince(syncState.LastSyncTime))
|
|
.data;
|
|
// filter out the claims that we should add to discord
|
|
let claims = [];
|
|
for (let claim of claimsSince) {
|
|
claim.value = JSON.parse(claim.value);
|
|
if (claim.value.Claim && claim.value.Claim.stream) {
|
|
claim.metadata = claim.value.Claim.stream.metadata;
|
|
} else {
|
|
claim.metadata = null;
|
|
}
|
|
if (claim.bid_state !== "Spent" || claim.bid_state !== "Expired") {
|
|
claims.push(claim);
|
|
}
|
|
}
|
|
for (let claim of claims) {
|
|
console.log(claim);
|
|
}
|
|
// send each claim to discord.
|
|
for (let claim of claims) {
|
|
console.log(claim);
|
|
if (claim.metadata) {
|
|
// If its a claim, make a claimEmbed
|
|
let claimEmbed = new Discord.RichEmbed()
|
|
.setAuthor(
|
|
claim.channel
|
|
? `New claim from ${claim.channel}`
|
|
: "New claim from Anonymous",
|
|
"http://barkpost-assets.s3.amazonaws.com/wp-content/uploads/2013/11/3dDoge.gif",
|
|
`http://open.lbry.io/${
|
|
claim.channel
|
|
? `${claim.channel}#${claim.channelId}/${claim["name"]}`
|
|
: `${claim["name"]}#${claim["claimId"]}`
|
|
}`
|
|
)
|
|
.setTitle(
|
|
"lbry://" + (claim.channel ? `${claim.channel}/` : "") + claim["name"]
|
|
)
|
|
.setURL(
|
|
`http://open.lbry.io/${
|
|
claim.channel
|
|
? `${claim.channel}#${claim.channelId}/${claim["name"]}`
|
|
: `${claim["name"]}#${claim["claimId"]}`
|
|
}`
|
|
)
|
|
.setColor(1399626)
|
|
.setFooter(
|
|
`Block ${claim.height} • Claim ID ${
|
|
claim.claimId
|
|
} • Data from Chainquery`
|
|
);
|
|
if (claim.metadata["title"])
|
|
claimEmbed.addField("Title", claim.metadata["title"]);
|
|
if (claim.metadata["author"])
|
|
claimEmbed.addField("Author", claim.metadata["author"]);
|
|
if (claim.metadata["description"]) {
|
|
claimEmbed.addField(
|
|
"Description",
|
|
claim.metadata["description"].substring(0, 1020)
|
|
);
|
|
}
|
|
if (claim.metadata["fee"])
|
|
claimEmbed.addField(
|
|
"Fee",
|
|
claim.metadata["fee"].amount + " " + claim.metadata["fee"].currency
|
|
);
|
|
if (claim.metadata["license"] && claim.metadata["license"].length > 2)
|
|
claimEmbed.addField("License", claim.metadata["license"]);
|
|
if (!claim.metadata["nsfw"] && claim.metadata["thumbnail"])
|
|
claimEmbed.setThumbnail(claim.metadata["thumbnail"]);
|
|
if (
|
|
claim.bid_state !== "Controlling" &&
|
|
claim.height < claim.valid_at_height
|
|
) {
|
|
// Claim have not taken over the old claim, send approx time to event.
|
|
let takeoverTime =
|
|
Date.now() + (claim.valid_at_height - lastBlockHeight) * 161 * 1000; // in theory this should be 150, but in practice its closer to 161
|
|
claimEmbed.addField(
|
|
"Takes effect on approx",
|
|
moment(takeoverTime, "x").format("MMMM Do [at] HH:mm [UTC]") +
|
|
` • at block height ${claim.valid_at_height}`
|
|
);
|
|
}
|
|
/*claimEmbed.addField("Claimed for", `${claim.effective_amount} LBC`);*/
|
|
discordPost(claimEmbed);
|
|
} else if (claim.name.charAt(0) === "@") {
|
|
// This is a channel claim
|
|
let channelEmbed = new Discord.RichEmbed()
|
|
.setAuthor(
|
|
"New channel claim",
|
|
"http://barkpost-assets.s3.amazonaws.com/wp-content/uploads/2013/11/3dDoge.gif",
|
|
`http://open.lbry.io/${claim["name"]}#${claim["claimId"]}`
|
|
)
|
|
.setTitle(
|
|
"lbry://" + (claim.channel ? claim.channel + "/" : "") + claim["name"]
|
|
)
|
|
.setURL(`http://open.lbry.io/${claim["name"]}#${claim["claimId"]}`)
|
|
.setColor(1399626)
|
|
.setFooter(
|
|
`Block ${claim.height} • Claim ID ${
|
|
claim.claimId
|
|
} • Data from Chainquery`
|
|
)
|
|
.addField("Channel Name", claim["name"]);
|
|
discordPost(channelEmbed);
|
|
}
|
|
}
|
|
// set the last sync time to the db.
|
|
syncState.LastSyncTime = new Date()
|
|
.toISOString()
|
|
.slice(0, 19)
|
|
.replace("T", " ");
|
|
await saveJSON(path.join(appRoot.path, "syncState.json"), syncState);
|
|
}
|
|
|
|
function getJSON(path) {
|
|
return new Promise((resolve, reject) => {
|
|
jsonfile.readFile(path, function(err, jsoncontent) {
|
|
if (err) {
|
|
reject(err);
|
|
} else {
|
|
resolve(jsoncontent);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
function saveJSON(path, obj) {
|
|
return new Promise((resolve, reject) => {
|
|
jsonfile.writeFile(path, obj, function(err, jsoncontent) {
|
|
if (err) {
|
|
reject(err);
|
|
} else {
|
|
resolve();
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
function discordPost(embed) {
|
|
channels.forEach(channel => {
|
|
discordBot.channels
|
|
.get(channel)
|
|
.send("", embed)
|
|
.catch(console.error);
|
|
});
|
|
}
|
|
|
|
function getClaimsSince(time) {
|
|
return new Promise((resolve, reject) => {
|
|
let query =
|
|
`` +
|
|
`SELECT ` +
|
|
`c.name,` +
|
|
`c.valid_at_height,` +
|
|
`c.height,` +
|
|
`p.name as channel,` +
|
|
`c.publisher_id as channelId,` +
|
|
`c.bid_state,` +
|
|
`c.effective_amount,` +
|
|
`c.claim_id as claimId,` +
|
|
`c.value_as_json as value ` +
|
|
// `,transaction_by_hash_id, ` + // txhash and vout needed to leverage old format for comparison.
|
|
// `vout ` +
|
|
`FROM claim c ` +
|
|
`LEFT JOIN claim p on p.claim_id = c.publisher_id ` +
|
|
`WHERE c.created_at >='` +
|
|
time +
|
|
`'`;
|
|
// Outputs full query to console for copy/paste into chainquery (debugging)
|
|
// console.log(query);
|
|
rp(`https://chainquery.lbry.io/api/sql?query=` + query)
|
|
.then(function(htmlString) {
|
|
resolve(htmlString);
|
|
})
|
|
.catch(function(err) {
|
|
console.log("error", "[Importer] Error getting updated claims. " + err);
|
|
reject(err);
|
|
});
|
|
});
|
|
}
|