From 3364931bae856f50e4bc5fcf567fed62c25bc42c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Verg=C3=A9s?= Date: Wed, 25 Feb 2026 21:25:36 +0100 Subject: [PATCH 1/4] prevent non commentable components to be commented --- .../chatbot/workflows/proposals_workflow.rb | 32 ++++++++------ .../workflows/proposals_workflow_spec.rb | 42 +++++++++++++++---- 2 files changed, 55 insertions(+), 19 deletions(-) diff --git a/app/services/decidim/chatbot/workflows/proposals_workflow.rb b/app/services/decidim/chatbot/workflows/proposals_workflow.rb index 7cc11c8..06ac17f 100644 --- a/app/services/decidim/chatbot/workflows/proposals_workflow.rb +++ b/app/services/decidim/chatbot/workflows/proposals_workflow.rb @@ -71,18 +71,22 @@ def send_proposal_details # Use video thumbnail as header image if available, otherwise use proposal photo with fallback header_image = video.thumbnail_url.presence || resource_url(proposal.photo, fallback_image: true) - send_message!( - type: :interactive_buttons, - body_text: body, - header_image:, - footer_text: sanitize_text(proposal.creator_author&.presenter&.name, 60), - buttons: [ - { - id: "comment-#{proposal.id}", - title: I18n.t("decidim.chatbot.workflows.proposals.buttons.comment") - } - ] - ) + if component_comentable? + send_message!( + type: :interactive_buttons, + body_text: body, + header_image:, + footer_text: sanitize_text(proposal.creator_author&.presenter&.name, 60), + buttons: [ + { + id: "comment-#{proposal.id}", + title: I18n.t("decidim.chatbot.workflows.proposals.buttons.comment") + } + ] + ) + else + send_message!(body:, preview_url: true) + end end # Calculate maximum body length dynamically to stay within 1024 char limit @@ -143,6 +147,10 @@ def component @component ||= Decidim::Component.find_by(id: config[:component_id]) end + def component_comentable? + @component_comentable ||= component&.settings&.comments_enabled? + end + def proposals @proposals ||= begin proposal_search = Decidim::Proposals::Proposal.where(component:).published.only_amendables diff --git a/spec/services/workflows/proposals_workflow_spec.rb b/spec/services/workflows/proposals_workflow_spec.rb index 29239a1..64773cf 100644 --- a/spec/services/workflows/proposals_workflow_spec.rb +++ b/spec/services/workflows/proposals_workflow_spec.rb @@ -298,14 +298,39 @@ module Workflows subject.start end - it "sends proposal details with comment button" do - expect(adapter).to receive(:send_message!).with( - hash_including( - type: :interactive_buttons, - buttons: [hash_including(id: "comment-#{clicked_proposal.id}")] + context "when comments are enabled in the component" do + before do + proposals_component.update!(settings: { comments_enabled: true }) + end + + it "sends proposal details with comment button" do + expect(adapter).to receive(:send_message!).with( + hash_including( + type: :interactive_buttons, + buttons: [hash_including(id: "comment-#{clicked_proposal.id}")] + ) ) - ) - subject.start + subject.start + end + end + + context "when comments are disabled in the component" do + before do + proposals_component.update!(settings: { comments_enabled: false }) + end + + it "sends proposal details as text message without buttons" do + expect(adapter).to receive(:send_message!).with( + hash_including( + body: anything, + preview_url: true + ) + ) do |args| + # Make sure it's not an interactive_buttons message + expect(args).not_to include(:type) + end + subject.start + end end context "when proposal body contains a YouTube iframe" do @@ -322,6 +347,7 @@ module Workflows before do clicked_proposal.update!(body: body_with_youtube) + proposals_component.update!(settings: { comments_enabled: true }) end it "sends interactive_buttons message with video URL in body text" do @@ -368,6 +394,7 @@ module Workflows before do clicked_proposal.update!(body: body_with_vimeo) + proposals_component.update!(settings: { comments_enabled: true }) end it "sends interactive_buttons message with video URL in body text" do @@ -407,6 +434,7 @@ module Workflows before do clicked_proposal.update!(body: body_without_video) + proposals_component.update!(settings: { comments_enabled: true }) end it "sends interactive_buttons message without video URL" do From e30766b6248bd7981c59efd5d024d7abd45eb2b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Verg=C3=A9s?= Date: Wed, 25 Feb 2026 22:31:57 +0100 Subject: [PATCH 2/4] Update app/services/decidim/chatbot/workflows/proposals_workflow.rb Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- app/services/decidim/chatbot/workflows/proposals_workflow.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/services/decidim/chatbot/workflows/proposals_workflow.rb b/app/services/decidim/chatbot/workflows/proposals_workflow.rb index 06ac17f..9e0bd1c 100644 --- a/app/services/decidim/chatbot/workflows/proposals_workflow.rb +++ b/app/services/decidim/chatbot/workflows/proposals_workflow.rb @@ -147,8 +147,8 @@ def component @component ||= Decidim::Component.find_by(id: config[:component_id]) end - def component_comentable? - @component_comentable ||= component&.settings&.comments_enabled? + def component_commentable? + @component_commentable ||= component&.settings&.comments_enabled? end def proposals From a49ace1230c5964ab2d22338a5d864e7316609c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Verg=C3=A9s?= Date: Wed, 25 Feb 2026 22:37:52 +0100 Subject: [PATCH 3/4] add guard --- .../chatbot/workflows/proposals_workflow.rb | 18 +++++++---- config/locales/en.yml | 31 +++++++++++++------ config/locales/pt-BR.yml | 1 + .../workflows/proposals_workflow_spec.rb | 17 ++++++++++ 4 files changed, 51 insertions(+), 16 deletions(-) diff --git a/app/services/decidim/chatbot/workflows/proposals_workflow.rb b/app/services/decidim/chatbot/workflows/proposals_workflow.rb index 9e0bd1c..72c8bc5 100644 --- a/app/services/decidim/chatbot/workflows/proposals_workflow.rb +++ b/app/services/decidim/chatbot/workflows/proposals_workflow.rb @@ -20,11 +20,17 @@ def process_action_input else mark_as_responding if commentable_id - delegate_workflow( - Decidim::Chatbot::Workflows::CommentsWorkflow, - resource_gid: commentable_gid.to_s, - back_button: { id: "more", title: I18n.t("decidim.chatbot.workflows.proposals.buttons.more") } - ) + if component_commentable? + delegate_workflow( + Decidim::Chatbot::Workflows::CommentsWorkflow, + resource_gid: commentable_gid.to_s, + back_button: { id: "more", title: I18n.t("decidim.chatbot.workflows.proposals.buttons.more") } + ) + else + send_message!( + body: I18n.t("decidim.chatbot.workflows.proposals.comments_disabled") + ) + end else send_proposal_details end @@ -71,7 +77,7 @@ def send_proposal_details # Use video thumbnail as header image if available, otherwise use proposal photo with fallback header_image = video.thumbnail_url.presence || resource_url(proposal.photo, fallback_image: true) - if component_comentable? + if component_commentable? send_message!( type: :interactive_buttons, body_text: body, diff --git a/config/locales/en.yml b/config/locales/en.yml index 8179004..121fdcc 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -45,11 +45,12 @@ en: success: Chatbot settings saved successfully. messages: deactivated: The chatbot is currently deactivated. Please try again later. + generic_error: Sorry, something went wrong while processing your request. + Please try again later. reset_workflows: Thanks for participating! You can start again by sending any message. stale_cleared: Your previous session was cleared due to inactivity. Starting fresh! - generic_error: Sorry, something went wrong while processing your request. Please try again later. providers: whatsapp: description: Enable to receive and respond to messages via WhatsApp Business @@ -61,18 +62,27 @@ en: exit: Exit & go back reset: End conversation unprocessable_input: Sorry, I couldn't process that. Please try again with - a different message or use "Exit & go back" or "End conversation" to start over. + a different message or use "Exit & go back" or "End conversation" to start + over. comments: - comment_received: Here is your comment, if you want to change it just send a new message. If you're happy with it, click "Submit comment". - resource_not_found: Unfortunately, the requested resource could not be found. - Please choose another one or exit and restart. - instructions: Thanks for your interest in commenting "%{title}"! Please write your comment below and send it to me. You will have the chance to review and edit your comment before submitting it. - comment_created: "Your comment has been published successfully! You can view it here:" - comment_creation_failed: "Unfortunately, your comment could not be published. Please try again or contact support." - signature: "\n\nSent via %{provider}" buttons: - submit: Publish comment exit: Cancel & go back + submit: Publish comment + comment_created: 'Your comment has been published successfully! You can + view it here:' + comment_creation_failed: Unfortunately, your comment could not be published. + Please try again or contact support. + comment_received: Here is your comment, if you want to change it just send + a new message. If you're happy with it, click "Submit comment". + instructions: Thanks for your interest in commenting "%{title}"! Please + write your comment below and send it to me. You will have the chance to + review and edit your comment before submitting it. + resource_not_found: Unfortunately, the requested resource could not be found. + Please choose another one or exit and restart. + signature: |2- + + + Sent via %{provider} organization_welcome: title: Organization Welcome proposals: @@ -80,6 +90,7 @@ en: comment: Comment proposal more: View more view_proposal: View proposal + comments_disabled: Commenting is disabled for this proposal. no_more_proposals: There are no more proposals to show. Please choose one of the proposals above. no_proposals: There are no proposals published yet. Please check back later. diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index f981824..b977251 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -73,6 +73,7 @@ pt-BR: comment: Comentar proposta more: Ver mais view_proposal: Ver proposta + comments_disabled: Os comentários estão desativados para esta proposta. no_more_proposals: Não há mais propostas para mostrar. Por favor, escolha uma das propostas acima. no_proposals: Não há propostas publicadas ainda. Por favor, verifique novamente mais tarde. remaining_proposals: Há %{count} mais propostas. Clique em "Ver mais" para vê-las. diff --git a/spec/services/workflows/proposals_workflow_spec.rb b/spec/services/workflows/proposals_workflow_spec.rb index 64773cf..7ee49ee 100644 --- a/spec/services/workflows/proposals_workflow_spec.rb +++ b/spec/services/workflows/proposals_workflow_spec.rb @@ -475,6 +475,7 @@ module Workflows allow(received_message).to receive(:button_id).and_return("comment-#{clicked_proposal.id}") allow(CommentsWorkflow).to receive(:new).and_return(comments_workflow_instance) allow(comments_workflow_instance).to receive(:start) + proposals_component.update!(settings: { comments_enabled: true }) end it "marks as responding" do @@ -494,6 +495,22 @@ module Workflows expect(sender.workflow_stack.last["options"]["resource_gid"]).to eq(clicked_proposal.to_global_id.to_s) expect(sender.workflow_stack.last["options"]["back_button"]).to be_present end + + context "when comments are disabled in the component" do + before do + proposals_component.update!(settings: { comments_enabled: false }) + end + + it "sends a non-interactive message and does not delegate" do + expect(adapter).to receive(:send_message!).with( + hash_including( + body: I18n.t("decidim.chatbot.workflows.proposals.comments_disabled") + ) + ) + expect(comments_workflow_instance).not_to receive(:start) + subject.start + end + end end end end From 291f7da5f06f5f4d405293352651f246cf94f18a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Verg=C3=A9s?= Date: Wed, 25 Feb 2026 22:52:50 +0100 Subject: [PATCH 4/4] word --- config/locales/en.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index 121fdcc..00b6b9a 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -73,7 +73,7 @@ en: comment_creation_failed: Unfortunately, your comment could not be published. Please try again or contact support. comment_received: Here is your comment, if you want to change it just send - a new message. If you're happy with it, click "Submit comment". + a new message. If you're happy with it, click "Publish comment". instructions: Thanks for your interest in commenting "%{title}"! Please write your comment below and send it to me. You will have the chance to review and edit your comment before submitting it.