Skip to content

Commit

Permalink
Add linking and update bridge
Browse files Browse the repository at this point in the history
  • Loading branch information
dmytrohoi committed Sep 12, 2020
1 parent 38e422b commit d7c43c2
Show file tree
Hide file tree
Showing 3 changed files with 190 additions and 57 deletions.
63 changes: 41 additions & 22 deletions tg-bridge.pyplugin/config.yml
Original file line number Diff line number Diff line change
@@ -1,33 +1,52 @@
# TelegramBridge v0.0.2 (on PyPlugins https://github.com/pyplugins/pyplugins)
# TelegramBridge v0.1.0 (on PyPlugins https://github.com/pyplugins/pyplugins)
# Link: https://github.com/dmytrohoi/tg-bridge-pyplugin
#
# NOTE: Reload config after changing - /tg-bridge-config reload

## WARNING: Required fields
# Telegram token (https://core.telegram.org/bots#6-botfather)
TOKEN:

## Bridge between Minecraft chat and Telegram group
# Server chat Telegram ID (https://stackoverflow.com/questions/32423837/telegram-bot-how-to-get-a-group-chat-id)
CHAT_ID:
bridge:
# Bridge can be disabled but allow notifications (chat_id required)
enable: false
chat_id:

## TEMPLATES NOTE:
# - available HTML tag (https://core.telegram.org/bots/api#html-style)
# - encode <, > and & symbols to HTML entities - < with &lt;, > with &gt; and & with &amp;
# - use <br/> for newline (aka \n)
# - placeholders: {message_text} and {username} (WARNING: only for outcoming_msg_template and outcoming_msg_broadcast_template)
# - Minecraft formating is available for outcoming_msg_broadcast_template and incoming_msg_template (https://minecraft.gamepedia.com/Formatting_codes)
outcoming_msg_template: '<b>MINECRAFT &lt;{username}&gt;</b>:<br/>{message_text}'
outcoming_msg_broadcast_template: '[ §5Telegram Chat§r §5§l<<§r ] <{username}> {message_text}'
incoming_msg_template: '[ §5Telegram Chat§r §5§l>>§r ] {message_text}'
## TEMPLATES
# - available HTML tag (https://core.telegram.org/bots/api#html-style)
# - encode <, > and & symbols to HTML entities - < with &lt;, > with &gt; and & with &amp;
# - use <br/> for newline (aka \n)
# - placeholders: {message_text} and {username} (WARNING: only for outcoming_msg_template and outcoming_msg_broadcast_template)
# - Minecraft formating is available for outcoming_msg_broadcast_template and incoming_msg_template (https://minecraft.gamepedia.com/Formatting_codes)
outcoming_msg_template: '<b>MINECRAFT &lt;{username}&gt;</b>:<br/>{message_text}'
outcoming_msg_broadcast_template: '[ §5Telegram Chat§r §5§l<<§r ] <{username}> {message_text}'
incoming_msg_template: '[ §5Telegram Chat§r §5§l>>§r ] {message_text}'

## Notifications
# The message will be sent to the Telegram chat when the Server starts or shuts down
# Placeholders:
# {ip} - Server IP and Port
# {motd} - Server MOTD
startup_notification:
enable: true
template: "Server {ip} started!"
shutdown_notification:
enable: true
template: "Server {ip} closed."

## Notifications
# The message will be sent to the Telegram chat when the Server starts or shuts down
# Placeholders:
# {ip} - Server IP and Port
# {motd} - Server MOTD
startup_notification:
enable: true
template: "Server {ip} started!"
shutdown_notification:
enable: true
template: "Server {ip} closed."
## LINKING
# Please implement catching of the inline button in your Telegram Bot
# Button callback_data format: tcp:link:{user_code}
linking:
enable: false
## Formatting
# - available HTML tag (https://core.telegram.org/bots/api#html-style)
# - encode <, > and & symbols to HTML entities - < with &lt;, > with &gt; and & with &amp;
# - use <br/> for newline (aka \n)
# - placeholders: {username}
message_text_template: "Player with username <b>{username}</b> try to link Minecraft account to this Telegram account"
button_text: "Confirm"
# - please set userid as first parameter in code and separate by ":"
code_validation_regexp: \d+
177 changes: 143 additions & 34 deletions tg-bridge.pyplugin/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,54 @@
"""
Plugin: TelegramBridge (https://github.com/dmytrohoi/tg-bridge-pyplugin)
File: plugin.py
Version: 0.0.2
Version: 0.1.0
Author: hedgehoi (Dmytro Hoi)
License: MIT License
Dependencies:
- PyPlugins v0.0.1 / https://github.com/pyplugins/pyplugins
- PyPlugins >0.0.1 / https://github.com/pyplugins/pyplugins
"""
import urllib
import json
import re


class TelegramChatCommands(PythonCommandExecutor):
commands = [
PyCommand('telegram', 'telegramCommand', 'telegramOnTabComplete'),
PyCommand('telegram-chat-response', 'responseCommand', 'telegramOnTabComplete')
PyCommand('telegram-chat-response', 'responseCommand', 'telegramOnTabComplete'),
PyCommand('link', 'linkCommand', 'linkOnTabComplete')
]

def telegramCommand(self, sender, command, label, args):

sender_name = sender.getName()
message_text = " ".join(args)
self.plugin.logger.info('{sender} try to send message to Telegram: {message}'.format(
sender=sender_name,
message=message_text
))

bridge_section = self.plugin.config.get("bridge")
if not bridge_section \
or not bridge_section.getBoolean("enable") \
or not bridge_section.getString("chat_id"):
sender.sendMessage(
self.plugin.placeholder
+ " Bridge disabled."
)
self.plugin.logger.info('Bridge disabled.')
return True

if not message_text:
sender.sendMessage(
self.plugin.placeholder
+ " Please add text to command, for example: /telegram Test"
)
return True

self.plugin.logger.info('{sender} try to send message to Telegram: {message}'.format(
sender=sender_name,
message=message_text
))

template = self.plugin.config.getString(
template = bridge_section.getString(
'outcoming_msg_template',
"{message_text}"
)
Expand All @@ -55,7 +70,7 @@ def telegramCommand(self, sender, command, label, args):
+ " Message sent to Telegram Chat."
)

bc_message = self.plugin.config.getString(
bc_message = bridge_section.getString(
'outcoming_msg_broadcast_template',
"[ Telegram Chat << ] <{username}> {message_text}"
).format(
Expand Down Expand Up @@ -91,13 +106,21 @@ def responseCommand(self, sender, command, label, args):
)
)

bc_message = self.plugin.config.getString(
bridge_section = self.plugin.config.get("bridge")
if not bridge_section or not bridge_section.getBoolean("enable"):
self.plugin.logger.info('Bridge not enabled.')
return True

bc_message = bridge_section.getString(
"incoming_msg_template",
"[ Telegram Chat >> ] {message_text}"
).format(message_text=message_text)

Bukkit.getServer().broadcastMessage(bc_message)
sender.sendMessage(self.plugin.placeholder + " Message sent to Minecraft Chat.")
sender.sendMessage(
self.plugin.placeholder
+ " Message sent to Minecraft Chat."
)
return True

def telegramOnTabComplete(self, sender, command, alias, args):
Expand All @@ -106,6 +129,65 @@ def telegramOnTabComplete(self, sender, command, alias, args):
else:
return []

def linkCommand(self, sender, command, label, args):
section = self.plugin.config.get("linking")
if not section or not section.getBoolean("enable"):
sender.sendMessage(self.plugin.placeholder + " Linking disabled.")
return True

if sender.getName() == "CONSOLE":
sender.sendMessage(self.plugin.placeholder + " Command only for player in-game usage")
return True

if len(args) > 1:
sender.sendMessage(
self.plugin.placeholder + " You sent more than 1 argument with /link command"
)
return True
elif not len(args):
sender.sendMessage(
self.plugin.placeholder + " To connect Minecraft account and "\
"Telegram account please go to Server's Telegram bot and "\
"perform /link command to get start!"
)
return True

# User code
code = args[0]

self.plugin.logger.info(
'{player} try to link Minecraft account to Telegram user with code: {code}'.format(
player=sender.getName(),
code=code
)
)

text = section.getString(
"message_text_template",
"Player with username <b>{username}</b> try to link Minecraft account to this Telegram account"
).format(
username=sender.getName()
)

#Validate code
validation_regex = section.getString("code_validation_regexp")
if validation_regex and not re.match(r'^' + validation_regex + r'$', code):
sender.sendMessage(self.plugin.placeholder + " Invalid code, please check code or call Server Admin.")
return True

result = self.plugin.sendTelegramMessage(text, button_confirm_code=code)
if result:
sender.sendMessage(self.plugin.placeholder + " Please check your Telegram dialog and confirm linking.")
else:
sender.sendMessage(self.plugin.placeholder + " Somethink went wrong, please check code or call Server Admin.")
return True

def linkOnTabComplete(self, sender, command, alias, args):
if len(args) == 1:
return ['<telegram bot code>']
else:
return []


class TelegramBridgePlugin(PythonPlugin):

Expand All @@ -117,13 +199,7 @@ def onEnable(self):

# Add bStats metrics
self.add_bstats(8809)
self.add_configuration(
available_options=[
"outcoming_msg_template",
"outcoming_msg_broadcast_template",
"incoming_msg_template"
]
)
self.add_configuration()
self.logger.info("plugin enabled!")

bot_token = self.config.getString('TOKEN')
Expand All @@ -133,24 +209,25 @@ def onEnable(self):
"Plugin is not configured, please set TOKEN in config.yml"
)

chat_id = self.config.getString('CHAT_ID')
if not chat_id:
self.logger.warning(
"Plugin is not configured, please set CHAT_ID in config.yml"
)
# Startup notification
self.notification("startup_notification")
bridge = self.config.get('bridge')
if not bridge or not bridge.getString("chat_id"):
self.logger.warning("Bridge disabled in config.yml")
else:
# Startup notification
self.notification("startup_notification")

def onDisable(self):
# Shutdown notification
self.notification("shutdown_notification")
bridge = self.config.get('bridge')
if bridge and bridge.getString("chat_id"):
self.notification("shutdown_notification")

self.logger.info("plugin disabled!")

def notification(self, name):
section = self.config.get(name)
section = self.config.get("bridge").get(name)
if not section or (section and not section.getBoolean('enable')):
self.logger.info("{} skipped".format(name))
self.logger.info("{} disabled.".format(name.replace("_", " ").capitalize()))
return

self.logger.info("{} option is enabled!".format(name))
Expand All @@ -172,25 +249,57 @@ def notification(self, name):
)
self.sendTelegramMessage(text)

def sendTelegramMessage(self, text):
def sendTelegramMessage(self, text, button_confirm_code=None):

chat_id = self.config.getString('CHAT_ID')
bot_token = self.config.getString('TOKEN')

if not chat_id or not bot_token:
if not bot_token:
self.logger.warning(
"Plugin is not configured, please set CHAT_ID and TOKEN in "
"Plugin is not configured, please set TOKEN in "
"config.yml"
)
return False

# Make data query for url
data_options = {
'text': text,
'chat_id': chat_id,
'parse_mode': 'HTML'
}

# Link command
if button_confirm_code:
# Default button text
confirm_button_text = "Confirm linking"

# Check config
linking_section = self.config.get('linking')
if linking_section and linking_section.getString("button_text"):
confirm_button_text = linking_section.getString("button_text")

data_options['reply_markup'] = json.dumps({
"inline_keyboard": [
[{
"text": confirm_button_text,
"callback_data": "tcp:link:" + button_confirm_code
}]
]
})
user_id = button_confirm_code.split(":")[0] if ":" in button_confirm_code else button_confirm_code
if user_id.startswith("-"):
return False

data_options["chat_id"] = user_id
else:
bridge_section = self.config.get('bridge')
if not bridge_section or not bridge_section.getString('chat_id'):
self.logger.warning(
"Bridge is not configured, please set 'bridge' > 'chat_id' in "
"config.yml"
)
return False

data_options["chat_id"] = bridge_section.getString('chat_id')

# Replace "<br/>" to new line char
data = urllib.urlencode(data_options).replace("%3Cbr%2F%3E", "%0A")
telegramRequestURL = "https://api.telegram.org/bot{bot_token}/sendMessage?{data}".format(
Expand Down
7 changes: 6 additions & 1 deletion tg-bridge.pyplugin/plugin.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: TelegramBridge
main: TelegramBridgePlugin
prefix: tg-bridge
version: 0.0.2
version: 0.1.0
author: hedgehoi
website: https://github.com/dmytrohoi/tg-bridge-pyplugin
commands:
Expand All @@ -19,3 +19,8 @@ commands:
description: Plugin settings
aliases: [tg-config, telegram-config]
permission: minecraft.command.op

link:
description: Link Minecraft account to Telegram account
aliases: tg-link
usage: /&lt;command&gt; &lt;telegram code&gt;

0 comments on commit d7c43c2

Please sign in to comment.