diff --git a/app/models/project_services/chat_slash_commands_service.rb b/app/models/project_services/chat_slash_commands_service.rb index 7ff80447a1c..f11d257e6c1 100644 --- a/app/models/project_services/chat_slash_commands_service.rb +++ b/app/models/project_services/chat_slash_commands_service.rb @@ -33,10 +33,11 @@ class ChatSlashCommandsService < Service user = find_chat_user(params) unless user url = authorize_chat_name_url(params) - return Gitlab::ChatCommands::Presenter.authorize_chat_name(url) + return presenter.authorize_chat_name(url) end - Gitlab::ChatCommands::Command.new(project, user, params).execute + Gitlab::ChatCommands::Command.new(project, user, + params.merge(presenter_format: presenter_format)).execute end private @@ -48,4 +49,12 @@ class ChatSlashCommandsService < Service def authorize_chat_name_url(params) ChatNames::AuthorizeUserService.new(self, params).execute end + + def presenter + Gitlab::ChatCommands::Presenter.new(presenter_format) + end + + def presenter_format + throw NotImplementedError + end end diff --git a/app/models/project_services/mattermost_slash_commands_service.rb b/app/models/project_services/mattermost_slash_commands_service.rb index 6aac7c2788b..f9d4b29f4ea 100644 --- a/app/models/project_services/mattermost_slash_commands_service.rb +++ b/app/models/project_services/mattermost_slash_commands_service.rb @@ -18,4 +18,8 @@ class MattermostSlashCommandsService < ChatService def to_param 'mattermost_slash_commands' end + + def presenter_format + 'mattermost' + end end diff --git a/app/models/project_services/slack_slash_commands_service.rb b/app/models/project_services/slack_slash_commands_service.rb index 197d8eb7bca..6bf10ff6572 100644 --- a/app/models/project_services/slack_slash_commands_service.rb +++ b/app/models/project_services/slack_slash_commands_service.rb @@ -12,4 +12,8 @@ class SlackSlashCommandsService < ChatSlashCommandsService def to_param 'slack_slash_commands' end + + def presenter_format + 'slack' + end end diff --git a/lib/gitlab/chat_commands/base_command.rb b/lib/gitlab/chat_commands/base_command.rb index 25da8474e95..156bb826f86 100644 --- a/lib/gitlab/chat_commands/base_command.rb +++ b/lib/gitlab/chat_commands/base_command.rb @@ -42,6 +42,10 @@ module Gitlab def find_by_iid(iid) collection.find_by(iid: iid) end + + def presenter + Gitlab::ChatCommands::Presenter.new(params[:presenter_format]) + end end end end diff --git a/lib/gitlab/chat_commands/command.rb b/lib/gitlab/chat_commands/command.rb index b0d3fdbc48a..c5c54cf7cfc 100644 --- a/lib/gitlab/chat_commands/command.rb +++ b/lib/gitlab/chat_commands/command.rb @@ -48,15 +48,15 @@ module Gitlab end def help(messages) - Mattermost::Presenter.help(messages, params[:command]) + presenter.help(messages, params[:command]) end def access_denied - Mattermost::Presenter.access_denied + presenter.access_denied end def present(resource) - Mattermost::Presenter.present(resource) + presenter.present(resource) end end end diff --git a/lib/gitlab/chat_commands/presenter.rb b/lib/gitlab/chat_commands/presenter.rb index 14c78ac39aa..e151513cbd5 100644 --- a/lib/gitlab/chat_commands/presenter.rb +++ b/lib/gitlab/chat_commands/presenter.rb @@ -1,131 +1,143 @@ module Gitlab class ChatCommands class Presenter - class << self - include Gitlab::Routing.url_helpers + include Gitlab::Routing.url_helpers - def authorize_chat_name(url) - message = if url - ":wave: Hi there! Before I do anything for you, please <#{url}|connect your GitLab account>." - else - ":sweat_smile: Couldn't identify you, nor can I autorize you!" - end + attr_reader :format + + def initialize(format) + @format = format + end + + def authorize_chat_name(url) + message = if url + ":wave: Hi there! Before I do anything for you, please #{link(url, 'connect your GitLab account')}." + else + ":sweat_smile: Couldn't identify you, nor can I autorize you!" + end + + ephemeral_response(message) + end + + def help(commands, trigger) + if commands.none? + ephemeral_response("No commands configured") + else + commands.map! { |command| "#{trigger} #{command}" } + message = header_with_list("Available commands", commands) ephemeral_response(message) end + end - def help(commands, trigger) - if commands.none? - ephemeral_response("No commands configured") - else - commands.map! { |command| "#{trigger} #{command}" } - message = header_with_list("Available commands", commands) + def present(subject) + return not_found unless subject - ephemeral_response(message) - end - end - - def present(subject) - return not_found unless subject - - if subject.is_a?(Gitlab::ChatCommands::Result) - show_result(subject) - elsif subject.respond_to?(:count) - if subject.many? - multiple_resources(subject) - elsif subject.none? - not_found - else - single_resource(subject) - end + if subject.is_a?(Gitlab::ChatCommands::Result) + show_result(subject) + elsif subject.respond_to?(:count) + if subject.many? + multiple_resources(subject) + elsif subject.none? + not_found else single_resource(subject) end + else + single_resource(subject) + end + end + + def access_denied + ephemeral_response("Whoops! That action is not allowed. This incident will be #{link('https://xkcd.com/838/', 'reported')}.") + end + + private + + def show_result(result) + case result.type + when :success + in_channel_response(result.message) + else + ephemeral_response(result.message) + end + end + + def not_found + ephemeral_response("404 not found! GitLab couldn't find what you were looking for! :boom:") + end + + def single_resource(resource) + return error(resource) if resource.errors.any? || !resource.persisted? + + message = "#{title(resource)}:" + message << "\n\n#{resource.description}" if resource.try(:description) + + in_channel_response(message) + end + + def multiple_resources(resources) + resources.map! { |resource| title(resource) } + + message = header_with_list("Multiple results were found:", resources) + + ephemeral_response(message) + end + + def error(resource) + message = header_with_list("The action was not successful, because:", resource.errors.messages) + + ephemeral_response(message) + end + + def title(resource) + reference = resource.try(:to_reference) || resource.try(:id) + title = resource.try(:title) || resource.try(:name) + + link(url(resource), "#{reference} #{title}") + end + + def header_with_list(header, items) + message = [header] + + items.each do |item| + message << "- #{item}" end - def access_denied - ephemeral_response("Whoops! That action is not allowed. This incident will be .") - end + message.join("\n") + end - private + def url(resource) + url_for( + [ + resource.project.namespace.becomes(Namespace), + resource.project, + resource + ] + ) + end - def show_result(result) - case result.type - when :success - in_channel_response(result.message) - else - ephemeral_response(result.message) - end - end + def ephemeral_response(message) + { + response_type: :ephemeral, + text: message, + status: 200 + } + end - def not_found - ephemeral_response("404 not found! GitLab couldn't find what you were looking for! :boom:") - end + def in_channel_response(message) + { + response_type: :in_channel, + text: message, + status: 200 + } + end - def single_resource(resource) - return error(resource) if resource.errors.any? || !resource.persisted? - - message = "#{title(resource)}:" - message << "\n\n#{resource.description}" if resource.try(:description) - - in_channel_response(message) - end - - def multiple_resources(resources) - resources.map! { |resource| title(resource) } - - message = header_with_list("Multiple results were found:", resources) - - ephemeral_response(message) - end - - def error(resource) - message = header_with_list("The action was not successful, because:", resource.errors.messages) - - ephemeral_response(message) - end - - def title(resource) - reference = resource.try(:to_reference) || resource.try(:id) - title = resource.try(:title) || resource.try(:name) - - "<#{url(resource)}|#{reference} #{title}>" - end - - def header_with_list(header, items) - message = [header] - - items.each do |item| - message << "- #{item}" - end - - message.join("\n") - end - - def url(resource) - url_for( - [ - resource.project.namespace.becomes(Namespace), - resource.project, - resource - ] - ) - end - - def ephemeral_response(message) - { - response_type: :ephemeral, - text: message, - status: 200 - } - end - - def in_channel_response(message) - { - response_type: :in_channel, - text: message, - status: 200 - } + def link(url, title) + case format + when 'slack' then "<#{url}|#{title}>" + when 'mattermost' then "[#{title}](#{url})" + else then title end end end