NAME
Net::Nostr::Reaction - NIP-25 reactions
SYNOPSIS
use Net::Nostr::Reaction;
# Like a note (default content is +)
my $reaction = Net::Nostr::Reaction->react(
event => $note,
pubkey => $my_pubkey,
relay_url => 'wss://relay.example.com',
);
# Dislike
my $reaction = Net::Nostr::Reaction->react(
event => $note,
pubkey => $my_pubkey,
relay_url => 'wss://relay.example.com',
content => '-',
);
# Emoji reaction
my $reaction = Net::Nostr::Reaction->react(
event => $note,
pubkey => $my_pubkey,
relay_url => 'wss://relay.example.com',
content => "\x{1F44D}",
);
# Custom emoji reaction (NIP-30)
my $reaction = Net::Nostr::Reaction->react(
event => $note,
pubkey => $my_pubkey,
relay_url => 'wss://relay.example.com',
content => ':soapbox:',
emoji => ['soapbox', 'https://gleasonator.com/emoji/Gleasonator/soapbox.png'],
);
# React to external content (kind 17)
my $reaction = Net::Nostr::Reaction->react_external(
pubkey => $my_pubkey,
content => "\x{2B50}",
tags => [
['k', 'web'],
['i', 'https://example.com'],
],
);
# Parse reaction from an event
my $info = Net::Nostr::Reaction->from_event($event);
if ($info) {
say $info->is_like ? "Liked" : $info->content;
}
# Validate a reaction event
Net::Nostr::Reaction->validate($event);
DESCRIPTION
Implements NIP-25 reactions. A reaction is a kind 7 event used to react to other nostr events. The content field indicates the reaction value: + or empty string for a "like", - for a "dislike", or an emoji (including NIP-30 custom emoji) for an emoji reaction. Emoji reactions SHOULD NOT be interpreted as likes or dislikes.
Tags include an e tag with the reacted event's ID (MUST), a p tag with the author's pubkey (SHOULD), a k tag with the stringified kind (MAY), and for addressable events an a tag with the event coordinate (SHOULD). The e and a tags SHOULD include relay and pubkey hints. The p tag SHOULD include a relay hint. If multiple e or p tags are present, the target event's ID and pubkey should be last.
External content reactions (websites, podcasts, etc.) use kind 17 with NIP-73 k and i tags instead of e tags.
CONSTRUCTOR
new
my $info = Net::Nostr::Reaction->new(%fields);
Creates a new Net::Nostr::Reaction object. Typically returned by "from_event"; calling new directly is useful for testing or manual construction.
my $info = Net::Nostr::Reaction->new(
event_id => 'aa' x 32,
content => '+',
);
Accepted fields: event_id, relay_url, author_pubkey, content, reacted_kind, event_coordinate. Croaks on unknown arguments.
CLASS METHODS
react
my $event = Net::Nostr::Reaction->react(
event => $original_event, # Net::Nostr::Event to react to
pubkey => $hex_pubkey, # reactor's hex pubkey
relay_url => 'wss://relay.example.com',
content => '+', # optional, default '+'
emoji => ['name', 'url'], # optional, NIP-30 custom emoji
created_at => time(), # optional, passed to Event
);
Creates a kind 7 reaction Net::Nostr::Event. The event parameter is the Net::Nostr::Event being reacted to. The pubkey is the reactor's hex public key.
The content defaults to + (like). Pass - for dislike, an emoji for emoji reaction, or a :shortcode: with the emoji parameter for a NIP-30 custom emoji reaction.
Returns a Net::Nostr::Event with kind 7 and the appropriate tags.
Croaks if event, pubkey, or relay_url is missing.
react_external
my $event = Net::Nostr::Reaction->react_external(
pubkey => $hex_pubkey,
content => "\x{2B50}",
tags => [
['k', 'web'],
['i', 'https://example.com'],
],
);
Creates a kind 17 external content reaction Net::Nostr::Event. The tags must include NIP-73 k and i tags to reference the external content.
Returns a Net::Nostr::Event with kind 17.
Croaks if pubkey, content, or tags is missing.
from_event
my $info = Net::Nostr::Reaction->from_event($event);
Parses reaction structure from a kind 7 or kind 17 Net::Nostr::Event. Returns a Net::Nostr::Reaction object with accessors, or undef if the event is not a reaction kind.
my $info = Net::Nostr::Reaction->from_event($event);
say $info->is_like ? "Liked" : $info->content;
validate
Net::Nostr::Reaction->validate($event);
Validates that a Net::Nostr::Event is a well-formed NIP-25 reaction. Croaks if:
Kind is not 7 or 17
Kind 7 missing
etagKind 17 missing
koritags
eval { Net::Nostr::Reaction->validate($event) };
warn "Invalid reaction: $@" if $@;
INSTANCE METHODS
is_like
$info->is_like; # true for '+' or ''
Returns true if the reaction content is + or an empty string.
is_dislike
$info->is_dislike; # true for '-'
Returns true if the reaction content is -.
ACCESSORS
These are available on objects returned by "from_event".
event_id
my $id = $info->event_id;
The ID of the reacted event (from the e tag), or undef for kind 17.
relay_url
my $url = $info->relay_url;
The relay URL hint (from the e tag), or undef.
author_pubkey
my $pk = $info->author_pubkey;
The pubkey of the reacted event's author (from the e or p tag), or undef.
content
my $c = $info->content; # '+', '-', emoji, or ':shortcode:'
The reaction content.
reacted_kind
my $kind = $info->reacted_kind; # '1' or 'web'
The stringified kind of the reacted event (from the k tag), or undef.
event_coordinate
my $coord = $info->event_coordinate; # '30023:pubkey:d-tag'
The event coordinate (from the a tag), or undef. Only present when reacting to addressable events.