FEATURE: Added Power Automate as a new provider (#204)
This commit is contained in:
parent
9e222691c3
commit
6acdb1e918
|
@ -1 +1,2 @@
|
||||||
node_modules
|
node_modules
|
||||||
|
.DS_Store
|
||||||
|
|
|
@ -71,7 +71,6 @@ en:
|
||||||
tags: "If specified, this rule will only apply to topics which have at least one of these tags"
|
tags: "If specified, this rule will only apply to topics which have at least one of these tags"
|
||||||
|
|
||||||
provider:
|
provider:
|
||||||
|
|
||||||
#######################################
|
#######################################
|
||||||
########### SLACK STRINGS #############
|
########### SLACK STRINGS #############
|
||||||
#######################################
|
#######################################
|
||||||
|
@ -229,6 +228,23 @@ en:
|
||||||
help: "The URL provided when you create a new incoming webhook"
|
help: "The URL provided when you create a new incoming webhook"
|
||||||
errors:
|
errors:
|
||||||
invalid_channel: "That channel does not exist on Microsoft Teams"
|
invalid_channel: "That channel does not exist on Microsoft Teams"
|
||||||
|
#####################################################
|
||||||
|
######### MICROSOFT POWER AUTOMATE STRINGS ##########
|
||||||
|
#####################################################
|
||||||
|
powerautomate:
|
||||||
|
title: "Microsoft Power Automate"
|
||||||
|
param:
|
||||||
|
name:
|
||||||
|
title: "Name"
|
||||||
|
help: "A name for the channel (only shown in the Discourse admin interface)"
|
||||||
|
webhook_url:
|
||||||
|
title: "Webhook URL"
|
||||||
|
help: "The URL provided when you create a new incoming webhook"
|
||||||
|
errors:
|
||||||
|
invalid_webhook: "That webhook URL is not valid."
|
||||||
|
########################################
|
||||||
|
######### CISCO WEBEX STRINGS ##########
|
||||||
|
########################################
|
||||||
webex:
|
webex:
|
||||||
title: "Webex Teams"
|
title: "Webex Teams"
|
||||||
param:
|
param:
|
||||||
|
|
|
@ -99,6 +99,12 @@ en:
|
||||||
chat_integration_teams_enabled: "Enable the Microsoft Teams chat integration provider"
|
chat_integration_teams_enabled: "Enable the Microsoft Teams chat integration provider"
|
||||||
chat_integration_teams_excerpt_length: "Microsoft Team post excerpt length"
|
chat_integration_teams_excerpt_length: "Microsoft Team post excerpt length"
|
||||||
|
|
||||||
|
####################################################
|
||||||
|
######## MICROSOFT POWER AUTOMATE SETTINGS #########
|
||||||
|
####################################################
|
||||||
|
chat_integration_powerautomate_enabled: "Enable the Microsoft Power Automate integration provider"
|
||||||
|
chat_integration_powerautomate_excerpt_length: "Microsoft Power Automate post excerpt length"
|
||||||
|
|
||||||
###########################################
|
###########################################
|
||||||
######## WEBEX TEAMS SETTINGS #########
|
######## WEBEX TEAMS SETTINGS #########
|
||||||
###########################################
|
###########################################
|
||||||
|
|
|
@ -148,9 +148,16 @@ chat_integration:
|
||||||
default: false
|
default: false
|
||||||
chat_integration_teams_excerpt_length:
|
chat_integration_teams_excerpt_length:
|
||||||
default: 400
|
default: 400
|
||||||
###########################################
|
####################################################
|
||||||
######## WEBEX TEAMS SETTINGS #########
|
######## MICROSOFT POWER AUTOMATE SETTINGS #########
|
||||||
###########################################
|
####################################################
|
||||||
|
chat_integration_powerautomate_enabled:
|
||||||
|
default: false
|
||||||
|
chat_integration_powerautomate_excerpt_length:
|
||||||
|
default: 400
|
||||||
|
#################################
|
||||||
|
######## WEBEX SETTINGS #########
|
||||||
|
#################################
|
||||||
chat_integration_webex_enabled:
|
chat_integration_webex_enabled:
|
||||||
default: false
|
default: false
|
||||||
chat_integration_webex_excerpt_length:
|
chat_integration_webex_excerpt_length:
|
||||||
|
|
|
@ -99,6 +99,7 @@ require_relative "provider/gitter/gitter_provider"
|
||||||
require_relative "provider/flowdock/flowdock_provider"
|
require_relative "provider/flowdock/flowdock_provider"
|
||||||
require_relative "provider/groupme/groupme_provider"
|
require_relative "provider/groupme/groupme_provider"
|
||||||
require_relative "provider/teams/teams_provider"
|
require_relative "provider/teams/teams_provider"
|
||||||
|
require_relative "provider/powerautomate/powerautomate_provider"
|
||||||
require_relative "provider/webex/webex_provider"
|
require_relative "provider/webex/webex_provider"
|
||||||
require_relative "provider/google/google_provider"
|
require_relative "provider/google/google_provider"
|
||||||
require_relative "provider/guilded/guilded_provider"
|
require_relative "provider/guilded/guilded_provider"
|
||||||
|
|
|
@ -0,0 +1,133 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module DiscourseChatIntegration::Provider::PowerAutomateProvider
|
||||||
|
PROVIDER_NAME = "powerautomate"
|
||||||
|
PROVIDER_ENABLED_SETTING = :chat_integration_powerautomate_enabled
|
||||||
|
CHANNEL_PARAMETERS = [
|
||||||
|
{ key: "name", regex: '^\S+$', unique: true },
|
||||||
|
{ key: "webhook_url", regex: '^https:\/\/\S+$', unique: true, hidden: true },
|
||||||
|
]
|
||||||
|
|
||||||
|
def self.trigger_notification(post, channel, rule)
|
||||||
|
message = get_message(post)
|
||||||
|
uri = URI(channel.data["webhook_url"])
|
||||||
|
|
||||||
|
http = FinalDestination::HTTP.new(uri.host, uri.port)
|
||||||
|
http.use_ssl = (uri.scheme == "https")
|
||||||
|
|
||||||
|
req = Net::HTTP::Post.new(uri, "Content-Type" => "application/json")
|
||||||
|
req.body = message.to_json
|
||||||
|
response = http.request(req)
|
||||||
|
|
||||||
|
unless response.kind_of? Net::HTTPSuccess
|
||||||
|
if response.body.include?("Invalid webhook URL")
|
||||||
|
error_key = "chat_integration.provider.powerautomate.errors.invalid_webhook"
|
||||||
|
else
|
||||||
|
error_key = nil
|
||||||
|
end
|
||||||
|
raise ::DiscourseChatIntegration::ProviderError.new info: {
|
||||||
|
error_key: error_key,
|
||||||
|
request: req.body,
|
||||||
|
response_code: response.code,
|
||||||
|
response_body: response.body,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.get_message(post)
|
||||||
|
display_name = "@#{post.user.username}"
|
||||||
|
full_name =
|
||||||
|
if SiteSetting.enable_names && post.user.name.present?
|
||||||
|
post.user.name
|
||||||
|
else
|
||||||
|
""
|
||||||
|
end
|
||||||
|
|
||||||
|
topic = post.topic
|
||||||
|
|
||||||
|
category = ""
|
||||||
|
if topic.category&.uncategorized?
|
||||||
|
category = "[#{I18n.t("uncategorized_category_name")}]"
|
||||||
|
elsif topic.category
|
||||||
|
category =
|
||||||
|
(
|
||||||
|
if (topic.category.parent_category)
|
||||||
|
"[#{topic.category.parent_category.name}/#{topic.category.name}]"
|
||||||
|
else
|
||||||
|
"[#{topic.category.name}]"
|
||||||
|
end
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
message = {
|
||||||
|
type: "message",
|
||||||
|
attachments: [
|
||||||
|
{
|
||||||
|
contentType: "application/vnd.microsoft.card.adaptive",
|
||||||
|
contentUrl: nil,
|
||||||
|
content: {
|
||||||
|
type: "AdaptiveCard",
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: "TextBlock",
|
||||||
|
size: "Large",
|
||||||
|
weight: "Bolder",
|
||||||
|
text:
|
||||||
|
"[#{topic.title} #{category} #{topic.tags.present? ? topic.tags.map(&:name).join(", ") : ""}](#{post.full_url})",
|
||||||
|
wrap: true,
|
||||||
|
spacing: "None",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "ColumnSet",
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
type: "Column",
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
type: "Image",
|
||||||
|
style: "Person",
|
||||||
|
url: post.user.small_avatar_url,
|
||||||
|
altText: full_name,
|
||||||
|
size: " Small",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
width: "auto",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "Column",
|
||||||
|
items: [
|
||||||
|
{ type: "TextBlock", weight: "Bolder", text: full_name, wrap: true },
|
||||||
|
{
|
||||||
|
type: "TextBlock",
|
||||||
|
spacing: "None",
|
||||||
|
text: display_name,
|
||||||
|
isSubtle: true,
|
||||||
|
wrap: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
width: "stretch",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "TextBlock",
|
||||||
|
text:
|
||||||
|
post.excerpt(
|
||||||
|
SiteSetting.chat_integration_powerautomate_excerpt_length,
|
||||||
|
text_entities: true,
|
||||||
|
strip_links: true,
|
||||||
|
remap_emoji: true,
|
||||||
|
),
|
||||||
|
wrap: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
|
||||||
|
version: "1.2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
message
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,37 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require "rails_helper"
|
||||||
|
|
||||||
|
RSpec.describe DiscourseChatIntegration::Provider::PowerAutomateProvider do
|
||||||
|
let(:post) { Fabricate(:post) }
|
||||||
|
|
||||||
|
describe ".trigger_notifications" do
|
||||||
|
before { SiteSetting.chat_integration_powerautomate_enabled = true }
|
||||||
|
|
||||||
|
let(:chan1) do
|
||||||
|
DiscourseChatIntegration::Channel.create!(
|
||||||
|
provider: "powerautomate",
|
||||||
|
data: {
|
||||||
|
name: "discourse",
|
||||||
|
webhook_url:
|
||||||
|
"https://prod-189.westus.logic.azure.com:443/workflows/c94b462906e64fe8a7299043706be96e/triggers/manual/paths/invoke?api-version=2016-06-01&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=-cmkg1oG-88dP3Yqdh62yTG1LUtJFcB91rQisorfw_w",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "sends a webhook request" do
|
||||||
|
stub1 = stub_request(:post, chan1.data["webhook_url"]).to_return(body: "1")
|
||||||
|
described_class.trigger_notification(post, chan1, nil)
|
||||||
|
expect(stub1).to have_been_requested.once
|
||||||
|
end
|
||||||
|
|
||||||
|
it "handles errors correctly" do
|
||||||
|
stub1 = stub_request(:post, chan1.data["webhook_url"]).to_return(status: 400, body: "{}")
|
||||||
|
expect(stub1).to have_been_requested.times(0)
|
||||||
|
expect { described_class.trigger_notification(post, chan1, nil) }.to raise_exception(
|
||||||
|
::DiscourseChatIntegration::ProviderError,
|
||||||
|
)
|
||||||
|
expect(stub1).to have_been_requested.once
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue