#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum ReactionSentiment {
Positive,
Negative,
Neutral,
}
const POSITIVE: &[&str] = &["👍", "👌", "💪", "🫡", "🆗", "🔥", "💯"];
const NEGATIVE: &[&str] = &["⛔️", "⛔", "🚫", "🛑", "👎"];
pub(crate) fn classify_reaction(emoji: &str) -> ReactionSentiment {
let trimmed = emoji.trim();
if POSITIVE.contains(&trimmed) {
ReactionSentiment::Positive
} else if NEGATIVE.contains(&trimmed) {
ReactionSentiment::Negative
} else {
ReactionSentiment::Neutral
}
}
pub(crate) fn build_reaction_prompt(first_name: &str, emoji: &str, preview: &str) -> String {
let steer = match classify_reaction(emoji) {
ReactionSentiment::Positive => format!(
"This reads as approval from {first_name}: you're on the right path. Acknowledge \
{first_name} by first name and keep the momentum. If you had proposed a next \
step or a turn is in progress, treat it as a green light to proceed."
),
ReactionSentiment::Negative => format!(
"This reads as {first_name} flagging that something is off. Address {first_name} \
by first name, pause rather than press on, and ask what they'd like changed."
),
ReactionSentiment::Neutral => {
format!("Acknowledge {first_name} by first name and respond naturally.")
}
};
format!(
"[Reaction notification] {first_name} reacted with {emoji} to your message:\n\
\"{preview}\"\n\n\
{steer}\n\n\
You may react back (use <<react:EMOJI>>), reply with text, or do both. If the \
reaction doesn't warrant a text response, reply with <<react:{emoji}>> to silently \
acknowledge."
)
}
pub(crate) fn build_midturn_reaction_message(first_name: &str, emoji: &str) -> String {
match classify_reaction(emoji) {
ReactionSentiment::Positive => format!(
"[Live feedback from {first_name}: reacted {emoji}] They approve of the current \
direction, you're on the right path. Keep going with the current plan, no need to \
stop or re-confirm. Acknowledge {first_name} by first name when you next reply."
),
ReactionSentiment::Negative => format!(
"[Live feedback from {first_name}: reacted {emoji}] They want you to PAUSE. Stop at \
the next safe point, summarize what you've done so far, and ask {first_name} (by \
first name) what they'd like changed before continuing."
),
ReactionSentiment::Neutral => format!(
"[Live feedback from {first_name}: reacted {emoji}] Take it into account and \
acknowledge {first_name} by first name when you next reply."
),
}
}