Browse Source

bot: fixes according to #36

traumschule 4 years ago
parent
commit
3dcebdd662

+ 1 - 1
community-contributions/joystreamtelegrambot/config.ts

@@ -1,8 +1,8 @@
 // website
 export const domain = "https://testnet.joystream.org";
 
-export const wsLocation = "ws://rome-rpc-endpoint.joystream.org:9944/";
 // websocket location
+export const wsLocation = "wss://rome-rpc-endpoint.joystream.org:9944/";
 
 // telegram bot token
 export const token: string = "";

+ 6 - 5
community-contributions/joystreamtelegrambot/src/bot.ts

@@ -20,8 +20,9 @@ process.env.NTBA_FIX_319 ||
 const bot = new TelegramBot(token, { polling: true });
 
 const sendMessage = (msg: string) => {
+  if (msg === "") return
   try {
-    //bot.sendMessage(chatid, msg, { parse_mode: "HTML" });
+    bot.sendMessage(chatid, msg, { parse_mode: "HTML" });
   } catch (e) {
     console.log(`Failed to send message: ${e}`);
   }
@@ -50,13 +51,13 @@ const main = async () => {
   if (opts.channel) channels[0] = await get.currentChannelId(api);
 
   if (opts.forum) {
-    posts[0] = (await get.currentPostId(api)) - 1;
-    cats[0] = (await get.currentCategoryId(api)) - 1;
-    threads[0] = (await get.currentThreadId(api)) - 1;
+    posts[0] = await get.currentPostId(api);
+    cats[0] = await get.currentCategoryId(api);
+    threads[0] = await get.currentThreadId(api);
   }
 
   if (opts.proposals) {
-    proposals.last = (await get.proposalCount(api)) - 1;
+    proposals.last = await get.proposalCount(api);
     proposals.active = await get.activeProposals(api);
     proposals.pending = await get.pendingProposals(api);
   }

+ 74 - 97
community-contributions/joystreamtelegrambot/src/lib/announcements.ts

@@ -1,7 +1,6 @@
 import { Api, Member, ProposalDetail, Proposals } from "../types";
 import { BlockNumber } from "@polkadot/types/interfaces";
 import { Channel, ElectionStage } from "@joystream/types/augment";
-//import { Channel } from "@joystream/types/channel";
 import { Category, Thread, Post } from "@joystream/types/forum";
 import { domain } from "../../config";
 import {
@@ -13,40 +12,13 @@ import {
 
 const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
 
-const query = async (
-  test: string,
-  callback: () => Promise<any>
-): Promise<any> => {
-  let result: any = await callback();
+const query = async (test: string, cb: () => Promise<any>): Promise<any> => {
+  let result = await cb();
   for (let i: number = 0; i < 10; i++) {
-    if (result[test] === "") {
-      console.debug(`refetching ${callback} (${i})`);
-      result = await callback();
-      await sleep(5000);
-    }
+    if (result[test] !== "") return result;
+    result = await cb();
+    await sleep(5000);
   }
-  return result;
-};
-
-// forum
-
-export const categories = async (
-  api: Api,
-  category: number[],
-  sendMessage: (msg: string) => void
-): Promise<number> => {
-  const messages: string[] = [];
-  let id: number = category[0] + 1;
-  for (id; id <= category[1]; id++) {
-    const category: Category = await query("title", () =>
-      categoryById(api, id)
-    );
-    messages.push(
-      `Category ${id}: <b><a href="${domain}/#/forum/categories/${id}">${category.title}</a></b>`
-    );
-  }
-  sendMessage(messages.join("\r\n\r\n"));
-  return category[1];
 };
 
 export const channels = async (
@@ -74,49 +46,57 @@ export const channels = async (
 
 export const councils = async (
   api: Api,
-  block: number,
+  currentBlock: number,
   sendMessage: (msg: string) => void
 ): Promise<number> => {
-  let current: number = block;
+  let lastBlock: number = currentBlock;
   const round: number = await api.query.councilElection.round();
-  const stage: ElectionStage | null = await await api.query.councilElection.stage();
+  const stage: ElectionStage | null = await api.query.councilElection.stage();
+  let msg = "";
   if (!stage) {
     const councilEnd: BlockNumber = await api.query.council.termEndsAt();
-    current = councilEnd.toNumber();
+    lastBlock = councilEnd.toNumber();
     const termDuration: BlockNumber = await api.query.councilElection.newTermDuration();
-    const block = current - termDuration.toNumber();
-    sendMessage(
-      `<a href="${domain}/#/council/members">Council for round ${round}</a> has been elected at block ${block} until block ${councilEnd}.`
-    );
+    const block = lastBlock - termDuration.toNumber();
+    msg = `<a href="${domain}/#/council/members">Council for round ${round}</a> has been elected at block ${block} until block ${councilEnd}.`;
   } else {
     if (stage.isAnnouncing) {
-      current = stage.asAnnouncing.toNumber();
+      lastBlock = stage.asAnnouncing.toNumber();
       const announcingPeriod: BlockNumber = await api.query.councilElection.announcingPeriod();
-      const block = current - announcingPeriod.toNumber();
-      sendMessage(
-        `Announcing election for round ${round} at ${block}.<a href="${domain}/#/council/applicants">Apply now!</a>`
-      );
-    }
-
-    if (stage.isVoting) {
-      current = stage.asVoting.toNumber();
+      const block = lastBlock - announcingPeriod.toNumber();
+      msg = `Announcing election for round ${round} at ${block}.<a href="${domain}/#/council/applicants">Apply now!</a>`;
+    } else if (stage.isVoting) {
+      lastBlock = stage.asVoting.toNumber();
       const votingPeriod: BlockNumber = await api.query.councilElection.votingPeriod();
-      const block = current - votingPeriod.toNumber();
-      sendMessage(
-        `Voting stage for council election started at block ${block}. <a href="${domain}/#/council/applicants">Vote now!</a>`
-      );
-    }
-
-    if (stage.isRevealing) {
-      current = stage.asRevealing.toNumber();
+      const block = lastBlock - votingPeriod.toNumber();
+      msg = `Voting stage for council election started at block ${block}. <a href="${domain}/#/council/applicants">Vote now!</a>`;
+    } else if (stage.isRevealing) {
+      lastBlock = stage.asRevealing.toNumber();
       const revealingPeriod: BlockNumber = await api.query.councilElection.revealingPeriod();
-      const block = current - revealingPeriod.toNumber();
-      sendMessage(
-        `Revealing stage for council election started at block ${block}. <a href="${domain}/#/council/votes">Don't forget to reveal your vote!</a>`
-      );
+      const block = lastBlock - revealingPeriod.toNumber();
+      msg = `Revealing stage for council election started at block ${block}. <a href="${domain}/#/council/votes">Don't forget to reveal your vote!</a>`;
     }
   }
-  return current;
+  sendMessage(msg);
+  return lastBlock;
+};
+
+// forum
+
+export const categories = async (
+  api: Api,
+  category: number[],
+  sendMessage: (msg: string) => void
+): Promise<number> => {
+  const messages: string[] = [];
+  let id: number = category[0] + 1;
+  for (id; id <= category[1]; 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);
+  }
+  sendMessage(messages.join("\r\n\r\n"));
+  return category[1];
 };
 
 export const posts = async (
@@ -143,14 +123,39 @@ export const posts = async (
       categoryById(api, thread.category_id.toNumber())
     );
     const handle = await memberHandleByAccount(api, post.author_id.toJSON());
-    messages.push(
-      `<b><a href="${domain}/#/members/${handle}">${handle}</a> posted <a href="${domain}/#/forum/threads/${threadId}?replyIdx=${replyId}">${threadTitle}</a> in <a href="${domain}/#/forum/categories/${category.id}">${category.title}</a>:</b>\n\r<i>${excerpt}</i> <a href="${domain}/#/forum/threads/${threadId}?replyIdx=${replyId}">more</a>`
-    );
+    const msg = `<b><a href="${domain}/#/members/${handle}">${handle}</a> posted <a href="${domain}/#/forum/threads/${threadId}?replyIdx=${replyId}">${threadTitle}</a> in <a href="${domain}/#/forum/categories/${category.id}">${category.title}</a>:</b>\n\r<i>${excerpt}</i> <a href="${domain}/#/forum/threads/${threadId}?replyIdx=${replyId}">more</a>`;
+    messages.push(msg);
   }
   sendMessage(messages.join("\r\n\r\n"));
   return current;
 };
 
+export const threads = async (
+  api: Api,
+  threads: number[],
+  sendMessage: (msg: string) => void
+): Promise<number> => {
+  const [last, current] = threads;
+  const messages: string[] = [];
+  let id: number = last + 1;
+  for (id; id <= current; id++) {
+    const thread: Thread = await query("title", () =>
+      api.query.forum.threadById(id)
+    );
+    const { title, author_id } = thread;
+    const handle: string = await memberHandleByAccount(api, author_id.toJSON());
+    const category: Category = await query("title", () =>
+      categoryById(api, thread.category_id.toNumber())
+    );
+    const msg = `Thread ${id}: <a href="${domain}/#/forum/threads/${id}">"${title}"</a> by <a href="${domain}/#/members/${handle}">${handle}</a> in category "<a href="${domain}/#/forum/categories/${category.id}">${category.title}</a>" `;
+    messages.push(msg);
+  }
+  sendMessage(messages.join("\r\n\r\n"));
+  return id;
+};
+
+// proposals
+
 const processActive = async (
   id: number,
   details: ProposalDetail,
@@ -162,7 +167,7 @@ const processActive = async (
     let label: string = result;
     if (result === "Approved") {
       const executed = parameters.gracePeriod.toNumber() > 0 ? false : true;
-      label = executed ? "Finalized" : "Finalized and Executed";
+      label = executed ? "Finalized" : "Executed";
     }
     msg = `Proposal ${id} <b>${label}</b> at block ${finalizedAt}.\r\n${message}`;
     sendMessage(msg);
@@ -203,35 +208,7 @@ export const proposals = async (
   return { current, last: current, active, pending };
 };
 
-export const threads = async (
-  api: Api,
-  threads: number[],
-  sendMessage: (msg: string) => void
-): Promise<number> => {
-  const [last, current] = threads;
-  const messages: string[] = [];
-  let id: number = last + 1;
-  for (id; id <= current; id++) {
-    const thread: Thread = await query("title", () =>
-      api.query.forum.threadById(id)
-    );
-    const { title, author_id } = thread;
-    const memberName: string = await memberHandleByAccount(
-      api,
-      author_id.toJSON()
-    );
-    const category: Category = await query("title", () =>
-      categoryById(api, thread.category_id.toNumber())
-    );
-    messages.push(
-      `Thread ${id}: <a href="${domain}/#/forum/threads/${id}">"${title}"</a> by <a href="${domain}/#/members/${memberName}">${memberName}</a> in category "<a href="${domain}/#/forum/categories/${category.id}">${category.title}</a>" `
-    );
-  }
-  sendMessage(messages.join("\r\n\r\n"));
-  return id;
-};
-
 export const formatProposalMessage = (data: string[]): string => {
-  const [id, title, type, stage, result, memberHandle] = data;
-  return `<b>Type</b>: ${type}\r\n<b>Proposer</b>:<a href="${domain}/#/members/${memberHandle}"> ${memberHandle}</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 [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}`;
 };

+ 17 - 32
community-contributions/joystreamtelegrambot/src/lib/getters.ts

@@ -1,17 +1,17 @@
-import { Api, Proposals, ProposalArray, ProposalDetail } from "../types";
+import { formatProposalMessage } from "./announcements";
+
+//types
+
+import { Api, ProposalArray, ProposalDetail } from "../types";
 import {
   ChannelId,
-  ElectionStage,
   PostId,
   ProposalDetailsOf,
   ThreadId
 } from "@joystream/types/augment";
 import { Category, CategoryId } from "@joystream/types/forum";
-import { MemberId, Membership } from "@joystream/types/members";
-import { Proposal, ProposalStatus } from "@joystream/types/proposals";
-
-import { formatProposalMessage } from "./announcements";
-import { domain } from "../../config";
+import { MemberId,Membership } from "@joystream/types/members";
+import { Proposal } from "@joystream/types/proposals";
 
 // channel
 
@@ -20,7 +20,7 @@ export const currentChannelId = async (api: Api): Promise<number> => {
   return id.toNumber() - 1;
 };
 
-export const memberHandle = async (api: Api, id: number): Promise<string> => {
+export const memberHandle = async (api: Api, id: MemberId): Promise<string> => {
   const membership: Membership = await api.query.members.membershipById(id);
   return membership.handle.toJSON();
 };
@@ -29,7 +29,7 @@ export const memberHandleByAccount = async (
   api: Api,
   account: string
 ): Promise<string> => {
-  const id: number = await api.query.members.memberIdsByRootAccountId(account);
+  const id: MemberId = await api.query.members.memberIdsByRootAccountId(account);
   const handle: string = await memberHandle(api, id);
   return handle;
 };
@@ -99,15 +99,9 @@ export const proposalDetail = async (
   id: number
 ): Promise<ProposalDetail> => {
   const proposal: Proposal = await api.query.proposalsEngine.proposals(id);
-  const { parameters, proposerId, description } = proposal;
-  const author: string = await memberHandle(api, proposerId.toNumber());
-  const createdAt: number = proposal.createdAt.toNumber();
-  const title: string = proposal.title.toString();
-  const proposerHandle: string = await memberHandle(api, proposerId.toJSON());
   const status: { [key: string]: any } = proposal.status;
   const stage: string = status.isActive ? "Active" : "Finalized";
   const { finalizedAt, proposalStatus } = status[`as${stage}`];
-  const type: string = await getProposalType(api, id);
   const result: string = proposalStatus
     ? (proposalStatus.isApproved && "Approved") ||
       (proposalStatus.isCanceled && "Canceled") ||
@@ -117,21 +111,12 @@ export const proposalDetail = async (
       (proposalStatus.isVetoed && "Vetoed")
     : "Pending";
 
-  const message: string = formatProposalMessage([
-    String(id),
-    title,
-    type,
-    stage,
-    result,
-    author
-  ]);
-  const proposalDetail: ProposalDetail = {
-    createdAt,
-    finalizedAt,
-    parameters,
-    message,
-    stage,
-    result
-  };
-  return proposalDetail;
+  const { parameters, proposerId } = proposal;
+  const author: string = await memberHandle(api, proposerId);
+  const title: string = proposal.title.toString();
+  const type: string = await getProposalType(api, id);
+  const args: string[] = [String(id), title, type, stage, result, author];
+  const message: string = formatProposalMessage(args);
+  const createdAt: number = proposal.createdAt.toNumber();
+  return { createdAt, finalizedAt, parameters, message, stage, result };
 };