diff --git a/app/models/slack_incident_modal.rb b/app/models/slack_incident_modal.rb index 026d84b..0713258 100644 --- a/app/models/slack_incident_modal.rb +++ b/app/models/slack_incident_modal.rb @@ -1,7 +1,8 @@ class SlackIncidentModal - attr_reader :title, :description, :service, :priority, :comms_lead, :tech_lead, :support_lead + attr_reader :title, :description, :service, :priority, :comms_lead, :tech_lead, :support_lead, :slack_response def initialize(slack_response) + @slack_response = slack_response payload_from_modal = slack_response[:payload][:view][:state][:values] @title = payload_from_modal[:incident_title_block][:incident_title][:value] @@ -16,4 +17,8 @@ def initialize(slack_response) def leads [@comms_lead, @tech_lead, @support_lead] end + + def declarer + slack_response[:payload][:user][:id] + end end diff --git a/app/models/slack_methods.rb b/app/models/slack_methods.rb index 03fd7cb..364b17e 100644 --- a/app/models/slack_methods.rb +++ b/app/models/slack_methods.rb @@ -40,15 +40,21 @@ def self.create_channel!(channel_name) ) end - def self.invite_users!(channel_id, leads) + def self.invite_users!(channel_id, leads, declarer = nil) + invitee = leads.compact.blank? ? declarer : leads.join(',') + slack_client.conversations_invite( channel: channel_id, - users: leads.join(','), + users: invitee, ) end def self.summary_for(incident) - "Description: #{incident.description.capitalize}\n Priority: #{incident.priority}\n Comms lead: <@#{incident.comms_lead}>\n Tech lead: <@#{incident.tech_lead}>\n Support lead: <@#{incident.support_lead}>" + summary = "Description: #{incident.description.capitalize}\n Priority: #{incident.priority}\n" + summary << "Comms lead: <@#{incident.comms_lead}>\n" unless incident.comms_lead.nil? + summary << "Tech lead: <@#{incident.tech_lead}>\n" unless incident.tech_lead.nil? + summary << "Support lead: <@#{incident.support_lead}>" unless incident.support_lead.nil? + summary end def self.set_channel_details!(channel_id, summary) @@ -70,11 +76,15 @@ def self.notify_channel_of_update!(channel_id) text: 'Incident has been updated') end - def self.introduce_incident!(channel_id, tech_lead) + def self.introduce_incident!(channel_id, tech_lead, declarer) message = slack_client.chat_postMessage(channel: channel_id, text: "Welcome to the incident channel. Please review the following docs:\n> <#{ENV['INCIDENT_PLAYBOOK']}|Incident playbook> \n><#{ENV['INCIDENT_CATEGORIES']}|Incident categorisation>") slack_client.pins_add(channel: channel_id, timestamp: message[:ts]) - slack_client.chat_postMessage(channel: channel_id, text: "<@#{tech_lead}> please make a copy of the <#{ENV['INCIDENT_TEMPLATE']}|incident template>.") + if tech_lead.nil? + slack_client.chat_postMessage(channel: channel_id, text: "<@#{declarer}> please make a copy of the <#{ENV['INCIDENT_TEMPLATE']}|incident template> and invite the leads.") + else + slack_client.chat_postMessage(channel: channel_id, text: "<@#{tech_lead}> please make a copy of the <#{ENV['INCIDENT_TEMPLATE']}|incident template>.") + end end def self.start_meet!(channel_id, meet_name) diff --git a/bot/actions/slack_incident_actions.rb b/bot/actions/slack_incident_actions.rb index b1b1fa3..bb5231b 100644 --- a/bot/actions/slack_incident_actions.rb +++ b/bot/actions/slack_incident_actions.rb @@ -9,9 +9,9 @@ def open_incident(slack_action, channel_calling_incident) threads = [] - threads << Thread.new { SlackMethods.invite_users!(channel_id, incident.leads) } + threads << Thread.new { SlackMethods.invite_users!(channel_id, incident.leads, incident.declarer) } threads << Thread.new { SlackMethods.set_channel_details!(channel_id, SlackMethods.summary_for(incident)) } - threads << Thread.new { SlackMethods.introduce_incident!(channel_id, incident.tech_lead) } + threads << Thread.new { SlackMethods.introduce_incident!(channel_id, incident.tech_lead, incident.declarer) } threads << Thread.new { SlackMethods.notify_channel!(channel_calling_incident, channel_id, incident.title, incident.priority) } threads << Thread.new { SlackMethods.start_meet!(channel_id, incident.title.parameterize) } diff --git a/lib/view_payloads/incident.json b/lib/view_payloads/incident.json index 7e69490..3a8e7f7 100644 --- a/lib/view_payloads/incident.json +++ b/lib/view_payloads/incident.json @@ -182,7 +182,8 @@ { "type": "input", "block_id": "incident_comms_lead_block", - "label": { + "optional": true, + "label": { "type": "plain_text", "text": "Who is the comms lead?", "emoji": true @@ -200,6 +201,7 @@ { "type": "input", "block_id": "incident_tech_lead_block", + "optional": true, "label": { "type": "plain_text", "text": "Who is the technical lead?", @@ -218,6 +220,7 @@ { "type": "input", "block_id": "incident_support_lead_block", + "optional": true, "label": { "type": "plain_text", "text": "Who is the support lead?", diff --git a/spec/models/slack_methods_spec.rb b/spec/models/slack_methods_spec.rb new file mode 100644 index 0000000..2999494 --- /dev/null +++ b/spec/models/slack_methods_spec.rb @@ -0,0 +1,43 @@ +require 'rails_helper' + +describe SlackMethods do + describe '.summary_for' do + let(:incident) { instance_double('SlackIncidentModal') } + + before do + allow(incident).to receive(:description).and_return('test description') + allow(incident).to receive(:priority).and_return('test priority') + end + + context 'when all leads are provided' do + it 'includes the full summary' do + + allow(incident).to receive(:comms_lead).and_return('test_comms') + allow(incident).to receive(:tech_lead).and_return('test_tech') + allow(incident).to receive(:support_lead).and_return('test_support') + + expect(described_class.summary_for(incident)).to eq "Description: Test description\n Priority: test priority\nComms lead: <@test_comms>\nTech lead: <@test_tech>\nSupport lead: <@test_support>" + end + end + + context 'when one lead is provided' do + it 'includes description, priority and the provided lead' do + allow(incident).to receive(:comms_lead).and_return(nil) + allow(incident).to receive(:tech_lead).and_return('test_tech') + allow(incident).to receive(:support_lead).and_return(nil) + + expect(described_class.summary_for(incident)).to eq "Description: Test description\n Priority: test priority\nTech lead: <@test_tech>\n" + end + end + + context 'when no leads are provied' do + it 'only includes the description and priority' do + allow(incident).to receive(:comms_lead).and_return(nil) + allow(incident).to receive(:tech_lead).and_return(nil) + allow(incident).to receive(:support_lead).and_return(nil) + + expect(described_class.summary_for(incident)).to eq "Description: Test description\n Priority: test priority\n" + end + end + end +end diff --git a/spec/requests/slack_incident_actions_spec.rb b/spec/requests/slack_incident_actions_spec.rb index c5bc982..1fb365e 100644 --- a/spec/requests/slack_incident_actions_spec.rb +++ b/spec/requests/slack_incident_actions_spec.rb @@ -4,7 +4,9 @@ let(:client) { Slack::Web::Client.new(token: ENV['SLACK_TOKEN']) } let(:incident_payload) do { - 'payload' => { 'view' => + 'payload' => + { 'user' => { 'id' => 'U01RVKPGZDL' }, + 'view' => { 'state' => { 'values' => { 'incident_title_block' => { 'incident_title' => { 'type' => 'plain_text_input', 'value' => 'hello' } },