Skip to content

Commit

Permalink
Merge pull request #247 from yoyogix/upgrading-slack-dialog-to-modal
Browse files Browse the repository at this point in the history
Slack Dialogs を Modals に移行します
  • Loading branch information
yoyogix authored Aug 28, 2024
2 parents 9988528 + 036059e commit ee7de0c
Show file tree
Hide file tree
Showing 15 changed files with 568 additions and 494 deletions.
2 changes: 1 addition & 1 deletion app/controllers/slack_interactive_message.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
module SlackInteractiveMessage
def run(request)
# Slack のレスポンス3秒以内ルールのため非同期処理
# https://api.slack.com/dialogs#submit
# https://api.slack.com/reference/interaction-payloads/views#view_submission
ReceptionWorker.perform_async JSON.parse(request["payload"])

""
Expand Down
4 changes: 2 additions & 2 deletions app/controllers/slack_slash_command.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# frozen_string_literal: true

require_relative "../models/slack_dialog"
require_relative "../models/slack_modal"

# @see https://api.slack.com/interactivity/slash-commands
module SlackSlashCommand
def run(request)
SlackDialog.open(request["trigger_id"])
SlackModal.open(request["trigger_id"])

""
end
Expand Down
13 changes: 0 additions & 13 deletions app/models/chat_message_sender.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,10 @@ def initialize
@slack_api_client = Slack::Web::Client.new(token: ENV.fetch("SLACK_TOKEN"))
end

# 全ユーザーに見える形で投稿
# @param post_body [Hash]
# @see https://api.slack.com/methods/chat.postMessage
# @see https://github.com/slack-ruby/slack-ruby-client/blob/master/lib/slack/web/api/endpoints/chat.rb
def post_public_message(post_body)
@slack_api_client.chat_postMessage(post_body)
end

def post_direct_message(post_body)
@slack_api_client.chat_postMessage(post_body)
end

# 特定のユーザーだけに見える形で投稿
# @param post_body [Hash]
# @see https://api.slack.com/methods/chat.postEphemeral
# @see https://github.com/slack-ruby/slack-ruby-client/blob/master/lib/slack/web/api/endpoints/chat.rb
def post_private_message(post_body)
@slack_api_client.chat_postEphemeral(post_body)
end
end
110 changes: 0 additions & 110 deletions app/models/slack_dialog.rb

This file was deleted.

36 changes: 19 additions & 17 deletions app/models/slack_message.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,18 @@ class SlackMessage
# TODO: fix Ruby 3.1+ https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Security/YAMLLoadQ
MESSAGES = open("./config/messages.yml", "r") { |f| YAML.unsafe_load(f) }

# @param dialog_submission [SlackDialogSubmission]
# @param dialog_submission [Email]
def initialize(dialog_submission: nil)
@dialog_submission = dialog_submission
# @param modal_submission [SlackModalSubmission]
def initialize(modal_submission: nil)
@modal_submission = modal_submission
end

# Factory Method
# @param dialog_submission [SlackDialogSubmission]
def self.post_received_message(dialog_submission)
post_body = new(dialog_submission:)
# @param modal_submission [SlackModalSubmission]
def self.post_received_message(modal_submission)
post_body = new(modal_submission:)
.send(:received_message_post_body)

ChatMessageSender.new.post_private_message(post_body)
ChatMessageSender.new.post_public_message(post_body)
end

private
Expand All @@ -28,21 +27,24 @@ def self.post_received_message(dialog_submission)
# @see https://github.com/slack-ruby/slack-ruby-client/blob/master/lib/slack/web/api/endpoints/chat.rb
# @private
def received_message_post_body
{ icon_emoji: MESSAGES["intarctive"]["icon"],
channel: @dialog_submission.slack_channel_id,
user: @dialog_submission.slack_user_id,
{ icon_emoji: MESSAGES["interactive"]["icon"],
channel: @modal_submission.slack_user_id,
text:,
attachments: [attachment(fields: received_message_attachment_fields)] }
end

def text
if send_to_direct_message?
MESSAGES["intarctive"]["dm_text_notification"]
MESSAGES["interactive"]["dm_text_notification"]
else
MESSAGES["intarctive"]["text_notification"]
MESSAGES["interactive"]["text_notification"]
end
end

def send_to_channel_message?
%w[CHANNEL BOTH].include?(ENV.fetch("SEND_MODE"))
end

# @private
# @return [Boolean]
def send_to_direct_message?
Expand All @@ -54,12 +56,12 @@ def send_to_direct_message?
def received_message_attachment_fields
[
attachment_field(
title: MESSAGES["intarctive"]["recept_name"],
value: "#{@dialog_submission.company_name} #{@dialog_submission.visitor_name} 様"
title: MESSAGES["interactive"]["recept_name"],
value: "#{@modal_submission.company_name} #{@modal_submission.visitor_name} 様"
),
attachment_field(
title: MESSAGES["intarctive"]["recept_datetime"],
value: "#{@dialog_submission.recept_date} #{@dialog_submission.recept_time}"
title: MESSAGES["interactive"]["recept_datetime"],
value: "#{@modal_submission.recept_date} #{@modal_submission.recept_time}"
)
]
end
Expand Down
142 changes: 142 additions & 0 deletions app/models/slack_modal.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
# frozen_string_literal: true

require "date"
require "yaml"

# @see https://api.slack.com/surfaces/modals
class SlackModal # rubocop:disable Metrics/ClassLength
SELECT_DATE_RANGE_NUM = 90
SELECT_TIME_HOUR_START = 8
SELECT_TIME_HOUR_END = 21

# TODO: fix Ruby 3.1+ https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Security/YAMLLoad
MESSAGES = open("./config/messages.yml", "r") { |f| YAML.unsafe_load(f) }

# Factory Method
# @param trigger_id [String]
def self.open(trigger_id)
post_body = new.send(:post_body)
client = Slack::Web::Client.new(token: ENV.fetch("SLACK_TOKEN"))
client.views_open(trigger_id:, view: post_body)
end

private

# @return [Hash]
# @private
def post_body
{
type: "modal",
callback_id: "callback_id",
title: {
type: "plain_text",
text: MESSAGES["dialog"]["title"]
},
submit: {
type: "plain_text",
text: "送信"
},
close: {
type: "plain_text",
text: "キャンセル"
},
blocks: [
select_element(
block_id: "recept_date",
label: MESSAGES["dialog"]["recept_date"],
options: date_select_options
),
select_element(
block_id: "recept_time",
label: MESSAGES["dialog"]["recept_time"],
options: time_select_options
),
plain_text_element(
block_id: "recept_company",
label: MESSAGES["dialog"]["recept_company"],
placeholder: MESSAGES["dialog"]["recept_company_placeholder"]
),
plain_text_element(
block_id: "recept_name",
label: MESSAGES["dialog"]["recept_name"],
placeholder: MESSAGES["dialog"]["recept_name_placeholder"]
)
]
}
end

# @param block_id [String]
# @param label [String]
# @param placeholder [String]
# @param action_id [String]
# @return [Hash]
# @see https://api.slack.com/reference/block-kit/block-elements#input
# @private
def plain_text_element(block_id:, label:, placeholder:, action_id: nil)
{
type: "input",
block_id:,
element: {
action_id: action_id || block_id,
type: "plain_text_input",
placeholder: {
type: "plain_text",
text: placeholder
}
},
label: {
type: "plain_text",
text: label
}
}
end

# @param block_id [String]
# @param label [String]
# @param options [Array]
# @param action_id [String]
# @return [Hash]
# @see https://api.slack.com/reference/block-kit/block-elements#select
# @private
def select_element(block_id:, label:, options:, action_id: nil)
{
type: "input",
block_id:,
element: {
type: "static_select",
action_id: action_id || block_id,
options:
},
label: {
type: "plain_text",
text: label
}
}
end

# @return [Array]
# @private
def date_select_options
dates = (Date.today...(Date.today + SELECT_DATE_RANGE_NUM)).to_a
dates.map do |date|
date_text = date.strftime("%Y/%m/%d")
wday = %w[ ][date.wday]
{ text: {
type: "plain_text",
text: "#{date_text} #{wday}"
},
value: date_text }
end
end

# @return [Array]
# @private
def time_select_options
hours = (SELECT_TIME_HOUR_START..SELECT_TIME_HOUR_END).to_a
hours.map do |hour|
padded_hours = format("%.2d", hour)
[{ text: { type: "plain_text", text: "#{padded_hours}:00" }, value: "#{padded_hours}:00" },
{ text: { type: "plain_text", text: "#{padded_hours}:30" }, value: "#{padded_hours}:30" }]
end.flatten
end
end
Loading

0 comments on commit ee7de0c

Please sign in to comment.