mirror of
https://github.com/discourse/discourse-chat-integration.git
synced 2025-07-21 12:13:26 +00:00
This patch concerns the Telegram integration. Currently, we always try to process commands when we receive a hook from Telegram. To do so we rely on the `text` parameters from a Telegram message but the API documentation tells us this parameters is actually optional. It means sometimes it’s not present in the payload we receive but we still try to access it resulting in a crash. This patch addresses the issue by simply returning early from the `#process_command` method when `text` is missing from the payload since we don’t have anything to process then.
115 lines
3.4 KiB
Ruby
115 lines
3.4 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module DiscourseChatIntegration::Provider::TelegramProvider
|
|
class TelegramCommandController < DiscourseChatIntegration::Provider::HookController
|
|
requires_provider ::DiscourseChatIntegration::Provider::TelegramProvider::PROVIDER_NAME
|
|
|
|
before_action :telegram_token_valid?, only: :command
|
|
|
|
skip_before_action :check_xhr,
|
|
:preload_json,
|
|
:verify_authenticity_token,
|
|
:redirect_to_login_if_required,
|
|
only: :command
|
|
|
|
def command
|
|
|
|
# If it's a new message (telegram also sends hooks for other reasons that we don't care about)
|
|
if params.key?('message')
|
|
chat_id = params['message']['chat']['id']
|
|
|
|
message_text = process_command(params['message'])
|
|
|
|
if message_text.present?
|
|
message = {
|
|
chat_id: chat_id,
|
|
text: message_text,
|
|
parse_mode: "html",
|
|
disable_web_page_preview: true,
|
|
}
|
|
|
|
DiscourseChatIntegration::Provider::TelegramProvider.sendMessage(message)
|
|
end
|
|
|
|
elsif params.dig('channel_post', 'text')&.include?('/getchatid')
|
|
chat_id = params['channel_post']['chat']['id']
|
|
|
|
message_text = I18n.t(
|
|
"chat_integration.provider.telegram.unknown_chat",
|
|
site_title: CGI::escapeHTML(SiteSetting.title),
|
|
chat_id: chat_id,
|
|
)
|
|
|
|
message = {
|
|
chat_id: chat_id,
|
|
text: message_text,
|
|
parse_mode: "html",
|
|
disable_web_page_preview: true,
|
|
}
|
|
|
|
DiscourseChatIntegration::Provider::TelegramProvider.sendMessage(message)
|
|
end
|
|
|
|
# Always give telegram a success message, otherwise we'll stop receiving webhooks
|
|
data = {
|
|
success: true
|
|
}
|
|
render json: data
|
|
end
|
|
|
|
def process_command(message)
|
|
return unless message['text'] # No command to be processed
|
|
|
|
chat_id = params['message']['chat']['id']
|
|
|
|
provider = DiscourseChatIntegration::Provider::TelegramProvider::PROVIDER_NAME
|
|
|
|
channel = DiscourseChatIntegration::Channel.with_provider(provider).with_data_value('chat_id', chat_id).first
|
|
|
|
text_key = if channel.nil?
|
|
"unknown_chat"
|
|
elsif !SiteSetting.chat_integration_telegram_enable_slash_commands || !message['text'].start_with?('/')
|
|
"silent"
|
|
else
|
|
""
|
|
end
|
|
|
|
return "" if text_key == "silent"
|
|
|
|
if text_key.present?
|
|
return I18n.t(
|
|
"chat_integration.provider.telegram.#{text_key}",
|
|
site_title: CGI::escapeHTML(SiteSetting.title),
|
|
chat_id: chat_id,
|
|
)
|
|
end
|
|
|
|
tokens = message['text'].split(" ")
|
|
|
|
tokens[0][0] = '' # Remove the slash from the first token
|
|
tokens[0] = tokens[0].split('@')[0] # Remove the bot name from the command (necessary for group chats)
|
|
|
|
::DiscourseChatIntegration::Helper.process_command(channel, tokens)
|
|
end
|
|
|
|
def telegram_token_valid?
|
|
params.require(:token)
|
|
|
|
if SiteSetting.chat_integration_telegram_secret.blank? ||
|
|
SiteSetting.chat_integration_telegram_secret != params[:token]
|
|
|
|
raise Discourse::InvalidAccess.new
|
|
end
|
|
end
|
|
end
|
|
|
|
class TelegramEngine < ::Rails::Engine
|
|
engine_name DiscourseChatIntegration::PLUGIN_NAME + "-telegram"
|
|
isolate_namespace DiscourseChatIntegration::Provider::TelegramProvider
|
|
end
|
|
|
|
TelegramEngine.routes.draw do
|
|
post "command/:token" => "telegram_command#command"
|
|
end
|
|
end
|