Add transcript posting support to slack
This commit is contained in:
parent
2d7f25d7e6
commit
8ca4797797
|
@ -73,7 +73,13 @@ en:
|
||||||
|
|
||||||
*List rules:* `/discourse status`
|
*List rules:* `/discourse status`
|
||||||
|
|
||||||
|
*Post transcript:* `/discourse post [n]`
|
||||||
|
Create a draft topic on discourse containing the last `n` posts in this channel
|
||||||
|
|
||||||
*Help:* `/discourse help`
|
*Help:* `/discourse help`
|
||||||
|
transcript_error: "Something went wrong when building the transcript, sorry!"
|
||||||
|
post_to_discourse: "Click here to post on Discourse"
|
||||||
|
api_required: "Sorry, this integration isn't setup to support posting transcripts."
|
||||||
|
|
||||||
#######################################
|
#######################################
|
||||||
########## TELEGRAM STRINGS ###########
|
########## TELEGRAM STRINGS ###########
|
||||||
|
|
|
@ -38,10 +38,90 @@ module DiscourseChat::Provider::SlackProvider
|
||||||
# Create channel if doesn't exist
|
# Create channel if doesn't exist
|
||||||
channel ||= DiscourseChat::Channel.create!(provider:provider, data:{identifier: channel_id})
|
channel ||= DiscourseChat::Channel.create!(provider:provider, data:{identifier: channel_id})
|
||||||
|
|
||||||
|
if tokens[0] == 'post'
|
||||||
|
return process_post_request(channel, tokens, params[:channel_id])
|
||||||
|
end
|
||||||
|
|
||||||
return ::DiscourseChat::Helper.process_command(channel, tokens)
|
return ::DiscourseChat::Helper.process_command(channel, tokens)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def process_post_request(channel, tokens, slack_channel_id)
|
||||||
|
if SiteSetting.chat_integration_slack_access_token.empty?
|
||||||
|
return I18n.t("chat_integration.provider.slack.api_required")
|
||||||
|
end
|
||||||
|
|
||||||
|
http = Net::HTTP.new("slack.com", 443)
|
||||||
|
http.use_ssl = true
|
||||||
|
|
||||||
|
messages_to_load = 10
|
||||||
|
|
||||||
|
if tokens.size > 1
|
||||||
|
begin
|
||||||
|
messages_to_load = Integer(tokens[1], 10)
|
||||||
|
rescue ArgumentError
|
||||||
|
return I18n.t("chat_integration.provider.slack.parse_error")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
error_text = I18n.t("chat_integration.provider.slack.transcript_error")
|
||||||
|
|
||||||
|
# Load the user data (we need this to change user IDs into usernames)
|
||||||
|
req = Net::HTTP::Post.new(URI('https://slack.com/api/users.list'))
|
||||||
|
req.set_form_data({token: SiteSetting.chat_integration_slack_access_token})
|
||||||
|
response = http.request(req)
|
||||||
|
return error_text unless response.kind_of? Net::HTTPSuccess
|
||||||
|
json = JSON.parse(response.body)
|
||||||
|
return error_text unless json['ok']
|
||||||
|
users = json["members"]
|
||||||
|
|
||||||
|
# Now load the chat message history
|
||||||
|
req = Net::HTTP::Post.new(URI('https://slack.com/api/channels.history'))
|
||||||
|
|
||||||
|
data = {
|
||||||
|
token: SiteSetting.chat_integration_slack_access_token,
|
||||||
|
channel: slack_channel_id,
|
||||||
|
count: messages_to_load
|
||||||
|
}
|
||||||
|
|
||||||
|
req.set_form_data(data)
|
||||||
|
response = http.request(req)
|
||||||
|
return error_text unless response.kind_of? Net::HTTPSuccess
|
||||||
|
json = JSON.parse(response.body)
|
||||||
|
return error_text unless json['ok']
|
||||||
|
post_content = ""
|
||||||
|
|
||||||
|
json["messages"].reverse.each do |message|
|
||||||
|
next unless message["type"] == "message"
|
||||||
|
|
||||||
|
username = ""
|
||||||
|
if message["user"]
|
||||||
|
username = users.find{|u| u["id"] == message["user"]}["name"]
|
||||||
|
elsif message.key?("username")
|
||||||
|
username = message["username"]
|
||||||
|
end
|
||||||
|
|
||||||
|
post_content << "[quote='@#{username}']\n"
|
||||||
|
post_content << message["text"]
|
||||||
|
|
||||||
|
if message.key?("attachments")
|
||||||
|
message["attachments"].each do |attachment|
|
||||||
|
next unless attachment.key?("fallback")
|
||||||
|
post_content << "\n[quote]\n#{attachment["fallback"]}\n[/quote]"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
post_content << "\n[/quote]\n\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
secret = DiscourseChat::Helper.save_transcript(post_content)
|
||||||
|
|
||||||
|
link = "#{Discourse.base_url}/chat-transcript/#{secret}"
|
||||||
|
|
||||||
|
return "<#{link}|#{I18n.t("chat_integration.provider.slack.post_to_discourse")}>"
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
def slack_token_valid?
|
def slack_token_valid?
|
||||||
params.require(:token)
|
params.require(:token)
|
||||||
|
|
||||||
|
|
|
@ -304,6 +304,8 @@ RSpec.describe DiscourseChat::Manager do
|
||||||
describe '.save_transcript' do
|
describe '.save_transcript' do
|
||||||
|
|
||||||
it 'saves a transcript to redis' do
|
it 'saves a transcript to redis' do
|
||||||
|
freeze_time
|
||||||
|
|
||||||
key = DiscourseChat::Helper.save_transcript("Some content here")
|
key = DiscourseChat::Helper.save_transcript("Some content here")
|
||||||
|
|
||||||
expect($redis.get("chat_integration:transcript:#{key}")).to eq("Some content here")
|
expect($redis.get("chat_integration:transcript:#{key}")).to eq("Some content here")
|
||||||
|
|
|
@ -109,6 +109,56 @@ describe 'Slack Command Controller', type: :request do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'post transcript' do
|
||||||
|
before do
|
||||||
|
SiteSetting.chat_integration_slack_access_token = 'abcde'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'generates a transcript properly' do
|
||||||
|
stub1 = stub_request(:post, "https://slack.com/api/users.list").to_return(body: '{"ok":true,"members":[{"id":"U5Z773QLS","name":"david"}]}')
|
||||||
|
stub2 = stub_request(:post, "https://slack.com/api/channels.history").to_return(body: '{"ok":true,"messages":[{"type":"message","user":"U5Z773QLS","text":"And this is a slack message with an attachment: <https:\/\/meta.discourse.org>","attachments":[{"title":"Discourse Meta","title_link":"https:\/\/meta.discourse.org","text":"Discussion about the next-generation open source Discourse forum software","fallback":"Discourse Meta","thumb_url":"https:\/\/discourse-meta.s3-us-west-1.amazonaws.com\/original\/3X\/c\/b\/cb4bec8901221d4a646e45e1fa03db3a65e17f59.png","from_url":"https:\/\/meta.discourse.org","thumb_width":350,"thumb_height":349,"service_icon":"https:\/\/discourse-meta.s3-us-west-1.amazonaws.com\/original\/3X\/c\/b\/cb4bec8901221d4a646e45e1fa03db3a65e17f59.png","service_name":"meta.discourse.org","id":1}],"ts":"1500910064.045243"},{"type":"message","user":"U5Z773QLS","text":"Hello world, this is a slack message","ts":"1500910051.036792"}],"has_more":true}')
|
||||||
|
|
||||||
|
post "/chat-integration/slack/command.json",
|
||||||
|
text: "post 2",
|
||||||
|
channel_name: 'general',
|
||||||
|
channel_id:'C6029G78F',
|
||||||
|
token: token
|
||||||
|
|
||||||
|
json = JSON.parse(response.body)
|
||||||
|
|
||||||
|
expect(json["text"]).to include(I18n.t("chat_integration.provider.slack.post_to_discourse"))
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'deals with failed API calls correctly' do
|
||||||
|
stub1 = stub_request(:post, "https://slack.com/api/users.list").to_return(status: 403)
|
||||||
|
|
||||||
|
post "/chat-integration/slack/command.json",
|
||||||
|
text: "post 2",
|
||||||
|
channel_name: 'general',
|
||||||
|
channel_id:'C6029G78F',
|
||||||
|
token: token
|
||||||
|
|
||||||
|
json = JSON.parse(response.body)
|
||||||
|
|
||||||
|
expect(json["text"]).to include(I18n.t("chat_integration.provider.slack.transcript_error"))
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'errors correctly if there is no api key' do
|
||||||
|
SiteSetting.chat_integration_slack_access_token = ''
|
||||||
|
|
||||||
|
post "/chat-integration/slack/command.json",
|
||||||
|
text: "post 2",
|
||||||
|
channel_name: 'general',
|
||||||
|
channel_id:'C6029G78F',
|
||||||
|
token: token
|
||||||
|
|
||||||
|
json = JSON.parse(response.body)
|
||||||
|
|
||||||
|
expect(json["text"]).to include(I18n.t("chat_integration.provider.slack.api_required"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue