forked from discourse/discourse-chat-integration
/
discord_provider.rb
119 lines (95 loc) · 3.99 KB
/
discord_provider.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
module DiscourseChat
module Provider
module DiscordProvider
PROVIDER_NAME = "discord".freeze
PROVIDER_ENABLED_SETTING = :chat_integration_discord_enabled
CHANNEL_PARAMETERS = [
{ key: "name", regex: '^\S+' },
{ key: "webhook_url", regex: '^https:\/\/discordapp\.com\/api\/webhooks\/', unique: true, hidden: true }
].freeze
def self.send_message(url, message)
http = Net::HTTP.new("discordapp.com", 443)
http.use_ssl = true
uri = URI(url)
req = Net::HTTP::Post.new(uri, 'Content-Type' => 'application/json')
req.body = message.to_json
response = http.request(req)
response
end
def self.ensure_protocol(url)
return url if !url.start_with?('//')
"http:#{url}"
end
def self.generate_discord_message(post)
display_name = "@#{post.user.username}"
full_name = post.user.name || ""
if !(full_name.strip.empty?) && (full_name.strip.gsub(' ', '_').casecmp(post.user.username) != 0) && (full_name.strip.gsub(' ', '').casecmp(post.user.username) != 0)
display_name = "#{full_name} (@#{post.user.username})"
end
topic = post.topic
category = ''
if topic.category
category = (topic.category.parent_category) ? "[#{topic.category.parent_category.name}/#{topic.category.name}]" : "[#{topic.category.name}]"
end
custom_user_embed_color = post.user.custom_fields["user_field_#{(UserField.find_by name: 'Embed Colour').id}"]
if post.post_number == 1
message = {
content: SiteSetting.chat_integration_discord_message_content,
embeds: [{
title: "#{(category == '[uncategorized]') ? '' : category} #{topic.title}",
footer: {
text: "New Thread • Invictus Roleplay Community"
},
thumbnail: {
url: "https://i.imgur.com/aEUkA0h.png"
},
color: custom_user_embed_color ? custom_user_embed_color.to_i(16) : nil,
description: post.excerpt(SiteSetting.chat_integration_discord_excerpt_length, text_entities: true, strip_links: true, remap_emoji: true),
url: post.full_url,
author: {
name: display_name,
url: Discourse.base_url + "/u/" + post.user.username,
icon_url: ensure_protocol(post.user.small_avatar_url)
}
}]
}
return message
end
if post.post_number != 1
message = {
content: SiteSetting.chat_integration_discord_message_content,
embeds: [{
title: "#{(category == '[uncategorized]') ? '' : category} #{topic.title}",
footer: {
text: "New Post • Invictus Roleplay Community"
},
thumbnail: {
url: "https://i.imgur.com/aEUkA0h.png"
},
color: custom_user_embed_color ? custom_user_embed_color.to_i(16) : nil,
description: post.excerpt(SiteSetting.chat_integration_discord_excerpt_length, text_entities: true, strip_links: true, remap_emoji: true),
url: post.full_url,
author: {
name: display_name,
url: Discourse.base_url + "/u/" + post.user.username,
icon_url: ensure_protocol(post.user.small_avatar_url)
}
}]
}
return message
end
end
def self.trigger_notification(post, channel)
# Adding ?wait=true means that we actually get a success/failure response, rather than returning asynchronously
webhook_url = "#{channel.data['webhook_url']}?wait=true"
message = generate_discord_message(post)
response = send_message(webhook_url, message)
if !response.kind_of?(Net::HTTPSuccess)
raise ::DiscourseChat::ProviderError.new(info: {
error_key: nil, message: message, response_body: response.body
})
end
end
end
end
end