|
@@ -42,7 +42,7 @@ export const channels = async (
|
|
channel: any
|
|
channel: any
|
|
): Promise<void> => {
|
|
): Promise<void> => {
|
|
const [last, current] = channels;
|
|
const [last, current] = channels;
|
|
- const messages: string[] = [];
|
|
|
|
|
|
+ const messages: string[][] = [[], []];
|
|
|
|
|
|
for (let id: number = +last + 1; id <= current; id++) {
|
|
for (let id: number = +last + 1; id <= current; id++) {
|
|
const channel: Channel = await query("title", () =>
|
|
const channel: Channel = await query("title", () =>
|
|
@@ -51,11 +51,17 @@ export const channels = async (
|
|
const member: Member = { id: channel.owner.asMember, handle: "", url: "" };
|
|
const member: Member = { id: channel.owner.asMember, handle: "", url: "" };
|
|
member.handle = await memberHandle(api, member.id);
|
|
member.handle = await memberHandle(api, member.id);
|
|
member.url = `${domain}/#/members/${member.handle}`;
|
|
member.url = `${domain}/#/members/${member.handle}`;
|
|
- messages.push(
|
|
|
|
|
|
+ messages[0].push(
|
|
`<b>Channel <a href="${domain}/#//media/channels/${id}">${id}</a> by <a href="${member.url}">${member.handle} (${member.id})</a></b>`
|
|
`<b>Channel <a href="${domain}/#//media/channels/${id}">${id}</a> by <a href="${member.url}">${member.handle} (${member.id})</a></b>`
|
|
);
|
|
);
|
|
|
|
+ messages[1].push(
|
|
|
|
+ `**Channel ${id}** by ${member.handle} (${member.id})\n${domain}/#//media/channels/${id}`
|
|
|
|
+ );
|
|
}
|
|
}
|
|
- sendMessage(messages.join("\r\n\r\n"), channel);
|
|
|
|
|
|
+ sendMessage(
|
|
|
|
+ { tg: messages[0].join("\r\n\r\n"), discord: messages[1].join(`\n\n`) },
|
|
|
|
+ channel
|
|
|
|
+ );
|
|
};
|
|
};
|
|
|
|
|
|
// announce council change
|
|
// announce council change
|
|
@@ -71,7 +77,7 @@ export const council = async (
|
|
const stage: any = await api.query.councilElection.stage();
|
|
const stage: any = await api.query.councilElection.stage();
|
|
const stageObj = JSON.parse(JSON.stringify(stage));
|
|
const stageObj = JSON.parse(JSON.stringify(stage));
|
|
let stageString = stageObj ? Object.keys(stageObj)[0] : "";
|
|
let stageString = stageObj ? Object.keys(stageObj)[0] : "";
|
|
- let msg = "";
|
|
|
|
|
|
+ let msg: string[] = ["", ""];
|
|
|
|
|
|
if (!stage || stage.toJSON() === null) {
|
|
if (!stage || stage.toJSON() === null) {
|
|
stageString = "elected";
|
|
stageString = "elected";
|
|
@@ -91,19 +97,25 @@ export const council = async (
|
|
);
|
|
);
|
|
const members = handles.join(", ");
|
|
const members = handles.join(", ");
|
|
|
|
|
|
- msg = `Council election ended: ${members} have been elected for <a href="${domain}/#/council/members">council ${round}</a>. Congratulations!\nNext election starts on ${endDate}.`;
|
|
|
|
|
|
+ msg[0] = `Council election ended: ${members} have been elected for <a href="${domain}/#/council/members">council ${round}</a>. Congratulations!\nNext election starts on ${endDate}.`;
|
|
|
|
+ msg[1] = `Council election ended: ${members} have been elected for council ${round}. Congratulations!\nNext election starts on ${endDate}.\n${domain}/#/council/members`;
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
const remainingBlocks = stage.toJSON()[stageString] - currentBlock;
|
|
const remainingBlocks = stage.toJSON()[stageString] - currentBlock;
|
|
const m = moment().add(remainingBlocks * 6, "second");
|
|
const m = moment().add(remainingBlocks * 6, "second");
|
|
const endDate = formatTime(m, "DD-MM-YYYY HH:mm (UTC)");
|
|
const endDate = formatTime(m, "DD-MM-YYYY HH:mm (UTC)");
|
|
|
|
|
|
- if (stageString === "Announcing")
|
|
|
|
- msg = `Council election started. You can <b><a href="${domain}/#/council/applicants">announce your application</a></b> until ${endDate}`;
|
|
|
|
- else if (stageString === "Voting")
|
|
|
|
- msg = `Council election: <b><a href="${domain}/#/council/applicants">Vote</a></b> until ${endDate}`;
|
|
|
|
- else if (stageString === "Revealing")
|
|
|
|
- msg = `Council election: <b><a href="${domain}/#/council/votes">Reveal your votes</a></b> until ${endDate}`;
|
|
|
|
|
|
+ const link = `${domain}/#/council/`;
|
|
|
|
+ if (stageString === "Announcing") {
|
|
|
|
+ msg[0] = `Council election started. You can <b><a href="${link}applicants">announce your application</a></b> until ${endDate}`;
|
|
|
|
+ msg[1] = `Council election started. You can **announce your application** until ${endDate} ${link}applicants`;
|
|
|
|
+ } else if (stageString === "Voting") {
|
|
|
|
+ msg[0] = `Council election: <b><a href="${link}applicants">Vote</a></b> until ${endDate}`;
|
|
|
|
+ msg[1] = `Council election: **Vote* until ${endDate} ${link}applicants`;
|
|
|
|
+ } else if (stageString === "Revealing") {
|
|
|
|
+ msg[0] = `Council election: <b><a href="${link}votes">Reveal your votes</a></b> until ${endDate}`;
|
|
|
|
+ msg[1] = `Council election: **Reveal your votes** until ${endDate} ${link}votes`;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
if (
|
|
if (
|
|
@@ -111,7 +123,7 @@ export const council = async (
|
|
round !== council.round &&
|
|
round !== council.round &&
|
|
stageString !== council.last
|
|
stageString !== council.last
|
|
)
|
|
)
|
|
- sendMessage(msg, channel);
|
|
|
|
|
|
+ sendMessage({ tg: msg[0], discord: msg[1] }, channel);
|
|
return { round, last: stageString };
|
|
return { round, last: stageString };
|
|
};
|
|
};
|
|
|
|
|
|
@@ -124,15 +136,22 @@ export const categories = async (
|
|
channel: any
|
|
channel: any
|
|
): Promise<number> => {
|
|
): Promise<number> => {
|
|
if (category[0] === category[1]) return category[0];
|
|
if (category[0] === category[1]) return category[0];
|
|
- const messages: string[] = [];
|
|
|
|
|
|
+ const messages: string[][] = [[], []];
|
|
|
|
|
|
for (let id: number = +category[0] + 1; id <= category[1]; id++) {
|
|
for (let id: number = +category[0] + 1; id <= category[1]; id++) {
|
|
const cat: Category = await query("title", () => categoryById(api, id));
|
|
const cat: Category = await query("title", () => categoryById(api, id));
|
|
- const msg = `Category ${id}: <b><a href="${domain}/#/forum/categories/${id}">${cat.title}</a></b>`;
|
|
|
|
- messages.push(msg);
|
|
|
|
|
|
+ messages[0].push(
|
|
|
|
+ `Category ${id}: <b><a href="${domain}/#/forum/categories/${id}">${cat.title}</a></b>`
|
|
|
|
+ );
|
|
|
|
+ messages[1].push(
|
|
|
|
+ `Category ${id}: **${cat.title}** ${domain}/#/forum/categories/${id}`
|
|
|
|
+ );
|
|
}
|
|
}
|
|
|
|
|
|
- sendMessage(messages.join("\r\n\r\n"), channel);
|
|
|
|
|
|
+ sendMessage(
|
|
|
|
+ { tg: messages[0].join("\r\n\r\n"), discord: messages[1].join(`\n\n`) },
|
|
|
|
+ channel
|
|
|
|
+ );
|
|
return category[1];
|
|
return category[1];
|
|
};
|
|
};
|
|
|
|
|
|
@@ -145,7 +164,7 @@ export const posts = async (
|
|
): Promise<number> => {
|
|
): Promise<number> => {
|
|
const [last, current] = posts;
|
|
const [last, current] = posts;
|
|
if (current === last) return last;
|
|
if (current === last) return last;
|
|
- const messages: string[] = [];
|
|
|
|
|
|
+ const messages: string[][] = [[], []];
|
|
|
|
|
|
for (let id: number = +last + 1; id <= current; id++) {
|
|
for (let id: number = +last + 1; id <= current; id++) {
|
|
const post: Post = await query("current_text", () =>
|
|
const post: Post = await query("current_text", () =>
|
|
@@ -167,19 +186,22 @@ export const posts = async (
|
|
const handle = await memberHandleByAccount(api, post.author_id.toJSON());
|
|
const handle = await memberHandleByAccount(api, post.author_id.toJSON());
|
|
|
|
|
|
const s = {
|
|
const s = {
|
|
- author: `<a href="${domain}/#/members/${handle}">${handle}</a>`,
|
|
|
|
- thread: `<a href="${domain}/#/forum/threads/${threadId}?replyIdx=${replyId}">${thread.title}</a>`,
|
|
|
|
- category: `<a href="${domain}/#/forum/categories/${category.id}">${category.title}</a>`,
|
|
|
|
- content: `<i>${post.current_text.substring(0, 150)}</i> `,
|
|
|
|
- link: `<a href="${domain}/#/forum/threads/${threadId}?replyIdx=${replyId}">more</a>`,
|
|
|
|
|
|
+ content: post.current_text.substring(0, 250),
|
|
|
|
+ link: `${domain}/#/forum/threads/${threadId}?replyIdx=${replyId}`,
|
|
};
|
|
};
|
|
|
|
|
|
- messages.push(
|
|
|
|
- `<u>${s.category}</u> <b>${s.author}</b> posted in <b>${s.thread}</b>:\n\r${s.content}${s.link}`
|
|
|
|
|
|
+ messages[0].push(
|
|
|
|
+ `<u><a href="${domain}/#/forum/categories/${category.id}">${category.title}</a></u> <b><a href="${domain}/#/members/${handle}">${handle}</a></b> posted in <b><a href="${domain}/#/forum/threads/${threadId}?replyIdx=${replyId}">${thread.title}</a></b>:\n\r<i>${s.content}</i> <a href="${s.link}">more</a>`
|
|
|
|
+ );
|
|
|
|
+ messages[1].push(
|
|
|
|
+ `**[${category.title}]** ${handle} posted in **${thread.title}**:\n*${s.content}*\nMore: ${s.link}`
|
|
);
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
- sendMessage(messages.join("\r\n\r\n"), channel);
|
|
|
|
|
|
+ sendMessage(
|
|
|
|
+ { tg: messages[0].join("\r\n\r\n"), discord: messages[1].join(`\n\n`) },
|
|
|
|
+ channel
|
|
|
|
+ );
|
|
return current;
|
|
return current;
|
|
};
|
|
};
|
|
|
|
|
|
@@ -200,8 +222,10 @@ export const proposals = async (
|
|
const endTime = moment()
|
|
const endTime = moment()
|
|
.add(6 * (votingEndsAt - block), "second")
|
|
.add(6 * (votingEndsAt - block), "second")
|
|
.format("DD/MM/YYYY HH:mm");
|
|
.format("DD/MM/YYYY HH:mm");
|
|
- const msg = `Proposal ${id} <b>created</b> at block ${createdAt}.\r\n${message}\r\nYou can vote until ${endTime} UTC (block ${votingEndsAt}).`;
|
|
|
|
- sendMessage(msg, channel);
|
|
|
|
|
|
+ const link = `${domain}/#/proposals/${id}`;
|
|
|
|
+ const tg = `Proposal ${id} <b>created</b> at block ${createdAt}.\r\n${message.tg}\r\nYou can <a href="${link}">vote</a> until ${endTime} UTC (block ${votingEndsAt}).`;
|
|
|
|
+ const discord = `Proposal ${id} **created** at block ${createdAt}. ${message.discord}\nVote until ${endTime} UTC (block ${votingEndsAt}). ${link}`;
|
|
|
|
+ sendMessage({ tg, discord }, channel);
|
|
active.push(id);
|
|
active.push(id);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -215,8 +239,10 @@ export const proposals = async (
|
|
label = executed ? "executed" : "finalized";
|
|
label = executed ? "executed" : "finalized";
|
|
if (!executed) executing.push(id);
|
|
if (!executed) executing.push(id);
|
|
}
|
|
}
|
|
- const msg = `Proposal ${id} <b>${label}</b> at block ${finalizedAt}.\r\n${message}`;
|
|
|
|
- sendMessage(msg, channel);
|
|
|
|
|
|
+ const link = `${domain}/#/proposals/${id}`;
|
|
|
|
+ const tg = `<a href="${link}">Proposal ${id}</a> <b>${label}</b> at block ${finalizedAt}.\r\n${message.tg}`;
|
|
|
|
+ const discord = `Proposal ${id} **${label}** at block ${finalizedAt}.\n${message.discord}\n${link}`;
|
|
|
|
+ sendMessage({ tg, discord }, channel);
|
|
active = active.filter((a) => a !== id);
|
|
active = active.filter((a) => a !== id);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -226,8 +252,10 @@ export const proposals = async (
|
|
const { finalizedAt, message, parameters } = proposal;
|
|
const { finalizedAt, message, parameters } = proposal;
|
|
const executesAt = +finalizedAt + parameters.gracePeriod.toNumber();
|
|
const executesAt = +finalizedAt + parameters.gracePeriod.toNumber();
|
|
if (block < executesAt) continue;
|
|
if (block < executesAt) continue;
|
|
- const msg = `Proposal ${id} <b>executed</b> at block ${executesAt}.\r\n${message}`;
|
|
|
|
- sendMessage(msg, channel);
|
|
|
|
|
|
+ const link = `${domain}/#/proposals/${id}`;
|
|
|
|
+ const tg = `<a href="${link}">Proposal ${id}</a> <b>executed</b> at block ${executesAt}.\r\n${message.tg}`;
|
|
|
|
+ const discord = `Proposal ${id} **executed** at block ${executesAt}.\n${message.discord}\n${link}`;
|
|
|
|
+ sendMessage({ tg, discord }, channel);
|
|
executing = executing.filter((e) => e !== id);
|
|
executing = executing.filter((e) => e !== id);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -268,11 +296,16 @@ export const heartbeat = async (
|
|
const pending = proposals.active.length;
|
|
const pending = proposals.active.length;
|
|
const finalized = proposals.executing.length;
|
|
const finalized = proposals.executing.length;
|
|
const p = (n: number) => (n > 1 ? "proposals" : "proposal");
|
|
const p = (n: number) => (n > 1 ? "proposals" : "proposal");
|
|
- let proposalString = pending
|
|
|
|
- ? `<a href="${domain}/#/proposals">${pending} pending ${p(pending)}</a> `
|
|
|
|
- : "";
|
|
|
|
|
|
+ let proposalString: string[] = pending
|
|
|
|
+ ? [
|
|
|
|
+ `<a href="${domain}/#/proposals">${pending} pending ${p(pending)}</a> `,
|
|
|
|
+ `${pending} pending ${p(pending)} ${domain}/#/proposals`,
|
|
|
|
+ ]
|
|
|
|
+ : ["", ""];
|
|
if (finalized)
|
|
if (finalized)
|
|
- proposalString += `${finalized} ${p(finalized)} in grace period.`;
|
|
|
|
|
|
+ proposalString = proposalString.map(
|
|
|
|
+ (s) => (s += `${finalized} ${p(finalized)} in grace period.`)
|
|
|
|
+ );
|
|
|
|
|
|
const msg = ` ${blocks.length} blocks produced in ${timePassed}
|
|
const msg = ` ${blocks.length} blocks produced in ${timePassed}
|
|
Blocktime: ${blocktime.toFixed(3)}s
|
|
Blocktime: ${blocktime.toFixed(3)}s
|
|
@@ -280,14 +313,17 @@ export const heartbeat = async (
|
|
Stake: ${avgStake.toFixed(1)} / ${avgIssued.toFixed()} M tJOY (${percent}%)
|
|
Stake: ${avgStake.toFixed(1)} / ${avgIssued.toFixed()} M tJOY (${percent}%)
|
|
Validators: ${avgVals.toFixed()} (${reward} tJOY/h)
|
|
Validators: ${avgVals.toFixed()} (${reward} tJOY/h)
|
|
Nominators: ${getAverage(noms).toFixed()}
|
|
Nominators: ${getAverage(noms).toFixed()}
|
|
- Volume: ${storageSize}
|
|
|
|
- ${proposalString}
|
|
|
|
- `;
|
|
|
|
-
|
|
|
|
- sendMessage(msg, channel);
|
|
|
|
|
|
+ Volume: ${storageSize}\n`;
|
|
|
|
+ const tg = msg + proposalString[0];
|
|
|
|
+ const discord = msg + proposalString[1];
|
|
|
|
+ sendMessage({ tg, discord }, channel);
|
|
};
|
|
};
|
|
|
|
|
|
-export const formatProposalMessage = (data: string[]): string => {
|
|
|
|
|
|
+export const formatProposalMessage = (
|
|
|
|
+ data: string[]
|
|
|
|
+): { tg: string; discord: string } => {
|
|
const [id, title, type, stage, result, handle] = data;
|
|
const [id, title, type, stage, result, handle] = data;
|
|
- return `<b>Type</b>: ${type}\r\n<b>Proposer</b>: <a href="${domain}/#/members/${handle}">${handle}</a>\r\n<b>Title</b>: <a href="${domain}/#/proposals/${id}">${title}</a>\r\n<b>Stage</b>: ${stage}\r\n<b>Result</b>: ${result}`;
|
|
|
|
|
|
+ const tg = `<b>Type</b>: ${type}\r\n<b>Proposer</b>: <a href="${domain}/#/members/${handle}">${handle}</a>\r\n<b>Title</b>: <a href="${domain}/#/proposals/${id}">${title}</a>\r\n<b>Stage</b>: ${stage}\r\n<b>Result</b>: ${result}`;
|
|
|
|
+ const discord = `**Type**: ${type}\n**Proposer**: ${handle}\n**Title**: ${title}\n**Stage**: ${stage}\n**Result*: ${result}\n${domain}/#/proposals/${id}`;
|
|
|
|
+ return { tg, discord };
|
|
};
|
|
};
|