Git Product home page Git Product logo

hopr-chatbot's People

Contributors

0xjjpa avatar nionis avatar shresthagrawal avatar thewanderingeditor avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

hopr-chatbot's Issues

Create an reusable library able to connect to the Twitter API

Introduction

All bots will require to read data from the Twitter API to verify some actions. Of course, these actions depend on the bot, but in most cases, we'll need to ensure the hoprnet is mentioned, as well as specific tags. We need a generic interface that can be extended by the bots in a generic fashion.

Task Description

  • Create an interface that can be implemented by any both that contains the following methods:
    • parseTweet(url: TweekLink) => { user_mentions, hashtags, content }: Method able to obtain the relevant data from a given week.
    • onTweet(callback: ChatPromise(res:ChatBotSuccess => ChatMessage, rej:ChatBotFailure => ChatMessage) => ()): Method able to be hooked to a generic ChatPromise which resolves to a specific ChatMessage given a condition within the chatbot.

Implement Bouncer Bot

Introduction

For our Week 3, we'll be creating Bouncer Bot. Given an outline, we now need to implement its actions for it to be fully functional.

Task Description

  • Based on the outline, implement all functions, rules, methods and payment conditions for Bouncer bot.

Create cover-node cron-job API

  • Setup API that can be queried to allow looping through our saved tweets to check if they are valid and the node still has the balance.
  • If query is valid, then send a message using the looped node as intermediate node, paying them xHOPR tokens.
  • Setup API that can showcase this information in real-time for other users to see, alongside an HTML page which can be seen online.

Check relayed messages are valid messages from coverbots

Introduction

Requires #48. The way coverbot has been verifying users is by sending a message to itself in the following manner:

coverbot.send(coverbot, message, [node])

You can actually see how coverbot sends those messages in https://github.com/hoprnet/hopr-chatbot/blob/feature/basodino/src/bots/coverbot/index.ts#L322. The issue of that approach is that due to the way we encode messages, any node could "pretend" being coverbot. In reality, a closer analysis to the way coverbot is verifying nodes is by decoding the messages and seeing the actual method as follows:

coverbot.send(coverbot, "$coverbot: verifying $node", [node])

This means that any node could actually do the following:

node.send(coverbot, "$coverbot: verifying $node", [])

which would be picked up in https://github.com/hoprnet/hopr-chatbot/blob/feature/basodino/src/bots/coverbot/index.ts#L406 as "coverbot successfully used $node" for relaying, which in reality would be a node that sent a message with settings includeRecipient false with the content "$coverbotAddress: verifying $myOwnNode".

This was a known 🐛 in the bot internally, which was up for grabs during our last session 👀 . As we will be using additional functionality for incoming sessions, we'll be patching that now. From now on, the "listener" of a message for coverbot upon successful relay (i.e. this line) will not only check that the message sent to it "comes from"* a coverbot address, but also that the contents have the $SECRET created for that particular node.

Task Description

Additional notes

  • we marked "comes from" because in reality, HOPR does not sign messages and currently makes no use of certificates to verify a message was sent by A or B. This is by design, but could be changed in the future and/or implemented on an application layer (as we are currently doing with coverbot with $SECRET, although there are of course better implementations).

Store coverbot address alongside a random number for further verification

Introduction

As part of the new relay schema, coverbots can send other coverbots messages to "ask" them to try and relay a message on the original's coverbot behalf. This process can be completed as much as N times, and looks something as follows:

Paper HOPR-IN 7

To avoid fake coverbots to trigger calls from nodes that are not HOPR Services AG bots, we'll store the address of the "official" coverbots into our database. We'll then ask coverbot to only listen to relays from messages that come from these registered coverbots.

Task Description

  • On start, store in the "database" inside the "table" bots the following key-value entry {$NODE: $SECRET} where $NODE is the this.address of the bot and $SECRET is a randomly generated numerical number. This value can be rewritten as many times, as will be read before validating any relay.

Notes

Upon completing this task, here's what the Firestore database could look like:

database
\_ basodino-v2-develop-steven
    \_ score = {...}
    \_ state = {...}
    \_ bots
       \_ { 16Uiu2HAkzz6ciBeuPCJ4mL3BCgbPhW4SyRwn8jd4gv8Q8w3P2Q5W: 939926 }

Bouncer Bot

As part of our community calls, we are constantly building games and bounties to showcase the uses of the HOPR protocol. Bounties are short-lived, asynchronous, specific incentivized activities that are run bi-weekly using eurogame-like dynamics.

BouncerBot is a chatbot built on top of the HOPR Protocol that invites Bounty users to interact with HOPR Nodes using HOPR Chat. Bouncerbot goals are to engage users, teach them about the commands available in HOPR Chat, while showcasing the dynamics of the protocol where the content can be hidden or not upon request.

Modify chatbot to allow interactive actions on a daily basis

Introduction

We'll be looking to ask people to do activities through chatbot as part of the dailies.

Task Description

  • Modify chatbot so it can run on daily mode
    • daily $day shows the timeframe where the bot can listen to you, whether the daily is completed and the time left.
    • daily $day view shows a list of actions, (e.g. open a payment channel to me) and whether message.from completed it.
    • daily $day verify $action prompts the bot to execute an action that verifies the user completes everything.
    • daily $day url returns the URL where that daily results can be seen by anyone.

Restore and load once the score table from another network

Introduction

For the round two of basodino, we'll need to copy the score "table" from the basodino "database" from our Firestore actual database, and restore them with a score of 100. This process should only run once if the "database" value for the score "table" is empty.

Task Description

  • Add in coverbot/constants.ts an array of the possible "databases" we can switch/base our scores from. Right now the value is ["basodino","basodino-develop"]
  • Create COVERBOT_DATABASE_RESTORE_SCORE_FROM env in our env.ts, with possible values being grabbed from coverbot/constants.ts
  • On load, coverbot checks if its score "table" is empty AND COVERBOT_DATABASE_RESTORE_SCORE_FROM is different from null. If so, then it copies the score "table" from COVERBOT_DATABASE_RESTORE_SCORE_FROM's value, and iterates over them to make them 100 before updating the new score table.
  • If a previously loaded score "table" exists, then nothing is done.

Notes

Although implementation is suggested, another alternative is welcomed. The goal is provided in the task subject. Also, the terms "table", "database" and database are used to express the NoSQL nature of our score key-value entry, where:

database (firestore)
\_ "database" (network, e.g. basodino)
   \_ "table" (i.e score or state)

Update settings for chatbot for development/deployment

  • Update README w/docker-compose.yml instructions to be able to use chatbot.
  • Create cloudconfig.yml file to allow creating Docker image for chatbot upon master merge.
  • Confirm workflow with pull-request to allow new image creation against hoprassociation

Change our setScore operations for Firestore.increment

Introduction

As we'll have now multiple coverbots writing into our score database, we need to ensure we increase our node scores atomically, as otherwise if N bots write on a given node at the same time, instead of increasing their score by relay_points * N points, we'll be doing relay_points only.

Task Description

Create an extendable interface that connects to the LinkDrop SDK and manages the payments of the bounties

Introduction

We need to ensure that the bots are able to pay back bounties given specific rules are completed. To do so, we'll be using the LinkDrop SDK to manage the creation of the payment based on the run-time parameters, by creating an interface each bot can extend. Each bot will be able to provide links with ERC-20 or Ether in them, and whenever they are deployed, initialize the adequate contract calls as to budget their rewards.

Task Description

  • Provide an interface IPayable which adds the following methods and objects to the bot:
    • setupSDK(): Method able to read from ENV to initialize the LinkDrop SDK and fail if it misses a param.
    • setupProxy(key: EthereumPrivateKey, campaignId: "$BOT_NAME", budget: number ): Method able to deploy a proxy contract with a given budget to be used for generating the rewards.
    • rules: { "rewardees": number, "reward": number }: The rules of engagement for the bot to know how many bounties it can pay per person.
    • payBounty(address: HOPRAddress): Method to pay the bounty which generates a LinkDrop link and sends it to the HOPR Address.

Notes

It's important to be able to provide network and other parameters for the LinkDrop SDK. Make sure to add these as environment variables.

The server isn't crawling newly connected nodes, which might prompt some timeouts

Introduction

In short, the server seems to welcome any node but might not learn about it until later when trying to send a message. Whoever, it could timeout before sending, not allowing it to crawl and thus failing to reach the original sender.

Task Description

  • Ensure server crawls the network every verification cycle to make sure it's able to find newly introduced peers.

Create cover-node bot

  • Allow bot to listen to messages from any user, and presenting them with the instructions if node hasn't been detected yet.
  • Allow bot to listen to tweets from any user, and obtain and verify their node address based on the tweet, which should include the #HOPRNetwork tag in it.
  • Allow bot to obtain Ethereum address based on the HOPR Address given from the tweet, and verify that the node has at least 10 xDAI in them.
  • Upon verifying all previous data, allow bot to save the Tweet into an in-memory set, which will be used for verification later.
  • Upon verifying all previous data, allow bot to open and fund an open payment channel with you w/10 xHOPR tokens which will be slowly dripped into the connected node.

Update coverbot to allow retry using support coverbots

Introduction

For context, a coverbot does the following actions:

  1. Registration (i.e. process users twitter ids and nodes and register them into our database)
  2. Verification (i.e. go through our nodes lists and ensure node is online)
  3. Relaying (i.e. send multi-hop message to our user to ourselves)
  4. Scoring (i.e. updating the user's score based on a successful relay)

To increase availability in round 2, we need to modify coverbot to use other coverbot as to relay connections whenever needed. The most common case, is when coverbot can not reach a node on a first try on 3. Whenever coverbot fails to do 3 to a node (e.g. alice), coverbot can try the next round to use one of the support coverbot to be able to reach alice instead. In short, this looks something like this:

coverbot.send(coverbot, [alice]) then coverbot.send(coverbot, [alice, support_{RU,JP,US}]) if fails.

Visually, this looks something like this:

image

We want to make sure only coverbot uses another coverbot to relay, so we'll add a separate table in the database where each coverbot will register its own address to ensure they only listen to other coverbots. We will tackle this in a separate ticket though.

Task Description

  • Update our relayTimeout data structure from Map<string, NodeJS.Timeout> to Map<{coverbot:string,node:string}, NodeJS.Timeout>. string is meant to be each respective node address.
  • Update timeout in https://github.com/hoprnet/hopr-chatbot/blob/feature/basodino/src/bots/coverbot/index.ts#L290-L299 to avoid giving up and instead, fetch another coverbot address and retry the message.
  • Updating listener handler to not only check for message.from == this.address but instead for message.from in coverbotAddressArray

Add Bouncer Bot outline

Introduction

For our Week 3, we'll be creating Bouncer Bot. The outline is its background story to it, and the logic that needs to follow, alongside the rules of engagement and when a price needs to be awarded.

Task Description

  • Create a README.md within bouncerbot folder that describes bouncerbot outline.

Create a generic chatbot interface able to be inherited

Introduction

All chatbots have common tasks and status that allows them to have generic functions while at the same time having their own specific “personality”. To achieve so, we need to create a Chatbot interface able to provide a structure for future chatbots, as to ensure they all a similar pattern when possible.

Task Description

  • Declare the interface ChatBot, which provides the general interface a bot needs to overload as to be able to be instantiated. This interface should include the following methods and types and/or a similar structure for instantiating bots on a long term basis (method definition can be changed):
    • init() => void: Initial behaviour for the bot to use whenever it starts.
    • type ChatBotStatus: enum: An enum describing all the possible status the bot can have.
    • type ChatBotCommands: enum: An enum describing all the methods the bot can have.
    • type ChatBotMessages: enum: An enum describing all the possible messages the bot can have.
    • state: { [key: ChatStatus]: ChatStatus }: An object containing an array describing the possible states the bot can go from/to.
    • directory: { [key: HOPRAddress]: number }: An object mapping interacting users and their messages.length
    • winners[]: HOPRAddress[]: An array showcasing the participants that have successfully completed the bounty from the bot.
    • commands: { [key: ChatBotCommand]: () => void }: An array describing which commands are enabled
    • send(address: HOPRAddress, message: HOPRMessage): A method for sending message to a node
    • stateReducer(address: HOPRAddress, from: ChatStatus, to: ChatStatus): A method that is being called whenever the bot changes state for a given HOPRNode, and updates the sate as needed for that user.
    • onMessage() => void: A method that is being called back when the bot receives a message
    • onSend() => void: A method that is called back when the bot sends a message

Minor improvements are reviewals for bouncerbot

  • Provide some sort of BOT_TIMESTAMP that allows to only "start" bot in such BOT_TIMESTAMP
  • Upon launching the bot, a TIMESTAMP is generated, and we need to make sure that the tweets do not come earlier than give TIMESTAMP (avoid reusing tweets).
  • Change parsing message to understand party rather than look only at the beginning of the message.
  • Change sending automating message from a timeout to a check of multiple messages.
  • Remove address from hint message.
  • Store twitter handlers to avoid users farm the bot w/the same twitter account
  • Move twitter usernames to environment variables to allow dynamic usernames, and showcase that in setup
  • Move twitter hashtags to environment variables to allow dynamic hashtags, and showcase that in setup
  • Make sure to store winner nodes in memory to avoid people trying to win multiple times
  • Make sure to store winner twitter usernames in memory to avoid people trying to win multiple times

WIP: Mysterybot

Thanks for your work so far on the cluebot, @shresthagrawal !

For the next iteration, let's change the flow slightly so that players can make some limited number of investigations, can make some limited number of guesses, and exactly one accusation, which needs to be made by tweet and parsed by the bot.

  • I think we should rename this bot Mysterybot, because I would like to reuse it in a later bounty where the name Cluebot doesn't make as much sense.

  • Implement two modes: bounty mode and fun mode. In bounty mode players must tweet their accusation and can win xDAI if they're among the first winners. In fun mode, the social media interaction is turned off and players can't win xDAI.

  • Add a new command investigate [room]. Three[?] times per case, the player can investigate a room. The response will either be to confirm the room is where the crime was committed (if they're investigating the right room) or (in every other room) to eliminate that room and a random incorrect suspect and weapon.

  • Formalize the commands. So instead of just parsing for suspect, weapon, room, let's have a clearly defined list of inputs:

Rules: Displays a message explaining the object of the game and how many guesses, investigations and accusations you get.

Winners (in bounty mode): Displays the number of winners and the number of prizes remaining.

Guess [suspect] [weapon] [room]: Make a guess at the solution: as now, the bot will respond to explain which items are wrong. If correct, the bot should indicate that the solution is correct, but not move straight to the reward.

Accuse [tweet URL] (in bounty mode): Make a single guess at the solution. If it's right, the player is congratulated and gets their reward. If it's wrong, the game is over.

Accuse [suspect] [weapon] [room] (in fun mode): Make a single guess at the solution. If it's right, the player gets congratulated. If wrong, the game ends. Entering an accusation in this format in bounty mode will prompt the player about tweeting.

Investigate [room]: A new command, explained above.

Help: Lists and explains the commands

Entering a command in the wrong format should trigger a message explaining the correct format.

  • Tidy up the text: I'll take charge of this. I'll probably rewrite some of the messages, and add a bit more flavour to the start and end, but I won't fiddle with the underlying logic.

Add Bouncer Bot deployment instructions

Introduction

For our Week 3, we'll be creating Bouncer Bot. As we need to deploy it live in our platform, it's important to provide the instructions on the base minimal requirements for its Docker image for deployment.

Task Description

  • Provide an example of a docker run command that has all the environment variables BouncerBot needs for it to run locally successfully.
  • Provide a docker-compose file that is able to quickly spin up a BouncerBot within the repository with pre-defined variables.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.