Feature: add chat integration reference post (#216)
* FEATURE: Add chat integration reference post This class works similar to a post but it is not a post. * DEV: change how `excerpt` method works * feature: Add `send_chat_integration_message` scriptable add `send_chat_integration_message` scriptable that uses the rules to send a message to the chat provider add locale strings for the new scriptable update `ChatIntegrationReferencePost` `excerpt` method add tests for `ChatIntegrationReferencePost` * DEV: Add `get_channel_by_name` to every provider This makes using `trigger_notification` easier with every provider as well. * DEV: Add `get_channel_name` to all providers This method gets the name of the channel based on how the provider identifies it. Updates channel_name in locales yaml Adds migrate_tag_added_filter_to_all_providers.rb to move all existing rules to use Automation * DEV: Add removal of old migration data Update small action locales with strings from core * DEV: solve review comments * DEV: update test locale strings * DEV: remove empty line to trigger lint * DEV: lint applied * DEV: Add tests for automation integration * DEV: add rails logger for when automatio error occurs * DEV: move migration to be SQL only Update provider helper to use hashes instead of dot notation * DEV: update migration with correct table names * DEV: Update migrate_tag_added_filter_to_all_providers to use smaller SQL queries Commented out migrate_tag_added_from_filter_to_automation.rb * DEV: update comments in migration file * DEV: update indentation in client.en.yml * DEV: update with review comments * Update spec/lib/discourse_chat_integration/chat_integration_reference_post_spec.rb Co-authored-by: Jarek Radosz <jradosz@gmail.com> * Update spec/lib/discourse_chat_integration/chat_integration_reference_post_spec.rb Co-authored-by: Jarek Radosz <jradosz@gmail.com> * Update spec/lib/discourse_chat_integration/chat_integration_reference_post_spec.rb Co-authored-by: Jarek Radosz <jradosz@gmail.com> * Update spec/integration/automation_spec.rb Co-authored-by: Jarek Radosz <jradosz@gmail.com> * Update lib/discourse_chat_integration/chat_integration_reference_post.rb Co-authored-by: Jarek Radosz <jradosz@gmail.com> * DEV: update specs with review comments * DEV: update typos in tests * DEV: inlined functions for getting channel name for provider in migration --------- Co-authored-by: Jarek Radosz <jradosz@gmail.com>
This commit is contained in:
parent
b36ddedb1a
commit
3f8b67d1c1
|
@ -281,3 +281,12 @@ en:
|
|||
label: URL
|
||||
channel:
|
||||
label: Channel
|
||||
|
||||
send_chat_integration_message:
|
||||
title: Send Chat-Integration message
|
||||
fields:
|
||||
channel_name:
|
||||
label: Channel name
|
||||
description: "You can find the channel name in the Chat Integration settings"
|
||||
provider:
|
||||
label: Provider
|
||||
|
|
|
@ -125,6 +125,8 @@ en:
|
|||
scriptables:
|
||||
send_slack_message:
|
||||
title: Send Slack message
|
||||
send_chat_integration_message:
|
||||
title: Send Chat-Integration message
|
||||
chat_integration:
|
||||
|
||||
all_categories: "(all categories)"
|
||||
|
@ -134,6 +136,12 @@ en:
|
|||
group_mention_template: "mentions of: @%{name}"
|
||||
group_message_template: "messages to: @%{name}"
|
||||
|
||||
|
||||
topic_tag_changed:
|
||||
added_and_removed: "Added %{added} and removed %{removed}"
|
||||
added: "Added %{added}"
|
||||
removed: "Removed %{removed}"
|
||||
|
||||
provider:
|
||||
|
||||
#######################################
|
||||
|
|
|
@ -1,92 +1,96 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# The next migration file is a migration that migrates the tag_added filter to an automation.
|
||||
# this one uses ActiveRecord which is not recommended for migrations.
|
||||
|
||||
class MigrateTagAddedFromFilterToAutomation < ActiveRecord::Migration[7.1]
|
||||
def up
|
||||
if defined?(DiscourseAutomation) &&
|
||||
DiscourseChatIntegration::Channel.with_provider("slack").exists?
|
||||
begin
|
||||
DiscourseChatIntegration::Rule
|
||||
.where("value::json->>'filter'=?", "tag_added")
|
||||
.each do |rule|
|
||||
channel_id = rule.value["channel_id"]
|
||||
channel_name =
|
||||
DiscourseChatIntegration::Channel.find(channel_id).value["data"]["identifier"] # it _must_ have a channel_id
|
||||
# if defined?(DiscourseAutomation) &&
|
||||
# DiscourseChatIntegration::Channel.with_provider("slack").exists?
|
||||
# begin
|
||||
# DiscourseChatIntegration::Rule
|
||||
# .where("value::json->>'filter'=?", "tag_added")
|
||||
# .each do |rule|
|
||||
# channel_id = rule.value["channel_id"]
|
||||
# channel_name =
|
||||
# DiscourseChatIntegration::Channel.find(channel_id).value["data"]["identifier"] # it _must_ have a channel_id
|
||||
|
||||
category_id = rule.value["category_id"]
|
||||
tags = rule.value["tags"]
|
||||
# category_id = rule.value["category_id"]
|
||||
# tags = rule.value["tags"]
|
||||
|
||||
automation =
|
||||
DiscourseAutomation::Automation.new(
|
||||
script: "send_slack_message",
|
||||
trigger: "topic_tags_changed",
|
||||
name: "When tags change in topic",
|
||||
enabled: true,
|
||||
last_updated_by_id: Discourse.system_user.id,
|
||||
)
|
||||
# automation =
|
||||
# DiscourseAutomation::Automation.new(
|
||||
# script: "send_slack_message",
|
||||
# trigger: "topic_tags_changed",
|
||||
# name: "When tags change in topic",
|
||||
# enabled: true,
|
||||
# last_updated_by_id: Discourse.system_user.id,
|
||||
# )
|
||||
|
||||
automation.save!
|
||||
# automation.save!
|
||||
|
||||
# Triggers:
|
||||
# Watching categories
|
||||
# # Triggers:
|
||||
# # Watching categories
|
||||
|
||||
metadata = (category_id ? { "value" => [category_id] } : {})
|
||||
# metadata = (category_id ? { "value" => [category_id] } : {})
|
||||
|
||||
automation.upsert_field!(
|
||||
"watching_categories",
|
||||
"categories",
|
||||
metadata,
|
||||
target: "trigger",
|
||||
)
|
||||
# automation.upsert_field!(
|
||||
# "watching_categories",
|
||||
# "categories",
|
||||
# metadata,
|
||||
# target: "trigger",
|
||||
# )
|
||||
|
||||
# Watching tags
|
||||
# # Watching tags
|
||||
|
||||
metadata = (tags ? { "value" => tags } : {})
|
||||
# metadata = (tags ? { "value" => tags } : {})
|
||||
|
||||
automation.upsert_field!("watching_tags", "tags", metadata, target: "trigger")
|
||||
# automation.upsert_field!("watching_tags", "tags", metadata, target: "trigger")
|
||||
|
||||
# Script options:
|
||||
# Message
|
||||
automation.upsert_field!(
|
||||
"message",
|
||||
"message",
|
||||
{ "value" => "${ADDED_AND_REMOVED}" },
|
||||
target: "script",
|
||||
)
|
||||
# # Script options:
|
||||
# # Message
|
||||
# automation.upsert_field!(
|
||||
# "message",
|
||||
# "message",
|
||||
# { "value" => "${ADDED_AND_REMOVED}" },
|
||||
# target: "script",
|
||||
# )
|
||||
|
||||
# URL
|
||||
automation.upsert_field!(
|
||||
"url",
|
||||
"text",
|
||||
{ "value" => Discourse.current_hostname },
|
||||
target: "script",
|
||||
)
|
||||
# # URL
|
||||
# automation.upsert_field!(
|
||||
# "url",
|
||||
# "text",
|
||||
# { "value" => Discourse.current_hostname },
|
||||
# target: "script",
|
||||
# )
|
||||
|
||||
# Channel
|
||||
automation.upsert_field!(
|
||||
"channel",
|
||||
"text",
|
||||
{ "value" => channel_name },
|
||||
target: "script",
|
||||
)
|
||||
end
|
||||
rescue StandardError
|
||||
Rails.logger.warn("Failed to migrate tag_added rules to automations")
|
||||
end
|
||||
end
|
||||
# # Channel
|
||||
# automation.upsert_field!(
|
||||
# "channel",
|
||||
# "text",
|
||||
# { "value" => channel_name },
|
||||
# target: "script",
|
||||
# )
|
||||
# end
|
||||
# rescue StandardError
|
||||
# Rails.logger.warn("Failed to migrate tag_added rules to automations")
|
||||
# end
|
||||
# end
|
||||
end
|
||||
|
||||
def down
|
||||
if defined?(DiscourseAutomation) &&
|
||||
DiscourseChatIntegration::Channel.with_provider("slack").exists?
|
||||
DiscourseAutomation::Automation
|
||||
.where(script: "send_slack_message", trigger: "topic_tags_changed")
|
||||
.each do |automation|
|
||||
# if is the same name as created and message is the same
|
||||
if automation.name == "When tags change in topic" &&
|
||||
automation.fields.where(name: "message").first.metadata["value"] ==
|
||||
"${ADDED_AND_REMOVED}"
|
||||
automation.destroy!
|
||||
end
|
||||
end
|
||||
end
|
||||
# if defined?(DiscourseAutomation) &&
|
||||
# DiscourseChatIntegration::Channel.with_provider("slack").exists?
|
||||
# DiscourseAutomation::Automation
|
||||
# .where(script: "send_slack_message", trigger: "topic_tags_changed")
|
||||
# .each do |automation|
|
||||
# # if is the same name as created and message is the same
|
||||
# if automation.name == "When tags change in topic" &&
|
||||
# automation.fields.where(name: "message").first.metadata["value"] ==
|
||||
# "${ADDED_AND_REMOVED}"
|
||||
# automation.destroy!
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,153 @@
|
|||
# frozen_string_literal: true
|
||||
class MigrateTagAddedFilterToAllProviders < ActiveRecord::Migration[7.1]
|
||||
def up
|
||||
if defined?(DiscourseAutomation)
|
||||
begin
|
||||
slack_usage_rows = DB.query <<~SQL
|
||||
SELECT plugin_store_rows.* FROM plugin_store_rows
|
||||
WHERE plugin_store_rows.type_name = 'JSON'
|
||||
AND plugin_store_rows.plugin_name = 'discourse-chat-integration'
|
||||
AND (key LIKE 'channel:%')
|
||||
AND (value::json->>'provider'='slack')
|
||||
SQL
|
||||
|
||||
old_migration_delete = <<~SQL
|
||||
DELETE FROM discourse_automation_automations
|
||||
WHERE id IN (
|
||||
SELECT a.id
|
||||
FROM discourse_automation_automations a
|
||||
JOIN discourse_automation_fields f ON f.automation_id = a.id
|
||||
WHERE a.script = 'send_slack_message'
|
||||
AND a.trigger = 'topic_tags_changed'
|
||||
AND a.name = 'When tags change in topic'
|
||||
AND f.name = 'message'
|
||||
AND f.metadata->>'value' = '${ADDED_AND_REMOVED}'
|
||||
)
|
||||
SQL
|
||||
# Trash old migration
|
||||
DB.exec old_migration_delete if slack_usage_rows.count > 0
|
||||
|
||||
rules_with_tag_added = <<~SQL
|
||||
SELECT value
|
||||
FROM plugin_store_rows
|
||||
WHERE plugin_name = 'discourse-chat-integration'
|
||||
AND key LIKE 'rule:%'
|
||||
AND value::json->>'filter' = 'tag_added'
|
||||
SQL
|
||||
|
||||
channel_query = <<~SQL
|
||||
SELECT *
|
||||
FROM plugin_store_rows
|
||||
WHERE type_name = 'JSON'
|
||||
AND plugin_name = 'discourse-chat-integration'
|
||||
AND key LIKE 'channel:%'
|
||||
AND id = :channel_id
|
||||
LIMIT 1
|
||||
SQL
|
||||
|
||||
automation_creation = <<~SQL
|
||||
INSERT INTO discourse_automation_automations (script, trigger, name, enabled, last_updated_by_id, created_at, updated_at)
|
||||
VALUES ('send_chat_integration_message', 'topic_tags_changed', 'When tags change in topic', true, -1, NOW(), NOW())
|
||||
RETURNING id
|
||||
SQL
|
||||
|
||||
create_automation_field = <<~SQL
|
||||
INSERT INTO discourse_automation_fields (automation_id, name, component, metadata, target, created_at, updated_at)
|
||||
VALUES (:automation_id, :name, :component, :metadata, :target, NOW(), NOW())
|
||||
SQL
|
||||
|
||||
provider_identifier_map = {
|
||||
"groupme" => "groupme_instance_name",
|
||||
"discord" => "name",
|
||||
"guilded" => "name",
|
||||
"mattermost" => "identifier",
|
||||
"matrix" => "name",
|
||||
"teams" => "name",
|
||||
"zulip" => "stream",
|
||||
"powerautomate" => "name",
|
||||
"rocketchat" => "identifier",
|
||||
"gitter" => "name",
|
||||
"telegram" => "name",
|
||||
"flowdock" => "flow_token",
|
||||
"google" => "name",
|
||||
"webex" => "name",
|
||||
"slack" => "identifier",
|
||||
}
|
||||
|
||||
DB
|
||||
.query(rules_with_tag_added)
|
||||
.each do |row|
|
||||
rule = JSON.parse(row.value).with_indifferent_access
|
||||
|
||||
channel =
|
||||
JSON.parse(
|
||||
DB.query(channel_query, channel_id: rule[:channel_id]).first.value,
|
||||
).with_indifferent_access
|
||||
|
||||
provider_name = channel[:provider]
|
||||
channel_name = channel[:data][provider_identifier_map[provider_name]]
|
||||
|
||||
category_id = rule[:category_id]
|
||||
tags = rule[:tags]
|
||||
|
||||
automation_id = DB.query(automation_creation).first.id
|
||||
|
||||
# Triggers:
|
||||
# Watching categories
|
||||
metadata = (category_id ? { "value" => [category_id] } : {}).to_json
|
||||
DB.exec(
|
||||
create_automation_field,
|
||||
automation_id: automation_id,
|
||||
name: "watching_categories",
|
||||
component: "categories",
|
||||
metadata: metadata,
|
||||
target: "trigger",
|
||||
)
|
||||
|
||||
# Watching tags
|
||||
metadata = (tags.present? ? { "value" => tags } : {}).to_json
|
||||
DB.exec(
|
||||
create_automation_field,
|
||||
automation_id: automation_id,
|
||||
name: "watching_tags",
|
||||
component: "tags",
|
||||
metadata: metadata,
|
||||
target: "trigger",
|
||||
)
|
||||
|
||||
# Script options:
|
||||
# Provider
|
||||
DB.exec(
|
||||
create_automation_field,
|
||||
automation_id: automation_id,
|
||||
name: "provider",
|
||||
component: "choices",
|
||||
metadata: { "value" => provider_name }.to_json,
|
||||
target: "script",
|
||||
)
|
||||
|
||||
# Channel name
|
||||
DB.exec(
|
||||
create_automation_field,
|
||||
automation_id: automation_id,
|
||||
name: "channel_name",
|
||||
component: "text",
|
||||
metadata: { "value" => channel_name }.to_json,
|
||||
target: "script",
|
||||
)
|
||||
end
|
||||
rescue StandardError
|
||||
puts "Error migrating tag_added filters to all providers"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
DB.exec <<~SQL if defined?(DiscourseAutomation)
|
||||
DELETE FROM discourse_automation_automations
|
||||
WHERE script = 'send_chat_integration_message'
|
||||
AND trigger = 'topic_tags_changed'
|
||||
AND name = 'When tags change in topic'
|
||||
SQL
|
||||
end
|
||||
end
|
|
@ -0,0 +1,75 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module DiscourseChatIntegration
|
||||
class ChatIntegrationReferencePost
|
||||
def initialize(user:, topic:, kind:, raw: nil, context: {})
|
||||
@user = user
|
||||
@topic = topic
|
||||
@kind = kind
|
||||
@raw = raw if raw.present?
|
||||
@context = context
|
||||
@created_at = Time.current
|
||||
end
|
||||
|
||||
def id
|
||||
@topic.posts.empty? ? @topic.id : @topic.posts.first.id
|
||||
end
|
||||
|
||||
def user
|
||||
@user
|
||||
end
|
||||
|
||||
def topic
|
||||
@topic
|
||||
end
|
||||
|
||||
def full_url
|
||||
@topic.posts.empty? ? @topic.full_url : @topic.posts.first.full_url
|
||||
end
|
||||
|
||||
def excerpt(maxlength = nil, options = {})
|
||||
cooked = PrettyText.cook(raw, { user_id: user.id })
|
||||
maxlength ||= SiteSetting.post_excerpt_maxlength
|
||||
PrettyText.excerpt(cooked, maxlength, options)
|
||||
end
|
||||
|
||||
def is_first_post?
|
||||
topic.try(:highest_post_number) == 0
|
||||
end
|
||||
|
||||
def created_at
|
||||
@created_at
|
||||
end
|
||||
|
||||
def raw
|
||||
if @raw.nil? && @kind == DiscourseAutomation::Triggers::TOPIC_TAGS_CHANGED
|
||||
tag_list_to_raw = ->(tag_list) do
|
||||
tag_list.sort.map { |tag_name| "##{tag_name}" }.join(", ")
|
||||
end
|
||||
|
||||
added_tags = @context["added_tags"]
|
||||
removed_tags = @context["removed_tags"]
|
||||
|
||||
@raw =
|
||||
if added_tags.present? && removed_tags.present?
|
||||
I18n.t(
|
||||
"chat_integration.topic_tag_changed.added_and_removed",
|
||||
added: tag_list_to_raw.call(added_tags),
|
||||
removed: tag_list_to_raw.call(removed_tags),
|
||||
)
|
||||
elsif added_tags.present?
|
||||
I18n.t(
|
||||
"chat_integration.topic_tag_changed.added",
|
||||
added: tag_list_to_raw.call(added_tags),
|
||||
)
|
||||
elsif removed_tags.present?
|
||||
I18n.t(
|
||||
"chat_integration.topic_tag_changed.removed",
|
||||
removed: tag_list_to_raw.call(removed_tags),
|
||||
)
|
||||
end
|
||||
end
|
||||
@raw
|
||||
end
|
||||
end
|
||||
end
|
|
@ -5,7 +5,7 @@ module DiscourseChatIntegration
|
|||
module DiscordProvider
|
||||
PROVIDER_NAME = "discord".freeze
|
||||
PROVIDER_ENABLED_SETTING = :chat_integration_discord_enabled
|
||||
|
||||
CHANNEL_IDENTIFIER_KEY = "name".freeze
|
||||
CHANNEL_PARAMETERS = [
|
||||
{ key: "name", regex: '^\S+' },
|
||||
{
|
||||
|
@ -94,6 +94,13 @@ module DiscourseChatIntegration
|
|||
)
|
||||
end
|
||||
end
|
||||
|
||||
def self.get_channel_by_name(name)
|
||||
DiscourseChatIntegration::Channel
|
||||
.with_provider(PROVIDER_NAME)
|
||||
.with_data_value(CHANNEL_IDENTIFIER_KEY, name)
|
||||
.first
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
module DiscourseChatIntegration::Provider::FlowdockProvider
|
||||
PROVIDER_NAME = "flowdock".freeze
|
||||
PROVIDER_ENABLED_SETTING = :chat_integration_flowdock_enabled
|
||||
CHANNEL_IDENTIFIER_KEY = "flow_token".freeze # this is really weird but is the only way to identify a channel in this provider
|
||||
CHANNEL_PARAMETERS = [{ key: "flow_token", regex: '^\S+', unique: true, hidden: true }]
|
||||
|
||||
def self.send_message(url, message)
|
||||
|
@ -60,4 +61,11 @@ module DiscourseChatIntegration::Provider::FlowdockProvider
|
|||
}
|
||||
end
|
||||
end
|
||||
|
||||
def self.get_channel_by_name(name)
|
||||
DiscourseChatIntegration::Channel
|
||||
.with_provider(PROVIDER_NAME)
|
||||
.with_data_value(CHANNEL_IDENTIFIER_KEY, name)
|
||||
.first
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,6 +5,7 @@ module DiscourseChatIntegration
|
|||
module GitterProvider
|
||||
PROVIDER_NAME = "gitter".freeze
|
||||
PROVIDER_ENABLED_SETTING = :chat_integration_gitter_enabled
|
||||
CHANNEL_IDENTIFIER_KEY = "name".freeze
|
||||
CHANNEL_PARAMETERS = [
|
||||
{ key: "name", regex: '^\S+$', unique: true },
|
||||
{
|
||||
|
@ -43,6 +44,13 @@ module DiscourseChatIntegration
|
|||
|
||||
"[__#{display_name}__ - #{topic.title} - #{category_name}](#{post.full_url})"
|
||||
end
|
||||
|
||||
def self.get_channel_by_name(name)
|
||||
DiscourseChatIntegration::Channel
|
||||
.with_provider(PROVIDER_NAME)
|
||||
.with_data_value(CHANNEL_IDENTIFIER_KEY, name)
|
||||
.first
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,6 +5,7 @@ module DiscourseChatIntegration
|
|||
module GoogleProvider
|
||||
PROVIDER_NAME = "google".freeze
|
||||
PROVIDER_ENABLED_SETTING = :chat_integration_google_enabled
|
||||
CHANNEL_IDENTIFIER_KEY = "name".freeze
|
||||
CHANNEL_PARAMETERS = [
|
||||
{ key: "name", regex: '^\S+$', unique: true },
|
||||
{
|
||||
|
@ -107,6 +108,13 @@ module DiscourseChatIntegration
|
|||
],
|
||||
}
|
||||
end
|
||||
|
||||
def self.get_channel_by_name(name)
|
||||
DiscourseChatIntegration::Channel
|
||||
.with_provider(PROVIDER_NAME)
|
||||
.with_data_value(CHANNEL_IDENTIFIER_KEY, name)
|
||||
.first
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
module DiscourseChatIntegration::Provider::GroupmeProvider
|
||||
PROVIDER_NAME = "groupme".freeze
|
||||
PROVIDER_ENABLED_SETTING = :chat_integration_groupme_enabled
|
||||
CHANNEL_IDENTIFIER_KEY = "groupme_instance_name".freeze
|
||||
CHANNEL_PARAMETERS = [{ key: "groupme_instance_name", regex: '[\s\S]*', unique: true }]
|
||||
|
||||
def self.generate_groupme_message(post)
|
||||
|
@ -84,4 +85,11 @@ module DiscourseChatIntegration::Provider::GroupmeProvider
|
|||
data_package = generate_groupme_message(post)
|
||||
self.send_via_webhook(data_package, channel)
|
||||
end
|
||||
|
||||
def self.get_channel_by_name(name)
|
||||
DiscourseChatIntegration::Channel
|
||||
.with_provider(PROVIDER_NAME)
|
||||
.with_data_value(CHANNEL_IDENTIFIER_KEY, name)
|
||||
.first
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,7 +5,7 @@ module DiscourseChatIntegration
|
|||
module GuildedProvider
|
||||
PROVIDER_NAME = "guilded".freeze
|
||||
PROVIDER_ENABLED_SETTING = :chat_integration_guilded_enabled
|
||||
|
||||
CHANNEL_IDENTIFIER_KEY = "name".freeze
|
||||
CHANNEL_PARAMETERS = [
|
||||
{ key: "name", regex: '^\S+' },
|
||||
{
|
||||
|
@ -92,6 +92,13 @@ module DiscourseChatIntegration
|
|||
return url if !url.start_with?("//")
|
||||
"http:#{url}"
|
||||
end
|
||||
|
||||
def self.get_channel_by_name(name)
|
||||
DiscourseChatIntegration::Channel
|
||||
.with_provider(PROVIDER_NAME)
|
||||
.with_data_value(CHANNEL_IDENTIFIER_KEY, name)
|
||||
.first
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,6 +5,7 @@ module DiscourseChatIntegration
|
|||
module MatrixProvider
|
||||
PROVIDER_NAME = "matrix".freeze
|
||||
PROVIDER_ENABLED_SETTING = :chat_integration_matrix_enabled
|
||||
CHANNEL_IDENTIFIER_KEY = "name".freeze
|
||||
CHANNEL_PARAMETERS = [
|
||||
{ key: "name", regex: '^\S+' },
|
||||
{ key: "room_id", regex: '^\!\S+:\S+$', unique: true, hidden: true },
|
||||
|
@ -88,6 +89,13 @@ module DiscourseChatIntegration
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.get_channel_by_name(name)
|
||||
DiscourseChatIntegration::Channel
|
||||
.with_provider(PROVIDER_NAME)
|
||||
.with_data_value(CHANNEL_IDENTIFIER_KEY, name)
|
||||
.first
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,6 +5,7 @@ module DiscourseChatIntegration
|
|||
module MattermostProvider
|
||||
PROVIDER_NAME = "mattermost".freeze
|
||||
PROVIDER_ENABLED_SETTING = :chat_integration_mattermost_enabled
|
||||
CHANNEL_IDENTIFIER_KEY = "identifier".freeze
|
||||
CHANNEL_PARAMETERS = [{ key: "identifier", regex: '^[@#]\S*$', unique: true }]
|
||||
|
||||
def self.send_via_webhook(message)
|
||||
|
@ -93,6 +94,13 @@ module DiscourseChatIntegration
|
|||
|
||||
self.send_via_webhook(message)
|
||||
end
|
||||
|
||||
def self.get_channel_by_name(name)
|
||||
DiscourseChatIntegration::Channel
|
||||
.with_provider(PROVIDER_NAME)
|
||||
.with_data_value(CHANNEL_IDENTIFIER_KEY, name)
|
||||
.first
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
module DiscourseChatIntegration::Provider::PowerAutomateProvider
|
||||
PROVIDER_NAME = "powerautomate"
|
||||
PROVIDER_ENABLED_SETTING = :chat_integration_powerautomate_enabled
|
||||
CHANNEL_IDENTIFIER_KEY = "name".freeze
|
||||
CHANNEL_PARAMETERS = [
|
||||
{ key: "name", regex: '^\S+$', unique: true },
|
||||
{ key: "webhook_url", regex: '^https:\/\/\S+$', unique: true, hidden: true },
|
||||
|
@ -130,4 +131,11 @@ module DiscourseChatIntegration::Provider::PowerAutomateProvider
|
|||
|
||||
message
|
||||
end
|
||||
|
||||
def self.get_channel_by_name(name)
|
||||
DiscourseChatIntegration::Channel
|
||||
.with_provider(PROVIDER_NAME)
|
||||
.with_data_value(CHANNEL_IDENTIFIER_KEY, name)
|
||||
.first
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,7 +4,7 @@ module DiscourseChatIntegration::Provider::RocketchatProvider
|
|||
PROVIDER_NAME = "rocketchat".freeze
|
||||
|
||||
PROVIDER_ENABLED_SETTING = :chat_integration_rocketchat_enabled
|
||||
|
||||
CHANNEL_IDENTIFIER_KEY = "identifier".freeze
|
||||
CHANNEL_PARAMETERS = [{ key: "identifier", regex: '^[@#]\S*$', unique: true }]
|
||||
|
||||
def self.rocketchat_message(post, channel)
|
||||
|
@ -82,4 +82,11 @@ module DiscourseChatIntegration::Provider::RocketchatProvider
|
|||
|
||||
self.send_via_webhook(message)
|
||||
end
|
||||
|
||||
def self.get_channel_by_name(name)
|
||||
DiscourseChatIntegration::Channel
|
||||
.with_provider(PROVIDER_NAME)
|
||||
.with_data_value(CHANNEL_IDENTIFIER_KEY, name)
|
||||
.first
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,7 +12,7 @@ module DiscourseChatIntegration::Provider::SlackProvider
|
|||
THREAD_LEGACY = "thread"
|
||||
|
||||
PROVIDER_ENABLED_SETTING = :chat_integration_slack_enabled
|
||||
|
||||
CHANNEL_IDENTIFIER_KEY = "identifier".freeze
|
||||
CHANNEL_PARAMETERS = [{ key: "identifier", regex: '^[@#]?\S*$', unique: true }]
|
||||
|
||||
require_dependency "topic"
|
||||
|
@ -339,6 +339,13 @@ module DiscourseChatIntegration::Provider::SlackProvider
|
|||
def self.create_tag_list(tag_list)
|
||||
tag_list.map { |tag_name| "<#{Tag.find_by_name(tag_name).full_url}|#{tag_name}>" }.join(", ")
|
||||
end
|
||||
|
||||
def self.get_channel_by_name(name)
|
||||
DiscourseChatIntegration::Channel
|
||||
.with_provider(PROVIDER_NAME)
|
||||
.with_data_value(CHANNEL_IDENTIFIER_KEY, name)
|
||||
.first
|
||||
end
|
||||
end
|
||||
|
||||
require_relative "slack_message_formatter"
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
module DiscourseChatIntegration::Provider::TeamsProvider
|
||||
PROVIDER_NAME = "teams".freeze
|
||||
PROVIDER_ENABLED_SETTING = :chat_integration_teams_enabled
|
||||
CHANNEL_IDENTIFIER_KEY = "name".freeze
|
||||
CHANNEL_PARAMETERS = [
|
||||
{ key: "name", regex: '^\S+$', unique: true },
|
||||
{ key: "webhook_url", regex: '^https:\/\/\S+$', unique: true, hidden: true },
|
||||
|
@ -82,4 +83,11 @@ module DiscourseChatIntegration::Provider::TeamsProvider
|
|||
|
||||
message
|
||||
end
|
||||
|
||||
def self.get_channel_by_name(name)
|
||||
DiscourseChatIntegration::Channel
|
||||
.with_provider(PROVIDER_NAME)
|
||||
.with_data_value(CHANNEL_IDENTIFIER_KEY, name)
|
||||
.first
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,6 +5,7 @@ module DiscourseChatIntegration
|
|||
module TelegramProvider
|
||||
PROVIDER_NAME = "telegram".freeze
|
||||
PROVIDER_ENABLED_SETTING = :chat_integration_telegram_enabled
|
||||
CHANNEL_IDENTIFIER_KEY = "name".freeze
|
||||
CHANNEL_PARAMETERS = [
|
||||
{ key: "name", regex: '^\S+' },
|
||||
{ key: "chat_id", regex: '^(-?[0-9]+|@\S+)$', unique: true },
|
||||
|
@ -110,6 +111,13 @@ module DiscourseChatIntegration
|
|||
}
|
||||
end
|
||||
end
|
||||
|
||||
def self.get_channel_by_name(name)
|
||||
DiscourseChatIntegration::Channel
|
||||
.with_provider(PROVIDER_NAME)
|
||||
.with_data_value(CHANNEL_IDENTIFIER_KEY, name)
|
||||
.first
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
module DiscourseChatIntegration::Provider::WebexProvider
|
||||
PROVIDER_NAME = "webex".freeze
|
||||
PROVIDER_ENABLED_SETTING = :chat_integration_webex_enabled
|
||||
CHANNEL_IDENTIFIER_KEY = "name".freeze
|
||||
CHANNEL_PARAMETERS = [
|
||||
{ key: "name", regex: '^\S+$', unique: true },
|
||||
{
|
||||
|
@ -71,4 +72,11 @@ module DiscourseChatIntegration::Provider::WebexProvider
|
|||
|
||||
{ markdown: markdown }
|
||||
end
|
||||
|
||||
def self.get_channel_by_name(name)
|
||||
DiscourseChatIntegration::Channel
|
||||
.with_provider(PROVIDER_NAME)
|
||||
.with_data_value(CHANNEL_IDENTIFIER_KEY, name)
|
||||
.first
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,6 +5,7 @@ module DiscourseChatIntegration
|
|||
module ZulipProvider
|
||||
PROVIDER_NAME = "zulip".freeze
|
||||
PROVIDER_ENABLED_SETTING = :chat_integration_zulip_enabled
|
||||
CHANNEL_IDENTIFIER_KEY = "stream".freeze
|
||||
CHANNEL_PARAMETERS = [
|
||||
{ key: "stream", unique: true, regex: '^\S+' },
|
||||
{ key: "subject", unique: true, regex: '^\S+' },
|
||||
|
@ -71,6 +72,13 @@ module DiscourseChatIntegration
|
|||
}
|
||||
end
|
||||
end
|
||||
|
||||
def self.get_channel_by_name(name)
|
||||
DiscourseChatIntegration::Channel
|
||||
.with_provider(PROVIDER_NAME)
|
||||
.with_data_value(CHANNEL_IDENTIFIER_KEY, name)
|
||||
.first
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
48
plugin.rb
48
plugin.rb
|
@ -16,6 +16,7 @@ register_svg_icon "fa-arrow-circle-o-right" if respond_to?(:register_svg_icon)
|
|||
|
||||
# Site setting validators must be loaded before initialize
|
||||
require_relative "lib/discourse_chat_integration/provider/slack/slack_enabled_setting_validator"
|
||||
require_relative "lib/discourse_chat_integration/chat_integration_reference_post"
|
||||
|
||||
after_initialize do
|
||||
require_relative "app/initializers/discourse_chat_integration"
|
||||
|
@ -84,5 +85,52 @@ after_initialize do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
add_automation_scriptable("send_chat_integration_message") do
|
||||
field :provider,
|
||||
component: :choices,
|
||||
extra: {
|
||||
content:
|
||||
DiscourseChatIntegration::Provider.enabled_provider_names.map do |provider|
|
||||
{ id: provider, name: "chat_integration.provider.#{provider}.title" }
|
||||
end,
|
||||
},
|
||||
required: true
|
||||
field :channel_name, component: :text, required: true
|
||||
|
||||
version 1
|
||||
|
||||
triggerables %i[topic_tags_changed]
|
||||
|
||||
script do |context, fields, automation|
|
||||
provider = fields.dig("provider", "value")
|
||||
channel_name = fields.dig("channel_name", "value")
|
||||
|
||||
post =
|
||||
DiscourseChatIntegration::ChatIntegrationReferencePost.new(
|
||||
user: context["user"],
|
||||
topic: context["topic"],
|
||||
kind: context["kind"],
|
||||
context: {
|
||||
"added_tags" => context["added_tags"],
|
||||
"removed_tags" => context["removed_tags"],
|
||||
},
|
||||
)
|
||||
provider = DiscourseChatIntegration::Provider.get_by_name(provider)
|
||||
|
||||
channel = provider.get_channel_by_name(channel_name) # user must have created a channel in /admin/plugins/chat-integration/<provider> page
|
||||
|
||||
if channel.nil?
|
||||
Rails.logger.warn "[discourse-automation] Channel not found. Automation ID: #{automation.id}"
|
||||
next
|
||||
end
|
||||
|
||||
begin
|
||||
provider.trigger_notification(post, channel, nil)
|
||||
rescue StandardError => _
|
||||
Rails.logger.warn "[discourse-automation] Error while sending chat integration message. Automation ID: #{automation.id}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -40,6 +40,7 @@ RSpec.shared_context "with validated dummy provider" do
|
|||
module ::DiscourseChatIntegration::Provider::Dummy2Provider
|
||||
PROVIDER_NAME = "dummy2".freeze
|
||||
PROVIDER_ENABLED_SETTING = :chat_integration_enabled # Tie to main plugin enabled setting
|
||||
CHANNEL_IDENTIFIER_KEY = "val".freeze
|
||||
CHANNEL_PARAMETERS = [{ key: "val", regex: '^\S+$', unique: true }]
|
||||
|
||||
@@sent_messages = []
|
||||
|
@ -51,8 +52,17 @@ RSpec.shared_context "with validated dummy provider" do
|
|||
def self.sent_messages
|
||||
@@sent_messages
|
||||
end
|
||||
|
||||
def self.get_channel_by_name(name)
|
||||
DiscourseChatIntegration::Channel
|
||||
.with_provider(PROVIDER_NAME)
|
||||
.with_data_value(CHANNEL_IDENTIFIER_KEY, name)
|
||||
.first
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
after(:each) { ::DiscourseChatIntegration::Provider.send(:remove_const, :Dummy2Provider) }
|
||||
|
||||
let(:validated_provider) { ::DiscourseChatIntegration::Provider::Dummy2Provider }
|
||||
end
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
# frozen_string_literal: true
|
||||
require_relative "../dummy_provider"
|
||||
RSpec.describe "Triggering notifications" do
|
||||
include_context "with validated dummy provider"
|
||||
|
||||
context "with automation installed", if: defined?(DiscourseAutomation) do
|
||||
fab!(:admin)
|
||||
fab!(:category)
|
||||
fab!(:tag)
|
||||
|
||||
fab!(:automation) do
|
||||
Fabricate(
|
||||
:automation,
|
||||
script: "send_chat_integration_message",
|
||||
trigger: "topic_tags_changed",
|
||||
enabled: true,
|
||||
)
|
||||
end
|
||||
let(:channel1) do
|
||||
DiscourseChatIntegration::Channel.create!(provider: "dummy2", data: { val: "channel" })
|
||||
end
|
||||
|
||||
before do
|
||||
SiteSetting.chat_integration_enabled = true
|
||||
SiteSetting.discourse_automation_enabled = true
|
||||
|
||||
SiteSetting.tagging_enabled = true
|
||||
SiteSetting.create_tag_allowed_groups = Group::AUTO_GROUPS[:everyone]
|
||||
SiteSetting.tag_topic_allowed_groups = Group::AUTO_GROUPS[:everyone]
|
||||
|
||||
automation.upsert_field!(
|
||||
"watching_categories",
|
||||
"categories",
|
||||
{ "value" => [category.id] },
|
||||
target: "trigger",
|
||||
)
|
||||
automation.upsert_field!(
|
||||
"watching_tags",
|
||||
"tags",
|
||||
{ "value" => [tag.name] },
|
||||
target: "trigger",
|
||||
)
|
||||
automation.upsert_field!(
|
||||
"provider",
|
||||
"choices",
|
||||
{ "value" => channel1.provider },
|
||||
target: "script",
|
||||
)
|
||||
automation.upsert_field!("channel_name", "text", { "value" => "channel" }, target: "script")
|
||||
end
|
||||
|
||||
it "triggers a notification" do
|
||||
topic = Fabricate(:topic, user: admin, tags: [], category: category)
|
||||
|
||||
DiscourseTagging.tag_topic_by_names(topic, Guardian.new(admin), [tag.name])
|
||||
|
||||
expect(validated_provider.sent_messages.length).to eq(1)
|
||||
expect(validated_provider.sent_messages.first[:post]).to eq(topic.id)
|
||||
expect(validated_provider.sent_messages.first[:channel]).to eq(channel1)
|
||||
end
|
||||
|
||||
it "only triggers for the correct tag" do
|
||||
topic = Fabricate(:topic, user: admin, tags: [], category: category)
|
||||
|
||||
DiscourseTagging.tag_topic_by_names(topic, Guardian.new(admin), ["other_tag"])
|
||||
|
||||
expect(validated_provider.sent_messages.length).to eq(0)
|
||||
end
|
||||
|
||||
it "only triggers for the correct category" do
|
||||
topic = Fabricate(:topic, user: admin, tags: [], category: Fabricate(:category))
|
||||
|
||||
DiscourseTagging.tag_topic_by_names(topic, Guardian.new(admin), [tag.name])
|
||||
|
||||
expect(validated_provider.sent_messages.length).to eq(0)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,49 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe DiscourseChatIntegration::ChatIntegrationReferencePost do
|
||||
fab!(:topic)
|
||||
fab!(:first_post) { Fabricate(:post, topic: topic) }
|
||||
let!(:context) do
|
||||
{
|
||||
"user" => Fabricate(:user),
|
||||
"topic" => topic,
|
||||
# every rule will add a kind and their context params
|
||||
}
|
||||
end
|
||||
|
||||
describe "when creating when topic tags change" do
|
||||
before do
|
||||
context["kind"] = DiscourseAutomation::Triggers::TOPIC_TAGS_CHANGED
|
||||
context["added_tags"] = %w[tag1 tag2]
|
||||
context["removed_tags"] = %w[tag3 tag4]
|
||||
end
|
||||
|
||||
it "creates a post with the correct raw" do
|
||||
post =
|
||||
described_class.new(
|
||||
user: context["user"],
|
||||
topic: context["topic"],
|
||||
kind: context["kind"],
|
||||
context: {
|
||||
"added_tags" => context["added_tags"],
|
||||
"removed_tags" => context["removed_tags"],
|
||||
},
|
||||
)
|
||||
expect(post.raw).to eq("Added #tag1, #tag2 and removed #tag3, #tag4")
|
||||
end
|
||||
|
||||
it "has a working excerpt" do
|
||||
post =
|
||||
described_class.new(
|
||||
user: context["user"],
|
||||
topic: context["topic"],
|
||||
kind: context["kind"],
|
||||
context: {
|
||||
"added_tags" => context["added_tags"],
|
||||
"removed_tags" => context["removed_tags"],
|
||||
},
|
||||
)
|
||||
expect(post.excerpt).to eq("Added #tag1, #tag2 and removed #tag3, #tag4")
|
||||
end
|
||||
end
|
||||
end
|
|
@ -49,4 +49,18 @@ RSpec.describe DiscourseChatIntegration::Provider::DiscordProvider do
|
|||
expect(stub1).to have_been_requested.once
|
||||
end
|
||||
end
|
||||
|
||||
describe ".get_channel_by_name" do
|
||||
it "returns the right channel" do
|
||||
expected =
|
||||
DiscourseChatIntegration::Channel.create!(
|
||||
provider: "discord",
|
||||
data: {
|
||||
name: "Awesome Channel",
|
||||
webhook_url: "https://discord.com/api/webhooks/1234/abcd",
|
||||
},
|
||||
)
|
||||
expect(described_class.get_channel_by_name("Awesome Channel")).to eq(expected)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -36,4 +36,19 @@ RSpec.describe DiscourseChatIntegration::Provider::FlowdockProvider do
|
|||
expect(stub1).to have_been_requested.once
|
||||
end
|
||||
end
|
||||
|
||||
describe ".get_channel_by_name" do
|
||||
it "returns the right channel" do
|
||||
expected =
|
||||
DiscourseChatIntegration::Channel.create!(
|
||||
provider: "flowdock",
|
||||
data: {
|
||||
flow_token: "5d1fe04cf66e078d6a2b579ddb8a465b",
|
||||
},
|
||||
)
|
||||
expect(described_class.get_channel_by_name("5d1fe04cf66e078d6a2b579ddb8a465b")).to eq(
|
||||
expected,
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -37,4 +37,18 @@ RSpec.describe DiscourseChatIntegration::Provider::GitterProvider do
|
|||
expect(stub1).to have_been_requested.once
|
||||
end
|
||||
end
|
||||
|
||||
describe ".get_channel_by_name" do
|
||||
it "returns the right channel" do
|
||||
expected =
|
||||
DiscourseChatIntegration::Channel.create!(
|
||||
provider: "gitter",
|
||||
data: {
|
||||
name: "gitterHQ/services",
|
||||
webhook_url: "https://webhooks.gitter.im/e/a1e2i3o4u5",
|
||||
},
|
||||
)
|
||||
expect(described_class.get_channel_by_name("gitterHQ/services")).to eq(expected)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -33,4 +33,18 @@ RSpec.describe DiscourseChatIntegration::Provider::GoogleProvider do
|
|||
expect(stub1).to have_been_requested.once
|
||||
end
|
||||
end
|
||||
|
||||
describe ".get_channel_by_name" do
|
||||
it "returns the right channel" do
|
||||
expected =
|
||||
DiscourseChatIntegration::Channel.create!(
|
||||
provider: "google",
|
||||
data: {
|
||||
name: "discourse",
|
||||
webhook_url: "https://chat.googleapis.com/v1/abcdefg",
|
||||
},
|
||||
)
|
||||
expect(described_class.get_channel_by_name("discourse")).to eq(expected)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -39,4 +39,17 @@ RSpec.describe DiscourseChatIntegration::Provider::GroupmeProvider do
|
|||
expect(stub1).to have_been_requested.once
|
||||
end
|
||||
end
|
||||
|
||||
describe ".get_channel_by_name" do
|
||||
it "returns the right channel" do
|
||||
expected =
|
||||
DiscourseChatIntegration::Channel.create!(
|
||||
provider: "groupme",
|
||||
data: {
|
||||
groupme_instance_name: "my instance",
|
||||
},
|
||||
)
|
||||
expect(described_class.get_channel_by_name("my instance")).to eq(expected)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -35,4 +35,18 @@ RSpec.describe DiscourseChatIntegration::Provider::GuildedProvider do
|
|||
expect(stub1).to have_been_requested.once
|
||||
end
|
||||
end
|
||||
|
||||
describe ".get_channel_by_name" do
|
||||
it "returns the right channel" do
|
||||
expected =
|
||||
DiscourseChatIntegration::Channel.create!(
|
||||
provider: "guilded",
|
||||
data: {
|
||||
name: "Awesome Channel",
|
||||
webhook_url: "https://media.guilded.gg/webhooks/1234/abcd",
|
||||
},
|
||||
)
|
||||
expect(described_class.get_channel_by_name("Awesome Channel")).to eq(expected)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -44,4 +44,18 @@ RSpec.describe DiscourseChatIntegration::Provider::MatrixProvider do
|
|||
expect(stub1).to have_been_requested.once
|
||||
end
|
||||
end
|
||||
|
||||
describe ".get_channel_by_name" do
|
||||
it "returns the right channel" do
|
||||
expected =
|
||||
DiscourseChatIntegration::Channel.create!(
|
||||
provider: "matrix",
|
||||
data: {
|
||||
name: "Awesome Channel",
|
||||
room_id: "!blah:matrix.org",
|
||||
},
|
||||
)
|
||||
expect(described_class.get_channel_by_name("Awesome Channel")).to eq(expected)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -57,4 +57,17 @@ RSpec.describe DiscourseChatIntegration::Provider::MattermostProvider do
|
|||
expect(stub1).to have_been_requested.once
|
||||
end
|
||||
end
|
||||
|
||||
describe ".get_channel_by_name" do
|
||||
it "returns the right channel" do
|
||||
expected =
|
||||
DiscourseChatIntegration::Channel.create!(
|
||||
provider: "mattermost",
|
||||
data: {
|
||||
identifier: "#awesomechannel",
|
||||
},
|
||||
)
|
||||
expect(described_class.get_channel_by_name("#awesomechannel")).to eq(expected)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -34,4 +34,19 @@ RSpec.describe DiscourseChatIntegration::Provider::PowerAutomateProvider do
|
|||
expect(stub1).to have_been_requested.once
|
||||
end
|
||||
end
|
||||
|
||||
describe ".get_channel_by_name" do
|
||||
it "returns the right channel" do
|
||||
expected =
|
||||
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",
|
||||
},
|
||||
)
|
||||
expect(described_class.get_channel_by_name("discourse")).to eq(expected)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -35,4 +35,17 @@ RSpec.describe DiscourseChatIntegration::Provider::RocketchatProvider do
|
|||
expect(stub1).to have_been_requested.once
|
||||
end
|
||||
end
|
||||
|
||||
describe ".get_channel_by_name" do
|
||||
it "returns the right channel" do
|
||||
expected =
|
||||
DiscourseChatIntegration::Channel.create!(
|
||||
provider: "rocketchat",
|
||||
data: {
|
||||
identifier: "#general",
|
||||
},
|
||||
)
|
||||
expect(described_class.get_channel_by_name("#general")).to eq(expected)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -346,4 +346,17 @@ RSpec.describe DiscourseChatIntegration::Provider::SlackProvider do
|
|||
}.to raise_error(StandardError)
|
||||
end
|
||||
end
|
||||
|
||||
describe ".get_channel_by_name" do
|
||||
it "returns the right channel" do
|
||||
expected =
|
||||
DiscourseChatIntegration::Channel.create!(
|
||||
provider: "slack",
|
||||
data: {
|
||||
identifier: "#general",
|
||||
},
|
||||
)
|
||||
expect(described_class.get_channel_by_name("#general")).to eq(expected)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -44,4 +44,19 @@ RSpec.describe DiscourseChatIntegration::Provider::TeamsProvider do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe ".get_channel_by_name" do
|
||||
it "returns the right channel" do
|
||||
expected =
|
||||
DiscourseChatIntegration::Channel.create!(
|
||||
provider: "teams",
|
||||
data: {
|
||||
name: "discourse",
|
||||
webhook_url:
|
||||
"https://outlook.office.com/webhook/677980e4-e03b-4a5e-ad29-dc1ee0c32a80@9e9b5238-5ab2-496a-8e6a-e9cf05c7eb5c/IncomingWebhook/e7a1006ded44478992769d0c4f391e34/e028ca8a-e9c8-4c6c-a4d8-578f881a3cff",
|
||||
},
|
||||
)
|
||||
expect(described_class.get_channel_by_name("discourse")).to eq(expected)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -48,4 +48,18 @@ RSpec.describe DiscourseChatIntegration::Provider::TelegramProvider do
|
|||
expect(stub1).to have_been_requested.once
|
||||
end
|
||||
end
|
||||
|
||||
describe ".get_channel_by_name" do
|
||||
it "returns the right channel" do
|
||||
expected =
|
||||
DiscourseChatIntegration::Channel.create!(
|
||||
provider: "telegram",
|
||||
data: {
|
||||
name: "Awesome Channel",
|
||||
chat_id: "123",
|
||||
},
|
||||
)
|
||||
expect(described_class.get_channel_by_name("Awesome Channel")).to eq(expected)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -34,4 +34,19 @@ RSpec.describe DiscourseChatIntegration::Provider::WebexProvider do
|
|||
expect(stub1).to have_been_requested.once
|
||||
end
|
||||
end
|
||||
|
||||
describe ".get_channel_by_name" do
|
||||
it "returns the right channel" do
|
||||
expected =
|
||||
DiscourseChatIntegration::Channel.create!(
|
||||
provider: "webex",
|
||||
data: {
|
||||
name: "discourse",
|
||||
webhook_url:
|
||||
"https://webexapis.com/v1/webhooks/incoming/jAHJjVVQ1cgEwb4ikQQawIrGdUtlocKA9fSNvIyADQoYo0mI70pztWUDOu22gDRPJOEJtCsc688zi1RMa",
|
||||
},
|
||||
)
|
||||
expect(described_class.get_channel_by_name("discourse")).to eq(expected)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -42,4 +42,19 @@ RSpec.describe DiscourseChatIntegration::Provider::ZulipProvider do
|
|||
expect(stub1).to have_been_requested.once
|
||||
end
|
||||
end
|
||||
|
||||
describe ".get_channel_by_name" do
|
||||
it "returns the right channel" do
|
||||
created =
|
||||
DiscourseChatIntegration::Channel.create!(
|
||||
provider: "zulip",
|
||||
data: {
|
||||
stream: "foo",
|
||||
subject: "Discourse Notifications",
|
||||
},
|
||||
)
|
||||
channel = described_class.get_channel_by_name("foo")
|
||||
expect(channel).to eq(created)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue