mirror of
https://github.com/basecamp/once-campfire.git
synced 2026-08-13 02:20:42 +09:00
feat: Add bot API endpoint for adding reactions (boosts) to messages
Adds a new endpoint that allows bots to add emoji reactions (boosts) to messages: POST /rooms/:room_id/:bot_key/messages/:message_id/boosts This enables bots to acknowledge messages with reactions like 👀 (eyes) when mentioned, providing immediate feedback to users before generating a full response. The endpoint: - Validates the bot is a member of the room - Validates the message exists in the room - Broadcasts the boost to connected clients via Turbo Streams - Returns 201 Created on success, 404 if room/message not found Co-authored-by: openhands <openhands@all-hands.dev>
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
class Messages::Boosts::ByBotsController < ApplicationController
|
||||
allow_bot_access only: :create
|
||||
|
||||
def create
|
||||
set_message
|
||||
@boost = @message.boosts.create!(content: read_body)
|
||||
|
||||
broadcast_create
|
||||
head :created
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
head :not_found
|
||||
end
|
||||
|
||||
private
|
||||
def set_message
|
||||
@room = Current.user.rooms.find(params[:room_id])
|
||||
@message = @room.messages.find(params[:message_id])
|
||||
end
|
||||
|
||||
def read_body
|
||||
request.body.rewind
|
||||
request.body.read.force_encoding("UTF-8")
|
||||
ensure
|
||||
request.body.rewind
|
||||
end
|
||||
|
||||
def broadcast_create
|
||||
@boost.broadcast_append_to @boost.message.room, :messages,
|
||||
target: "boosts_message_#{@boost.message.client_message_id}",
|
||||
partial: "messages/boosts/boost",
|
||||
attributes: { maintain_scroll: true }
|
||||
end
|
||||
end
|
||||
@@ -65,6 +65,7 @@ Rails.application.routes.draw do
|
||||
# Bot API endpoints - authenticated via bot_key in URL
|
||||
get ":bot_key/messages", to: "messages/by_bots#index", as: :bot_messages_index
|
||||
post ":bot_key/messages", to: "messages/by_bots#create", as: :bot_messages
|
||||
post ":bot_key/messages/:message_id/boosts", to: "messages/boosts/by_bots#create", as: :bot_message_boosts
|
||||
|
||||
scope module: "rooms" do
|
||||
resource :refresh, only: :show
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
require "test_helper"
|
||||
|
||||
class Messages::Boosts::ByBotsControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
@room = rooms(:watercooler)
|
||||
@message = messages(:fourth) # Message in watercooler room where bender bot is a member
|
||||
@bot = users(:bender)
|
||||
end
|
||||
|
||||
test "create adds a boost to the message" do
|
||||
assert_difference -> { @message.boosts.count }, +1 do
|
||||
post room_bot_message_boosts_url(@room, @bot.bot_key, @message), params: +"👀"
|
||||
assert_response :created
|
||||
end
|
||||
|
||||
assert_equal "👀", @message.boosts.last.content
|
||||
end
|
||||
|
||||
test "create with emoji reaction" do
|
||||
assert_difference -> { Boost.count }, +1 do
|
||||
post room_bot_message_boosts_url(@room, @bot.bot_key, @message), params: +"🎉"
|
||||
assert_response :created
|
||||
end
|
||||
end
|
||||
|
||||
test "create with text reaction" do
|
||||
assert_difference -> { Boost.count }, +1 do
|
||||
post room_bot_message_boosts_url(@room, @bot.bot_key, @message), params: +"Nice!"
|
||||
assert_response :created
|
||||
end
|
||||
|
||||
assert_equal "Nice!", @message.boosts.last.content
|
||||
end
|
||||
|
||||
test "create broadcasts the boost" do
|
||||
assert_turbo_stream_broadcasts [ @message.room, :messages ], count: 1 do
|
||||
post room_bot_message_boosts_url(@room, @bot.bot_key, @message), params: +"👍"
|
||||
end
|
||||
end
|
||||
|
||||
test "create requires valid bot key" do
|
||||
assert_no_difference -> { Boost.count } do
|
||||
post room_bot_message_boosts_url(@room, "invalid-bot-key", @message), params: +"👀"
|
||||
end
|
||||
assert_response :redirect # Redirects to login
|
||||
end
|
||||
|
||||
test "create returns not_found for room bot is not a member of" do
|
||||
room_without_bot = rooms(:designers)
|
||||
message_in_other_room = messages(:first) # Message in designers room
|
||||
|
||||
assert_no_difference -> { Boost.count } do
|
||||
post room_bot_message_boosts_url(room_without_bot, @bot.bot_key, message_in_other_room), params: +"👀"
|
||||
end
|
||||
assert_response :not_found
|
||||
end
|
||||
|
||||
test "create returns not_found for message not in the room" do
|
||||
message_in_other_room = messages(:first) # Message in designers room, not watercooler
|
||||
|
||||
assert_no_difference -> { Boost.count } do
|
||||
post room_bot_message_boosts_url(@room, @bot.bot_key, message_in_other_room), params: +"👀"
|
||||
end
|
||||
assert_response :not_found
|
||||
end
|
||||
|
||||
test "create can't be abused to post boosts as regular user" do
|
||||
user = users(:kevin)
|
||||
bot_key = "#{user.id}-"
|
||||
|
||||
assert_no_difference -> { Boost.count } do
|
||||
post room_bot_message_boosts_url(@room, bot_key, @message), params: +"👀"
|
||||
end
|
||||
assert_response :redirect
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user