Bounties-Network / BountiesAPI

The caching layer of the Bounties Network
MIT License
44 stars 26 forks source link

Build Slack Client Managing Slack Notifications #4

Closed villanuevawill closed 6 years ago

villanuevawill commented 6 years ago

Description

Currently, we have a notification channel in slack that lets us know when contract events have occurred. In its current state, it only sends the following info to the slack channel:

'Event {} passed for bounty {}'.format(event, str(bounty_id)) or an example: Event BountyFulfilled passed for bounty 162

We would like to make this slack channel public, and would like to provide more information. Gitcoin's notification channel provides a great example of detailed messages.

In our iteration, we'd actually like the std_bounties client to call the slack function at the end of each of the functions. Keep in mind, the std_bounties client is called by the long-running job bounties_subscriber. A file should be added called slack_clienty.py with the same functions as the std_bounties client and work as a mirror.

We want the following info posted for each event:

issue_bounty: Bounty Title, ID, Token info (symbol @ price), Fulfillment Amount, USD Price, Deadline
activate_bounty: Bounty Title, ID, Token, USD_Price
fulfill_bounty: Same as issue_bounty with fulfillment_id included
fulfillment_updated: Bounty Title, ID, fulfillment_id
fulfillment_accepted: Same as issue_bounty with fulfillment_id included
bounty_killed: Bounty Title, ID
contribution_added: Bounty Title, ID, Balance Added (token and USD_PRICE), Previous Balance, Token Info.
deadline_extended: Bounty Title, ID, previous deadline, new deadline
bounty_changed: Bounty title, ID
Issuer Transferred: Bounty Title, ID
Payout Increased: Bounty title, ID, Payout added (token and USD_PRICE), previous payout amount

Also, each should give a link to the issue on the bounty network: beta.bounties.network

Once work has been started, we will give access to the appropriate slack channels. Once completed, the channels will be public.

Pep8 compliance required

Definition of Done

Reviewers

Review Requirements

gitcoinbot commented 6 years ago

This issue now has a funding of 0.17 ETH (91.41 USD @ $537.71/ETH) attached to it.

gitcoinbot commented 6 years ago

Work has been started on the 0.17 ETH (87.37 USD @ $513.94/ETH) funding by:

  1. @ryansdavis
  2. @zoek1

    Please work together and coordinate delivery of the issue scope. Gitcoin doesn't know enough about everyones skillsets / free time to say who should work on what, but we trust that the community is smart and well-intentioned enough to work together. As a general rule; if you start work first, youll be at the top of the above list ^^, and should have 'dibs' as long as you follow through.

    On the above list? Please leave a comment to let the funder and the other parties involved what you're working, with respect to this issue and your plans to resolve it. If you don't leave a comment, the funder may expire your submission at their discretion.

zoek1 commented 6 years ago

@villanuevawill i propose use decorators that accept a format like "Bounty Title, ID, fulfillment_id" and provides the bounty object to each method in std_bounties client. After the method is executed, the notification to slack is sended. In thar way reduce 1:1 modification relation between slack and the client. what do you think?

ryansdavis commented 6 years ago

@villanuevawill Where do you think is the best directory for 'slack_client.py' to live? EDIT: was thinking 'bounties_api/std_bounties/slack_client.py' looks good, yah?

villanuevawill commented 6 years ago

@zoek1 I like the idea overall, however we run into a couple issues with this approach. 1 issue is that in some of these we need the fulfillment details. Another issue is that for issue_bounty, the bounty does not exist yet. For fulfill_bounty, the fulfillment object does not exist yet either.

The other concern I would have is that I want to keep the functions independent from the client.py functions. In the case we ever have to work on speeding up our realtime syncing processes, we may want to move the slack client to a listening service/separate job. Also, not all the notifications require acquiring the full bounty model.

I do like the concern of the 1:1 modification relation. I was thinking that we could do some refactoring where there is a generic client class for each event that calls the function on both. In this case, the client.py functions wouldn't need to know about the slack client functions.

Thoughts?

villanuevawill commented 6 years ago

@zoek1 and @ryansdavis - Since @zoek1 dibbed this first, if he still wants to move forward on this task, then I would say he would get priority. If you both want to work together, then that is fine as well, but typically first worker will handle this. @zoek1 let me know if you plan on moving forward on this.

zoek1 commented 6 years ago

Of course @villanuevawill, i'm working on this right now! I hope make the pull request tomorrow.

villanuevawill commented 6 years ago

also @zoek1 - where in Mexico do you live? I'm in Mexico City for the next 2 weeks.

zoek1 commented 6 years ago

@villanuevawill i was thinking about your concerns, and it can easily achieved in a "monadic" way.

  1. The first step is refactor the retrieving object (getting the Bounty or Fulfillment object): 1.1 If the object is required to exist, we use the operation >> that pass the object retrieved in case to exists or terminates the execution. 1.2 If is required that the object doesn't exists, we use !>> that return an empty Bounty or Fulfillment object in case doesn't exists or terminates the execution in case that exists the object
  2. The object is passed to the updater function, that return the object updated, in case the update fails, it raise an exception or returns None so the execution stops.
  3. We use a filter function that narrow the fields and return a dict with the required keys, if the fields doens't exist the execution stops
  4. Call slack enqueue or notification function
get_bounty(bounty_id) 
  !>> bounty_client.fulfill_bounty(fulfillment_id, ...) 
  >> narrow(['title', 'id', 'token', 'usd_price', ...)  
  >> slack_enqueue_or_notification

This functional way is more appropriate to async functionality or to move the slack notification system a listening service/separate job.

Obviosly we'll be using a pythonic implementation, this code is just an example.

i'll be in mexico city this week also.

villanuevawill commented 6 years ago

@zoek1 I like the proposal. Go for it. Only thing is it would be cool if each of the operations gets abstracted to a parent client that does this. That way the code is clean and just has one call in each event if statement. 👍 go for it.

Also, send me a dm on the gitcoin community slack - bountiesWill since you're in town!

ryansdavis commented 6 years ago

@villanuevawill @zoek1 Sounds like ya'll got a handle on this :+1: :+1:

zoek1 commented 6 years ago

@villanuevawill all events are processed correctly in this PR #12. I just need to clean the code and write pending tests. Can you give me feedback about the PR, please?

gitcoinbot commented 6 years ago

Work for 0.17 ETH (70.57 USD @ $415.12/ETH) has been submitted by:

  1. @zoek1

    Submitters, please leave a comment to let the funder (and the other parties involved) that you've submitted you work. If you don't leave a comment, the funder may expire your submission at their discretion.

gitcoinbot commented 6 years ago

The funding of 0.17 ETH (87.37 USD @ $513.94/ETH) attached to this issue has been approved & issued to @zoek1.

villanuevawill commented 6 years ago

Great work here.