Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NIP-41: Poll & Vote Event #148

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open

Conversation

0xtlt
Copy link
Contributor

@0xtlt 0xtlt commented Jan 5, 2023

41.md Outdated
}
```

Then the client should display voting options if more than **1 choice** is present in the poll.
Copy link

@AngusP AngusP Jan 17, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only one "poll" may seem pointless, but perhaps it'd be useful for an "Agree", "No", "Sign Up", "ACK" or whatever where ignoring it is an implicit no? Given that the responses are all going to be public events, so you could DM everyone if it was for a 'signup' mechanism or whatever.

So, I think it'd make sense to still show it if only one choice is present, even if that seems odd/niche

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Poll and sign up for something are two differents things, And we need an explicite usage of the poll, then if only one poll is defined, we can't decide for the user if he wanted to have "agree", "no" or sign up"

41.md Outdated

Then the client should display voting options if more than **1 choice** is present in the poll.

The client can then submit the vote by sending an event with kind `8` and its content which will be the index (start at `0`) of the chosen choice.
Copy link

@AngusP AngusP Jan 17, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not re-use/extend/abuse the NIP-25 reactions (type 7).

Then the poll options instead would be:

{
    "tags": [
        ["poll", "Choice 1"],
        ["poll", "Choice 2"],
        ["poll", "Choice 3"],
    ]
}

and reaction/response event type 7 would be like this:

{
    "id": "<ID>",
    "sig": "<signature>",
    "kind": 7,
    "tags": [
        ["e", "<event ID of the note with the poll>"],
        ["p", "<pubkey of the note with the poll>"]
    ],
    "pubkey": "<pubkey of the responder>",
    "content": "Choice 1",
    "created_at": 1234567891
}

Where the "content" has to exactly match the choices given to count, otherwise it's treated like a normal reaction.

For better interoperability( /not breaking the current type 7 use), using 1️⃣, 2️⃣, 3️⃣, 4️⃣ etc. as first char of the "poll"tag and then allowing the reaction to only need to include the minimum unique prefix to 'count' so a simple 1️⃣ emoji reaction would work as a vote:

poll

{
    "tags": [
        ["poll", "1️⃣ Choice 1 text"],
        ["poll", "2️⃣ Choice 2 text"],
        ["poll", "3️⃣ Choice 3 text"],
    ]
}

reaction

{
    ...,
    "content": "1️⃣",
}

Any reaction that doesn't match any of the "poll" options would be treated as just a normal reaction

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did see on your Damus PR though that @jb55 wasn't sure about re-using/overloading the reaction type

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem with using reactions is that the reaction is not necessarily used to respond to a poll but is intended for "reaction" use only.
So with @jb55, we thought it would be better to explain this "feature" via a dedicated NIP :)

Copy link

@jrc-dev jrc-dev May 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Polls are an event, reactions to an event that is a poll is indeed an answer, seems perfect simple to me. YAGNI! Also I disagree with reactions is not to respond a poll because reactions is also a flexible answer(upvote, donwvote, emoji), why not the answer of a poll, it is perfect.
The only thing that we are doing is leaving the count of answer to the client implementation, a thing that they are already doing with upvote and downvote.

@Giszmo
Copy link
Member

Giszmo commented Jan 17, 2023

The nip should be more explicit at least with an example how poll should work.

I suggest this should be valid:

poll:

{
    "tags": [
        ["p", <someKey>],
        ["poll", "Choice 1 text"],
        ["e", <someEvent>],
        ["poll", "Choice 2 text"],
        ["poll", "Choice 3 text"],
    ]
}

with votes being 0-based in the full tags array:

{
    ...,
    "content": "4", # this is "Choice 3 text". Content 0, 2 or 5 would be invalid votes.
}

41.md Outdated
Comment on lines 44 to 46
#### Warning

Keep in mind that all votes are public and accessible to everyone.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clients should make explicit that votes are public. Warning the implementer is not necessarily reaching the user.

@0xtlt
Copy link
Contributor Author

0xtlt commented Jan 17, 2023

Mmmh, I prefer to stay on the index of the tags filtered for poll values
If a day, a NIP makes tags array "dynamic" or another thing, I don't want to make this NIP blocking another possible future evolution m

But I will add examples to this NIP 👍

The nip should be more explicit at least with an example how poll should work.

I suggest this should be valid:

poll:


{

    "tags": [

        ["p", <someKey>],

        ["poll", "Choice 1 text"],

        ["e", <someEvent>],

        ["poll", "Choice 2 text"],

        ["poll", "Choice 3 text"],

    ]

}

with votes being 0-based in the full tags array:


{

    ...,

    "content": "4", # this is "Choice 3 text". Content 0, 2 or 5 would be invalid votes.

}

@Giszmo
Copy link
Member

Giszmo commented Jan 17, 2023

Please also explain the upside/downside compared with the prior PR #111

@Giszmo
Copy link
Member

Giszmo commented Jan 17, 2023

Mmmh, I prefer to stay on the index of the tags filtered for poll values If a day, a NIP makes tags array "dynamic" or another thing, I don't want to make this NIP blocking another possible future evolution m

The sorting of poll tags depends on the sorting of all tags. I don't get your argument here.

Why not slap all options into one poll tag like #111 ?

@0xtlt
Copy link
Contributor Author

0xtlt commented Jan 17, 2023

You're right @Giszmo, I made suggestions to the #111 PR, hope it will be helpful 👍

@improvethings
Copy link

I propose allowing for dynamic ranges for polling (for example, out of 1 to 100):

{
...
"kind": 1,
"tags": [
...
["response", "boolean|int"]
["poll", "Choice 1"],
["poll", "Choice 2"],
["poll", "Choice 3"]
...
],
}

and response:

{
...
"kind": 8,
"tags": [
...
["e", "", ""]
...
],
"content": "1"
}

@0xtlt
Copy link
Contributor Author

0xtlt commented Feb 28, 2023

Okay guys, I updated this NIP because there isn't much news on the other one, and there are some updates here.

@fernandolguevara
Copy link
Contributor

#111 updated!

@jrc-dev
Copy link

jrc-dev commented May 26, 2023

Sorry, I'm just starting to understand the protocol, I'll leave my simple idea here and of course I must makinh a lot of mistakes.

A poll is an event with a type: 0,set_metadata(poll metadata), the details of a poll are described in our nip-41, now about the voting poll.

Votes are reactions (NIP-25) to the event(poll): upvote! But then we asked how can I vote the poll option since the upvote is just "+" content, well nip-25 is flexible on that and we can pass the choosed pool option as answer in that place, so not much change in anything...

What can go wrong with this approuch ?

@jrc-dev
Copy link

jrc-dev commented May 26, 2023

Also, let's change the limit of 4 options to 10, 10 will be ugly in the frontend, but is not our problem, it is a frontend problem. why do that? we can use this to other things, like review(0-10) and use a star component... just 4 will limited the use case.

@AustinKelsay
Copy link

Is this implemented on any clients?

@gocedoko
Copy link

Hi everyone, can we maybe wake up this NIP ?
I will have some time next month to do some work and maybe implement this in 1-2 clients.

But I have some further suggestions/needs:

  • I wanted to have polls into direct messages, (something like in Whatsapp or Facebook)
    and for this they need to be private, so we should be able to keep the answer in the tag encrypted (same as the direct messages)

  • As discussed before, we need more options to choose from, Whatsapp allows up to 12 and facebook even more, so I'd say to allow around 15.
    In a few friends groups that I have in whatsapp, we often do polls (as to decide what are we gonna do next weekend), and we end up sometimes close to 10 possible options.

@0xtlt please let me know if we should continue working with this PR or should I just fork another one :)

@gocedoko
Copy link

Now I also see this request for zapless polls in amethyst
vitorpamplona/amethyst#935

@fiatjaf
Copy link
Member

fiatjaf commented Jun 24, 2024

We should probably do something like #148 (comment) with limitless options.

This would also work in NIP-29 groups.

We can define an entirely new scheme for DMs, but I don't get when you would use polls in DMs, since it's just two people.

@gocedoko
Copy link

gocedoko commented Jun 24, 2024

There are private group chats in 0xChat, that was what I was talking about.

It looks like Nip101 would actually satisfy and even extend what I intended #1190

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants