node-red-contrib-telegrambot
Version:
533 lines (467 loc) • 26 kB
HTML
<!-- Created by Karl-Heinz Wind -->
<!-- ------------------------------------------------------------------------------------------ -->
<script type="text/javascript">
RED.nodes.registerType('telegram bot', {
category: 'config',
defaults: {
botname: { value: "", required: true },
usernames: { value: "", required: false },
chatids: { value: "", required: false },
baseapiurl: { value: "", required: false },
updatemode: { value: "polling", required: true },
// only for polling mode
pollinterval: { value: 300, required: false, validate:function(v) { return ((v === "") || (RED.validators.number(v) && (v >= 0) && (v <= 2147483))) }},
// only for socks5 proxy support
usesocks: { value: false, required: false },
sockshost: { value: "", required: false },
socksport: { value: 6667, required: false, validate:function(v) { return ((v === "") || (RED.validators.number(v) && (v >= 0) && (v <= 2147483))) }},
socksusername: { value: "anonymous", required: false },
sockspassword: { value: "", required: false },
// only for webhook mode
bothost: { value: "", required: false },
localbotport: { value: 8443, required: false, validate:function(v) { return ((v === "") || (RED.validators.number(v) && (v >= 0) && (v <= 2147483))) }},
publicbotport: { value: 8443, required: false, validate:function(v) { return ((v === "") || (RED.validators.number(v) && (v >= 0) && (v <= 2147483))) }},
// only for webhook and certificate
privatekey: { value: "", required: false },
certificate: { value: "", required: false },
useselfsignedcertificate: { value: false, required: false },
verboselogging: { value: false, required: false }
},
credentials: {
token: { type: "text" }
},
label: function () {
return this.botname;
},
oneditprepare: function() {
// polling or webhook
var updateOptions = function() {
var mode = $("#node-config-input-updatemode").val();
if (mode == "webhook") {
$("#webhook").show();
$("#polling").hide();
} else if (mode == "polling"){
$("#webhook").hide();
$("#polling").show();
} else {
// option not supported
}
};
updateOptions();
$("#node-config-input-updatemode").change(updateOptions);
// socks5 on / off
var useSocks5 = function() {
var mode = $("#node-config-input-usesocks").prop('checked');
if (mode === false) {
$("#socks").hide();
} else {
$("#socks").show();
}
};
useSocks5();
$("#node-config-input-usesocks").change(useSocks5);
}
});
</script>
<script type="text/x-red" data-template-name="telegram bot">
<div class="form-row" style="min-width: 700px">
<div class="form-row">
<label for="node-config-input-botname"><i class="fa fa-telegram"></i> Bot-Name</label>
<input type="text" id="node-config-input-botname" placeholder="(Name of bot to connect to)">
</div>
<div class="form-row">
<label for="node-config-input-token"><i class="fa fa-key"></i> Token</label>
<input type="text" id="node-config-input-token" placeholder="(Enter the bot token from botfather here)">
</div>
<hr align="middle"/>
<div class="form-row">
<label for="node-config-input-usernames"><i class="fa fa-user"></i> Users</label>
<input type="text" id="node-config-input-usernames" placeholder="(Optional list of authorized user names e.g.: hugo,sepp,egon)">
</div>
<div class="form-row">
<label for="node-config-input-chatids"><i class="fa fa-comment"></i> ChatIds</label>
<input type="text" id="node-config-input-chatids" placeholder="(Optional list of authorized chat-ids e.g.: -1234567,2345678,-3456789)">
</div>
<div class="form-row">
<label for="node-config-input-baseapiurl"><i class="fa fa-server"></i> Server URL</label>
<input type="text" id="node-config-input-baseapiurl" placeholder="(Optional URL for proxying and testing e.g.: https://api.telegram.org)">
</div>
<div class="form-row">
<label for="node-config-input-updatemode"><i class="fa fa-link"></i> Update Mode</label>
<select id="node-config-input-updatemode">
<option value="polling">Polling</option>
<option value="webhook">Webhook</option>
</select>
</div>
<hr align="middle"/>
<div class="form-row hidden" id="polling" style="background: #fbfbfb">
<label style="width: auto"><i class="fa fa-cogs"></i> Polling Options:</label>
<div class="form-row" style="margin-left: 20px">
<div class="form-row">
<label for="node-config-input-pollinterval"><i class="fa fa-clock-o"></i> Poll Interval</label>
<input type="text" id="node-config-input-pollinterval" placeholder="(Optional poll interval in milliseconds. The default is 300.)">
</div>
</div>
<div class="form-tips" style="width: auto"><b>Tip:</b> Polling mode is very robust and easy to set up. Nevertheless it creates more traffic on the network over time.</div>
</div>
<div class="form-row hidden" id="webhook" style="background: #fbfbfb">
<label style="width: auto"><i class="fa fa-cogs"></i> Webhook Options:</label>
<div class="form-row" style="margin-left: 20px">
<div class="form-row">
<label for="node-config-input-bothost"><i class="fa fa-desktop"></i> Bot Host</label>
<input type="text" id="node-config-input-bothost" placeholder="(Optional public IP or hostname of your bot when using webhook. e.g.: mybot.domain.com)">
</div>
<div class="form-row">
<label for="node-config-input-publicbotport"><i class="fa fa-random"></i> Public Bot Port</label>
<input type="text" id="node-config-input-publicbotport" placeholder="(Optional public port for your bot when using webhook. The default is 8443.)">
</div>
<div class="form-row">
<label for="node-config-input-localbotport"><i class="fa fa-random"></i> Local Bot Port</label>
<input type="text" id="node-config-input-localbotport" placeholder="(Optional local port for your bot when using webhook. The default is 8443.)">
</div>
<div class="form-row">
<label for="node-config-input-privatekey"><i class="fa fa-id-card"></i> Private Key</label>
<input type="text" id="node-config-input-privatekey" placeholder="(Optional local path to your private key file. e.g.: C:\temp\\key.pem)">
</div>
<div class="form-row">
<label for="node-config-input-certificate"><i class="fa fa-id-card-o"></i> Certificate</label>
<input type="text" id="node-config-input-certificate" placeholder="(Optional local path to your certificate file. e.g.: C:\temp\\crt.pem)">
</div>
<div class="form-row">
<label for="node-config-input-useselfsignedcertificate"><i class="fa fa-pencil"></i> Certificate is self-signed</label>
<input type="checkbox" id="node-config-input-useselfsignedcertificate" style="display: inline-block; width: auto; vertical-align: top;">
</div>
<div class="form-tips" style="width: auto"><b>Tip:</b> Webhook mode requires a HTTPS certificate. The certificate can also be a self-signed (=custom) one. If any of the host, key, certificate properties is left blank the bot will default to polling mode.</div>
</div>
</div>
<hr align="middle"/>
<div class="form-row">
<label for="node-config-input-usesocks"><i class="fa fa-lock"></i> Use SOCKS5</label>
<input type="checkbox" id="node-config-input-usesocks" style="display: inline-block; width: auto; vertical-align: top;">
</div>
<div class="form-row hidden" id="socks" style="background: #fbfbfb">
<label style="width: auto"><i class="fa fa-cogs"></i> SOCKS5 Options:</label>
<div class="form-row" style="background: #fff; margin-left: 20px">
<div class="form-row">
<label for="node-config-input-sockshost"><i class="fa fa-desktop"></i> Host</label>
<input type="text" id="node-config-input-sockshost" placeholder="(Optional IP or hostname of the socks proxy when using polling mode.)">
</div>
<div class="form-row">
<label for="node-config-input-socksport"><i class="fa fa-random"></i> Port</label>
<input type="text" id="node-config-input-socksport" placeholder="(Optional port of the socks proxy when using polling mode.)">
</div>
<div class="form-row">
<label for="node-config-input-socksusername"><i class="fa fa-user"></i> Username</label>
<input type="text" id="node-config-input-socksusername" placeholder="(Optional username of the socks proxy when using polling mode.)">
</div>
<div class="form-row">
<label for="node-config-input-sockspassword"><i class="fa fa-key"></i> Password</label>
<input type="text" id="node-config-input-sockspassword" placeholder="(Optional password of the socks proxy when using polling mode.)">
</div>
</div>
<div class="form-tips" style="width: auto"><b>Tip:</b> SOCKS5 support is optional can can only be used with a valid proxy server, port, username and password.</div>
</div>
<hr align="middle"/>
<div class="form-row">
<label for="node-config-input-verboselogging"><i class="fa fa-search"></i> Verbose Logging</label>
<input type="checkbox" id="node-config-input-verboselogging" style="display: inline-block; width: auto; vertical-align: top;">
</div>
<div class="form-tips" style="width: auto"><b>Tip:</b> When verbose logging is turned on additional log messages will be printed to the node-red console.</div>
<hr align="middle"/>
</div>
</script>
<script type="text/x-red" data-help-name="telegram bot">
<p>A configuration node that holds the token of the telegram bot.</p>
<h3>Details</h3>
<p>It communicates with the telegram server. Do not create several configurations nodes with the same token!</p>
<p>The usernames and chat ids properties can be used to limit authorization to the bot. Enter values in comma separated format e.g. a,b,c</p>
<p>Usernames and chat ids are optional. Leave field blank if you do not want to use this feature.</p>
<p>The API Base URL can be changed for testing or when using a proxy.</p>
<p>You can enable verbose logging to get more details when debugging, but keep in mind that whis could fill your log file very rapidly.</p>
<p></p>
<h3>Operation Modes: Polling vs Webhook</h3>
<p>By default the bot polls the telegram api server every 300ms. But you can also create a webhook so that the telegram server sends updates via HTTPS POST directly to your host machine.</p>
<p>You can enable the webhook by providing the required data:</p>
<p>- private key</p>
<p>- public key</p>
<p>- the publicly reachable IP or hostname of your bot</p>
<p>- the public port (e.g.: 8443, 443, ...)</p>
<p>- the local port (e.g.: 8443. This value is only different to the public port when you are behind a router that maps ports from public to private ones) </p>
<p></p>
<h3>References</h3>
<p>See also </p>
<p>https://core.telegram.org/bots/webhooks</p>
<p>https://stackoverflow.com/questions/42713926/what-is-easy-way-to-create-and-use-a-self-signed-certification-for-a-telegram-we</p>
<p>One common pitfall when creating certificates that don't work is that the value CN you provided to openssl must match the bots domain name: see "bot host" above. </p>
</script>
<!-- ------------------------------------------------------------------------------------------ -->
<script type="text/javascript">
RED.nodes.registerType('telegram receiver', {
category: 'telegram',
color: '#3BABDD',
defaults: {
name: { value: "" },
bot: { value:"", type: "telegram bot", required: true },
saveDataDir: { value: "" }
},
inputs: 0,
outputs: 2,
icon: "telegram.png",
paletteLabel: "receiver",
label: function () {
return this.name || "Telegram receiver";
},
labelStyle: function() {
return this.name?"node_label_italic":"";
}
});
</script>
<script type="text/x-red" data-template-name="telegram receiver">
<div class="form-row">
<label for="node-input-bot"><i class="fa fa-telegram"></i> Bot</label>
<input type="text" id="node-input-bot" placeholder="Bot">
</div>
<div class="form-row">
<label for="node-input-saveDataDir"><i class="fa fa-hdd-o"></i> Download Directory</label>
<input type="text" id="node-input-saveDataDir" placeholder="Download directory">
</div>
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Name">
</div>
</script>
<script type="text/x-red" data-help-name="telegram receiver">
<p>A telegram node that triggers the output when some message is received from the chat.</p>
<p>The node receives all messages polled from/sent by the telegram server.</p>
<h3>Outputs</h3>
<p>1. Standard Ouput: Message is sent to output 1 if it is from an authorized user.</p>
<p>2. Unauthorized Output: Message is sent to output 2 if it is from a non-authorized user.</p>
<h3>Details</h3>
<p><code>msg.payload</code> typically contains the parsed data as follows:</p>
<ul>
<li><code>content</code> the message contents</li>
<li><code>type</code> the type of message contents</li>
<li><code>messageId</code> the messageId number</li>
<li><code>chatId</code> the chatId number</li>
</ul>
<p>Other properties may be present depending on the type of message.</p>
<code>msg.originalMessage</code> contains the raw data object from the underlying library,
and contains many useful properties.</p>
</script>
<!-- ------------------------------------------------------------------------------------------ -->
<script type="text/javascript">
RED.nodes.registerType('telegram command', {
category: 'telegram',
color: '#3BABDD',
defaults: {
name: { value: "" },
command: { value: ""},
bot: { value: "", type: "telegram bot", required: true },
strict : { value: false }
},
inputs: 0,
outputs: 2,
icon: "telegramc.png",
paletteLabel: "command",
label: function () {
return this.name || this.command || "Telegram command";
},
labelStyle: function() {
return this.name?"node_label_italic":"";
}
});
</script>
<script type="text/x-red" data-template-name="telegram command">
<div class="form-row">
<label for="node-input-command"><i class="fa fa-envelope"></i> Command</label>
<input type="text" id="node-input-command" placeholder="Command">
</div>
<div class="form-row">
<label for="node-input-bot"><i class="fa fa-telegram"></i> Bot</label>
<input type="text" id="node-input-bot" placeholder="Bot">
</div>
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Name">
</div>
<div class="form-row">
<label for="node-input-strict"><i class="fa fa-tag"></i> Strict in group chats</label>
<input type="checkbox" id="node-input-strict" style="display: inline-block; width: auto; vertical-align: top;">
</div>
</script>
<script type="text/x-red" data-help-name="telegram command">
<p>A telegram node that triggers the output when a specified command is received from the chat.</p>
<h3>Outputs</h3>
<p>1. Standard Ouput: Message is sent to output 1 if it is from an authorized user and it contains the command at the beginning of the message.</p>
<p>2. Error Ouput: Message is sent to output 2 if it is from an authorized user but does not contain the specified command.</p>
</script>
<!-- ------------------------------------------------------------------------------------------ -->
<script type="text/javascript">
RED.nodes.registerType('telegram event', {
category: 'telegram',
color: '#3BABDD',
defaults: {
name: { value: "" },
bot: { value: "", type: "telegram bot", required: true },
event: { value: "callback_query", required: true },
autoanswer: { value: false, required: false }
},
inputs: 0,
outputs: 1,
icon: "telegram.png",
paletteLabel: "event",
label: function () {
return this.name || this.event;
},
labelStyle: function() {
return this.name?"node_label_italic":"";
}
});
</script>
<script type="text/x-red" data-template-name="telegram event">
<div class="form-row">
<label for="node-input-bot"><i class="fa fa-telegram"></i> Bot</label>
<input type="text" id="node-input-bot" placeholder="Bot">
</div>
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Name">
</div>
<div class="form-row">
<label for="node-input-event"><i class="fa fa-mail-reply-all"></i> Event</label>
<div style="display: inline-block; position: relative; width: 70%; height: 19.1333px;">
<div style="position: absolute; left: 0; right: 0;">
<select id="node-input-event" style="width:100%">
<option value="callback_query">Callback Query</option>
<option value="inline_query">Inline Query</option>
<option value="edited_message">Edited Message</option>
<option value="edited_message_text">Edited Message Text</option>
<option value="edited_message_caption">Edited Message Caption</option>
<option value="channel_post">Channel Post</option>
<option value="edited_channel_post">Edited Channel Post</option>
<option value="edited_channel_post_text">Edited Channel Post Text</option>
<option value="edited_channel_post_caption">Edited Channel Post Caption</option>
</select>
</div>
</div>
</div>
<div class="form-row">
<label for="node-input-autoanswer"><i class="fa fa-retweet"></i> Auto-Answer</label>
<input type="checkbox" id="node-input-autoanswer" style="display:inline-block; width:auto; vertical-align:top;">
</div>
</script>
<script type="text/x-red" data-help-name="telegram event">
<p>A telegram node that triggers the output when a event is received from a chat.</p>
<h3>Outputs</h3>
<p>1. Standard Output: The output is triggered when the configured event was received.</p>
<h3>Details</h3>
<p>The event type can be selected.</p>
<p><code>msg.payload</code> typically contains the parsed data as follows:</p>
<ul>
<li><code>chatId</code>Unique identifier for this chat.</li>
<li><code>messageId</code>Message identifier.</li>
<li><code>type</code>event type</li>
<li><code>date</code>timestamp</li>
<li><code>content</code>the actual UTF-8 text of the message</li>
</ul>
<p>Other properties may be present depending on the type of message.</p>
<code>msg.originalMessage</code> contains the raw data object from the underlying library,
and contains many useful properties.</p>
<p>The autoanswer checkbox can be set for callback_query.</p>
<p>Then you won't have to send an explicit answer to the bot on your own.</p>
</script>
<!-- ------------------------------------------------------------------------------------------ -->
<script type="text/javascript">
RED.nodes.registerType('telegram sender', {
category: 'telegram',
color: '#3BABDD',
defaults: {
name: { value: "" },
bot: { value: "", type: "telegram bot", required: true }
},
inputs: 1,
outputs: 1,
icon: "telegram.png",
align: "right",
paletteLabel: "sender",
label: function () {
return this.name || "Telegram sender";
},
labelStyle: function() {
return this.name?"node_label_italic":"";
}
});
</script>
<script type="text/x-red" data-template-name="telegram sender">
<div class="form-row">
<label for="node-input-bot"><i class="fa fa-telegram"></i> Bot</label>
<input type="text" id="node-input-bot" placeholder="Bot">
</div>
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Name">
</div>
</script>
<script type="text/x-red" data-help-name="telegram sender">
<p>A telegram node that sends the <code>msg.payload</code> to the chat.</p>
<h3>Inputs</h3>
<p>1. Standard Input: receives a message object containing the chatId. It can be directly connected to the receiver node's output 1.</p>
<h3>Details</h3>
<p>The <code>msg.payload</code> must be an object that contains a complete set of telegram message properties,
at a minimum these should contain:
<ul>
<li><code>content</code> the message contents</li>
<li><code>type</code> the type of message contents</li>
<li><code>chatId</code> the chatId number</li>
</ul>
<p>The output message contains an error property if an exception occured.</p>
</script>
<!-- ------------------------------------------------------------------------------------------ -->
<!-- ------------------------------------------------------------------------------------------ -->
<script type="text/javascript">
RED.nodes.registerType('telegram reply', {
category: 'telegram',
color: '#3BABDD',
defaults: {
name: { value: "" },
bot: { value: "", type: "telegram bot", required: true }
},
inputs: 1,
outputs: 1,
icon: "telegram.png",
align: "right",
paletteLabel: "reply",
label: function () {
return this.name || "Telegram reply";
},
labelStyle: function() {
return this.name?"node_label_italic":"";
}
});
</script>
<script type="text/x-red" data-template-name="telegram reply">
<div class="form-row">
<label for="node-input-bot"><i class="fa fa-telegram"></i> Bot</label>
<input type="text" id="node-input-bot" placeholder="Bot">
</div>
<div class="form-row">
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Name">
</div>
</script>
<script type="text/x-red" data-help-name="telegram reply">
<p>A telegram node that is triggered when someone answered to a specified message.</p>
<h3>Inputs</h3>
<p>1. Standard Input: calls the onReplyToMessage of the bot.</p>
<h3>Outputs</h3>
<p>1. Standard Output: contains the result from the onReplyToMessage call.</p>
<h3>Details</h3>
<p>This can be useful, when the bot for example sent a message and you want to take some action</p>
<p>when someone responded to this specified message.</p>
<p>Responding to messages is done by clicking on the message in your client and choose "answer" from the popup.</p>
<p>The <code>msg.payload</code> should be an object that contains:</p>
<ul><li><code>chatId</code> destination chatId.</li>
<li><code>sentMessageId</code> the id of the previously sent message in the chat.</li>
<li><code>content</code> the message content.</li></ul>
</script>
<!-- ------------------------------------------------------------------------------------------ -->