first commit

This commit is contained in:
borovlioff 2023-09-09 00:11:17 +03:00
commit 9c23f9ba86
22 changed files with 2547 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
/auth.js
/database.sqlite
/node_modules

750
package-lock.json generated Normal file
View File

@ -0,0 +1,750 @@
{
"name": "node-red-telegram-account",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "node-red-telegram-account",
"version": "1.0.0",
"license": "MIT",
"dependencies": {
"input": "^1.0.1",
"telegram": "^2.17.10"
}
},
"node_modules/@cryptography/aes": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/@cryptography/aes/-/aes-0.1.1.tgz",
"integrity": "sha512-PcYz4FDGblO6tM2kSC+VzhhK62vml6k6/YAkiWtyPvrgJVfnDRoHGDtKn5UiaRRUrvUTTocBpvc2rRgTCqxjsg=="
},
"node_modules/ansi-escapes": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz",
"integrity": "sha512-wiXutNjDUlNEDWHcYH3jtZUhd3c4/VojassD8zHdHCY13xbZy2XbW+NKQwA0tWGBVzDA9qEzYwfoSsWmviidhw==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/ansi-regex": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
"integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/ansi-styles": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
"integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/async-mutex": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.3.2.tgz",
"integrity": "sha512-HuTK7E7MT7jZEh1P9GtRW9+aTWiDWWi9InbZ5hjxrnRa39KS4BW04+xLBhYNS2aXhHUIKZSw3gj4Pn1pj+qGAA==",
"dependencies": {
"tslib": "^2.3.1"
}
},
"node_modules/babel-runtime": {
"version": "6.26.0",
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
"integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==",
"dependencies": {
"core-js": "^2.4.0",
"regenerator-runtime": "^0.11.0"
}
},
"node_modules/base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
},
"node_modules/big-integer": {
"version": "1.6.51",
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz",
"integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==",
"engines": {
"node": ">=0.6"
}
},
"node_modules/buffer": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"dependencies": {
"base64-js": "^1.3.1",
"ieee754": "^1.2.1"
}
},
"node_modules/bufferutil": {
"version": "4.0.7",
"resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.7.tgz",
"integrity": "sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw==",
"hasInstallScript": true,
"dependencies": {
"node-gyp-build": "^4.3.0"
},
"engines": {
"node": ">=6.14.2"
}
},
"node_modules/chalk": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==",
"dependencies": {
"ansi-styles": "^2.2.1",
"escape-string-regexp": "^1.0.2",
"has-ansi": "^2.0.0",
"strip-ansi": "^3.0.0",
"supports-color": "^2.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/cli-cursor": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz",
"integrity": "sha512-25tABq090YNKkF6JH7lcwO0zFJTRke4Jcq9iX2nr/Sz0Cjjv4gckmwlW6Ty/aoyFd6z3ysR2hMGC2GFugmBo6A==",
"dependencies": {
"restore-cursor": "^1.0.1"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/cli-width": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz",
"integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw=="
},
"node_modules/code-point-at": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
"integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/core-js": {
"version": "2.6.12",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz",
"integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==",
"deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.",
"hasInstallScript": true
},
"node_modules/d": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
"integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==",
"dependencies": {
"es5-ext": "^0.10.50",
"type": "^1.0.1"
}
},
"node_modules/debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"dependencies": {
"ms": "2.0.0"
}
},
"node_modules/dom-serializer": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz",
"integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==",
"dependencies": {
"domelementtype": "^2.0.1",
"domhandler": "^4.2.0",
"entities": "^2.0.0"
},
"funding": {
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
}
},
"node_modules/domelementtype": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
"integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/fb55"
}
]
},
"node_modules/domhandler": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz",
"integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==",
"dependencies": {
"domelementtype": "^2.2.0"
},
"engines": {
"node": ">= 4"
},
"funding": {
"url": "https://github.com/fb55/domhandler?sponsor=1"
}
},
"node_modules/domutils": {
"version": "2.8.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
"integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
"dependencies": {
"dom-serializer": "^1.0.1",
"domelementtype": "^2.2.0",
"domhandler": "^4.2.0"
},
"funding": {
"url": "https://github.com/fb55/domutils?sponsor=1"
}
},
"node_modules/entities": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
"integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/es5-ext": {
"version": "0.10.62",
"resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz",
"integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==",
"hasInstallScript": true,
"dependencies": {
"es6-iterator": "^2.0.3",
"es6-symbol": "^3.1.3",
"next-tick": "^1.1.0"
},
"engines": {
"node": ">=0.10"
}
},
"node_modules/es6-iterator": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
"integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==",
"dependencies": {
"d": "1",
"es5-ext": "^0.10.35",
"es6-symbol": "^3.1.1"
}
},
"node_modules/es6-symbol": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz",
"integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==",
"dependencies": {
"d": "^1.0.1",
"ext": "^1.1.2"
}
},
"node_modules/escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/exit-hook": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz",
"integrity": "sha512-MsG3prOVw1WtLXAZbM3KiYtooKR1LvxHh3VHsVtIy0uiUu8usxgB/94DP2HxtD/661lLdB6yzQ09lGJSQr6nkg==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/ext": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz",
"integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==",
"dependencies": {
"type": "^2.7.2"
}
},
"node_modules/ext/node_modules/type": {
"version": "2.7.2",
"resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz",
"integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw=="
},
"node_modules/figures": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
"integrity": "sha512-UxKlfCRuCBxSXU4C6t9scbDyWZ4VlaFFdojKtzJuSkuOBQ5CNFum+zZXFwHjo+CxBC1t6zlYPgHIgFjL8ggoEQ==",
"dependencies": {
"escape-string-regexp": "^1.0.5",
"object-assign": "^4.1.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/graceful-fs": {
"version": "4.2.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="
},
"node_modules/has-ansi": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
"integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==",
"dependencies": {
"ansi-regex": "^2.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/htmlparser2": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz",
"integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==",
"funding": [
"https://github.com/fb55/htmlparser2?sponsor=1",
{
"type": "github",
"url": "https://github.com/sponsors/fb55"
}
],
"dependencies": {
"domelementtype": "^2.0.1",
"domhandler": "^4.0.0",
"domutils": "^2.5.2",
"entities": "^2.0.0"
}
},
"node_modules/ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
},
"node_modules/imurmurhash": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
"integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
"engines": {
"node": ">=0.8.19"
}
},
"node_modules/input": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/input/-/input-1.0.1.tgz",
"integrity": "sha512-5DKQKQ7Nm/CaPGYKF74uUvk5ftC3S04fLYWcDrNG2rOVhhRgB4E2J8JNb7AAh+RlQ/954ukas4bEbrRQ3/kPGA==",
"dependencies": {
"babel-runtime": "^6.6.1",
"chalk": "^1.1.1",
"inquirer": "^0.12.0",
"lodash": "^4.6.1"
},
"engines": {
"node": ">=0.12"
}
},
"node_modules/inquirer": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz",
"integrity": "sha512-bOetEz5+/WpgaW4D1NYOk1aD+JCqRjqu/FwRFgnIfiP7FC/zinsrfyO1vlS3nyH/R7S0IH3BIHBu4DBIDSqiGQ==",
"dependencies": {
"ansi-escapes": "^1.1.0",
"ansi-regex": "^2.0.0",
"chalk": "^1.0.0",
"cli-cursor": "^1.0.1",
"cli-width": "^2.0.0",
"figures": "^1.3.5",
"lodash": "^4.3.0",
"readline2": "^1.0.1",
"run-async": "^0.1.0",
"rx-lite": "^3.1.2",
"string-width": "^1.0.1",
"strip-ansi": "^3.0.0",
"through": "^2.3.6"
}
},
"node_modules/ip": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz",
"integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ=="
},
"node_modules/is-fullwidth-code-point": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
"integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==",
"dependencies": {
"number-is-nan": "^1.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/is-typedarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
"integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA=="
},
"node_modules/lodash": {
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
"node_modules/mime": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz",
"integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==",
"bin": {
"mime": "cli.js"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
"node_modules/mute-stream": {
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz",
"integrity": "sha512-EbrziT4s8cWPmzr47eYVW3wimS4HsvlnV5ri1xw1aR6JQo/OrJX5rkl32K/QQHdxeabJETtfeaROGhd8W7uBgg=="
},
"node_modules/next-tick": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz",
"integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ=="
},
"node_modules/node-gyp-build": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz",
"integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==",
"bin": {
"node-gyp-build": "bin.js",
"node-gyp-build-optional": "optional.js",
"node-gyp-build-test": "build-test.js"
}
},
"node_modules/node-localstorage": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/node-localstorage/-/node-localstorage-2.2.1.tgz",
"integrity": "sha512-vv8fJuOUCCvSPjDjBLlMqYMHob4aGjkmrkaE42/mZr0VT+ZAU10jRF8oTnX9+pgU9/vYJ8P7YT3Vd6ajkmzSCw==",
"dependencies": {
"write-file-atomic": "^1.1.4"
},
"engines": {
"node": ">=0.12"
}
},
"node_modules/number-is-nan": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
"integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"dependencies": {
"wrappy": "1"
}
},
"node_modules/onetime": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
"integrity": "sha512-GZ+g4jayMqzCRMgB2sol7GiCLjKfS1PINkjmx8spcKce1LiVqcbQreXwqs2YAFXC6R03VIG28ZS31t8M866v6A==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/pako": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz",
"integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug=="
},
"node_modules/path-browserify": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
"integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g=="
},
"node_modules/readline2": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz",
"integrity": "sha512-8/td4MmwUB6PkZUbV25uKz7dfrmjYWxsW8DVfibWdlHRk/l/DfHKn4pU+dfcoGLFgWOdyGCzINRQD7jn+Bv+/g==",
"dependencies": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
"mute-stream": "0.0.5"
}
},
"node_modules/real-cancellable-promise": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/real-cancellable-promise/-/real-cancellable-promise-1.2.0.tgz",
"integrity": "sha512-FYhmx1FVSgoPRjneoTjh+EKZcNb8ijl/dyatTzase5eujYhVrLNDOiIY6AgQq7GU1kOoLgEd9jLVbhFg8k8dOQ=="
},
"node_modules/regenerator-runtime": {
"version": "0.11.1",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
"integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg=="
},
"node_modules/restore-cursor": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz",
"integrity": "sha512-reSjH4HuiFlxlaBaFCiS6O76ZGG2ygKoSlCsipKdaZuKSPx/+bt9mULkn4l0asVzbEfQQmXRg6Wp6gv6m0wElw==",
"dependencies": {
"exit-hook": "^1.0.0",
"onetime": "^1.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/run-async": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz",
"integrity": "sha512-qOX+w+IxFgpUpJfkv2oGN0+ExPs68F4sZHfaRRx4dDexAQkG83atugKVEylyT5ARees3HBbfmuvnjbrd8j9Wjw==",
"dependencies": {
"once": "^1.3.0"
}
},
"node_modules/rx-lite": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz",
"integrity": "sha512-1I1+G2gteLB8Tkt8YI1sJvSIfa0lWuRtC8GjvtyPBcLSF5jBCCJJqKrpER5JU5r6Bhe+i9/pK3VMuUcXu0kdwQ=="
},
"node_modules/slide": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz",
"integrity": "sha512-NwrtjCg+lZoqhFU8fOwl4ay2ei8PaqCBOUV3/ektPY9trO1yQ1oXEfmHAhKArUVUr/hOHvy5f6AdP17dCM0zMw==",
"engines": {
"node": "*"
}
},
"node_modules/smart-buffer": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
"integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
"engines": {
"node": ">= 6.0.0",
"npm": ">= 3.0.0"
}
},
"node_modules/socks": {
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz",
"integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==",
"dependencies": {
"ip": "^2.0.0",
"smart-buffer": "^4.2.0"
},
"engines": {
"node": ">= 10.13.0",
"npm": ">= 3.0.0"
}
},
"node_modules/store2": {
"version": "2.14.2",
"resolved": "https://registry.npmjs.org/store2/-/store2-2.14.2.tgz",
"integrity": "sha512-siT1RiqlfQnGqgT/YzXVUNsom9S0H1OX+dpdGN1xkyYATo4I6sep5NmsRD/40s3IIOvlCq6akxkqG82urIZW1w=="
},
"node_modules/string-width": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
"integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==",
"dependencies": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
"strip-ansi": "^3.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/strip-ansi": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==",
"dependencies": {
"ansi-regex": "^2.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/supports-color": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
"integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==",
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/telegram": {
"version": "2.17.10",
"resolved": "https://registry.npmjs.org/telegram/-/telegram-2.17.10.tgz",
"integrity": "sha512-BeWrH6jrTjtmZtGi63mM2UWwciOivqQknhRIysULVRQkDbo+MW4I2jI6d3sPM5m8Ge9mhjeKg1aVZf2qG4vh2Q==",
"dependencies": {
"@cryptography/aes": "^0.1.1",
"async-mutex": "^0.3.0",
"big-integer": "^1.6.48",
"buffer": "^6.0.3",
"htmlparser2": "^6.1.0",
"mime": "^3.0.0",
"node-localstorage": "^2.2.1",
"pako": "^2.0.3",
"path-browserify": "^1.0.1",
"real-cancellable-promise": "^1.1.1",
"socks": "^2.6.2",
"store2": "^2.13.0",
"ts-custom-error": "^3.2.0",
"websocket": "^1.0.34"
},
"optionalDependencies": {
"bufferutil": "^4.0.3",
"utf-8-validate": "^5.0.5"
}
},
"node_modules/through": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
"integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg=="
},
"node_modules/ts-custom-error": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/ts-custom-error/-/ts-custom-error-3.3.1.tgz",
"integrity": "sha512-5OX1tzOjxWEgsr/YEUWSuPrQ00deKLh6D7OTWcvNHm12/7QPyRh8SYpyWvA4IZv8H/+GQWQEh/kwo95Q9OVW1A==",
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/tslib": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.0.tgz",
"integrity": "sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA=="
},
"node_modules/type": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
"integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg=="
},
"node_modules/typedarray-to-buffer": {
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
"integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
"dependencies": {
"is-typedarray": "^1.0.0"
}
},
"node_modules/utf-8-validate": {
"version": "5.0.10",
"resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.10.tgz",
"integrity": "sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==",
"hasInstallScript": true,
"dependencies": {
"node-gyp-build": "^4.3.0"
},
"engines": {
"node": ">=6.14.2"
}
},
"node_modules/websocket": {
"version": "1.0.34",
"resolved": "https://registry.npmjs.org/websocket/-/websocket-1.0.34.tgz",
"integrity": "sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ==",
"dependencies": {
"bufferutil": "^4.0.1",
"debug": "^2.2.0",
"es5-ext": "^0.10.50",
"typedarray-to-buffer": "^3.1.5",
"utf-8-validate": "^5.0.2",
"yaeti": "^0.0.6"
},
"engines": {
"node": ">=4.0.0"
}
},
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
},
"node_modules/write-file-atomic": {
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.3.4.tgz",
"integrity": "sha512-SdrHoC/yVBPpV0Xq/mUZQIpW2sWXAShb/V4pomcJXh92RuaO+f3UTWItiR3Px+pLnV2PvC2/bfn5cwr5X6Vfxw==",
"dependencies": {
"graceful-fs": "^4.1.11",
"imurmurhash": "^0.1.4",
"slide": "^1.1.5"
}
},
"node_modules/yaeti": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz",
"integrity": "sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug==",
"engines": {
"node": ">=0.10.32"
}
}
}
}

32
package.json Normal file
View File

@ -0,0 +1,32 @@
{
"name": "node-red-telegram-account",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "npm install /home/user/Desktop/node-red-telegram-account -g & node-red"
},
"keywords": [
"node-red",
"telegram"
],
"author": "borovlioff",
"license": "MIT",
"node-red": {
"nodes": {
"config": "sample/config.js",
"receiver": "sample/receiver.js",
"command": "sample/command.js",
"send-message": "sample/send-message.js",
"send-file": "sample/send-file.js",
"entity": "sample/get-entity.js",
"delete-message": "sample/delete-message.js",
"iter-dialog":"sample/iter-dialogs.js",
"iter-messages":"sample/iter-messages.js"
}
},
"dependencies": {
"input": "^1.0.1",
"telegram": "^2.17.10"
}
}

60
sample/command.html Normal file
View File

@ -0,0 +1,60 @@
<script type="text/javascript">
RED.nodes.registerType('command', {
category: 'telegram-account',
color: '#229ED9',
icon: 'tg.png',
align:"right",
defaults: {
name: { value: '' },
config: { type: 'config', required: false },
command: { value: "", required:true },
regex:{ value:false }
},
inputs: 1,
outputs: 1,
label: function () {
return this.name || 'Command';
},
});
</script>
<script type="text/html" data-template-name="command">
<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"
style="width: 60%"
/>
</div>
<div class="form-row">
<label for="node-input-config">
<i class="fa fa-tag"></i> Config
</label>
<input
type="text"
id="node-input-config"
placeholder="Config"
style="width: 60%"
/>
</div>
<div class="form-row">
<label for="node-input-command">
<i class="fa fa-tag"></i> Message
</label>
<input type="text" id="node-input-command" placeholder="Message">
</div>
<div class="form-row">
<label for="regex">
<i class="fa fa-cog"></i><span>Regular expression</span>
</label>
<input type="checkbox" style="display: inline; width: 22px;vertical-align: top;" id="node-input-regex">
</div>
</script>

55
sample/command.js Normal file
View File

@ -0,0 +1,55 @@
const { NewMessage } = require("telegram/events");
// event.js
module.exports = function (RED) {
function Command(config) {
RED.nodes.createNode(this, config);
this.config = RED.nodes.getNode(config.config);
var node = this;
/** @type {TelegramClient} */
const client = this.config.client;
try {
client.addEventHandler((update) => {
const message = update.message.message
if (message) {
if (config.regex) {
const regex = new RegExp(config.command);
if (regex.test(message)) {
// Создаем объект сообщения для отправки в следующий узел
var msg = {
payload: {
update
// Другие поля сообщения, которые вы хотите передать
}
};
// Отправляем объект сообщения в следующий узел
node.send(msg);
}
} else if (message === config.command) {
// Создаем объект сообщения для отправки в следующий узел
var msg = {
payload: {
update
// Другие поля сообщения, которые вы хотите передать
}
};
// Отправляем объект сообщения в следующий узел
node.send(msg);
}
}
}, new NewMessage());
} catch (err) {
node.error('Ошибка авторизации: ' + err.message);
}
}
RED.nodes.registerType('command', Command);
};

131
sample/config.html Normal file
View File

@ -0,0 +1,131 @@
<script type="text/javascript">
RED.nodes.registerType('config',{
category: 'config',
defaults: {
name: { value: '' },
api_id: {value:"", required:true},
api_hash: {value:"", required:true},
session: {value:"", required:true},
useIPV6: {value: undefined},
timeout: {value: undefined},
requestRetries: {value: undefined},
connectionRetries: {value: undefined},
proxy: {value: undefined},
downloadRetries: {value: undefined},
retryDelay: {value: undefined},
autoReconnect: {value: undefined},
sequentialUpdates: {value: undefined},
floodSleepThreshold: {value: undefined},
deviceModel: {value: undefined},
systemVersion: {value: undefined},
appVersion: {value: undefined},
langCode: {value: undefined},
systemLangCode: {value: undefined},
useWSS: {value: undefined},
maxConcurrentDownloads: {value: undefined},
securityChecks: {value: undefined},
testServers: {value: undefined}
},
label: function() {
return this.name || "Telegram Client Config";
},
oneditprepare: function() {
}
});
</script>
<script type="text/html" data-template-name="config">
<div class="form-row">
<label for="node-config-input-name"><i class="icon-tasks"></i>Name</label>
<input type="text" id="node-config-input-name" placeholder="Name" style="width:70%" ng-model="node.api_id">
</div>
<div class="form-row">
<label for="node-config-input-api_id"><i class="icon-tasks"></i> API ID</label>
<input type="text" id="node-config-input-api_id" placeholder="Enter API ID" style="width:70%" ng-model="node.api_id">
</div>
<div class="form-row">
<label for="node-config-input-api_hash"><i class="icon-tasks"></i> API Hash</label>
<input type="text" id="node-config-input-api_hash" placeholder="Enter API Hash" style="width:70%" ng-model="node.api_hash">
</div>
<div class="form-row">
<label for="node-config-input-session"><i class="icon-tasks"></i> Session</label>
<input type="text" id="node-config-input-session" placeholder="Enter Session" style="width:70%" ng-model="node.session">
</div>
<div class="form-row">
<label for="node-config-input-useIPV6"><i class="icon-tasks"></i> Use IPV6</label>
<input type="checkbox" id="node-config-input-useIPV6" ng-model="node.useIPV6">
</div>
<div class="form-row">
<label for="node-config-input-timeout"><i class="icon-tasks"></i> Timeout</label>
<input type="number" id="node-config-input-timeout" placeholder="Enter Timeout" style="width:70%" ng-model="node.timeout">
</div>
<div class="form-row">
<label for="node-config-input-requestRetries"><i class="icon-tasks"></i> Request Retries</label>
<input type="number" id="node-config-input-requestRetries" placeholder="Enter Request Retries" style="width:70%" ng-model="node.requestRetries">
</div>
<div class="form-row">
<label for="node-config-input-connectionRetries"><i class="icon-tasks"></i> Connection Retries</label>
<input type="number" id="node-config-input-connectionRetries" placeholder="Enter Connection Retries" style="width:70%" ng-model="node.connectionRetries">
</div>
<div class="form-row">
<label for="node-config-input-proxy"><i class="icon-tasks"></i> Proxy</label>
<input type="text" id="node-config-input-proxy" placeholder="Enter Proxy" style="width:70%" ng-model="node.proxy">
</div>
<div class="form-row">
<label for="node-config-input-downloadRetries"><i class="icon-tasks"></i> Download Retries</label>
<input type="number" id="node-config-input-downloadRetries" placeholder="Enter Download Retries" style="width:70%" ng-model="node.downloadRetries">
</div>
<div class="form-row">
<label for="node-config-input-retryDelay"><i class="icon-tasks"></i> Retry Delay</label>
<input type="number" id="node-config-input-retryDelay" placeholder="Enter Retry Delay" style="width:70%" ng-model="node.retryDelay">
</div>
<div class="form-row">
<label for="node-config-input-autoReconnect"><i class="icon-tasks"></i> Auto Reconnect</label>
<input type="checkbox" id="node-config-input-autoReconnect" ng-model="node.autoReconnect">
</div>
<div class="form-row">
<label for="node-config-input-sequentialUpdates"><i class="icon-tasks"></i> Sequential Updates</label>
<input type="checkbox" id="node-config-input-sequentialUpdates" ng-model="node.sequentialUpdates">
</div>
<div class="form-row">
<label for="node-config-input-floodSleepThreshold"><i class="icon-tasks"></i> Flood Sleep Threshold</label>
<input type="number" id="node-config-input-floodSleepThreshold" placeholder="Enter Flood Sleep Threshold" style="width:70%" ng-model="node.floodSleepThreshold">
</div>
<div class="form-row">
<label for="node-config-input-deviceModel"><i class="icon-tasks"></i> Device Model</label>
<input type="text" id="node-config-input-deviceModel" placeholder="Enter Device Model" style="width:70%" ng-model="node.deviceModel">
</div>
<div class="form-row">
<label for="node-config-input-systemVersion"><i class="icon-tasks"></i> System Version</label>
<input type="text" id="node-config-input-systemVersion" placeholder="Enter System Version" style="width:70%" ng-model="node.systemVersion">
</div>
<div class="form-row">
<label for="node-config-input-appVersion"><i class="icon-tasks"></i> App Version</label>
<input type="text" id="node-config-input-appVersion" placeholder="Enter App Version" style="width:70%" ng-model="node.appVersion">
</div>
<div class="form-row">
<label for="node-config-input-langCode"><i class="icon-tasks"></i> Language Code</label>
<input type="text" id="node-config-input-langCode" placeholder="Enter Language Code" style="width:70%" ng-model="node.langCode">
</div>
<div class="form-row">
<label for="node-config-input-systemLangCode"><i class="icon-tasks"></i> System Language Code</label>
<input type="text" id="node-config-input-systemLangCode" placeholder="Enter System Language Code" style="width:70%" ng-model="node.systemLangCode">
</div>
<div class="form-row">
<label for="node-config-input-useWSS"><i class="icon-tasks"></i> Use WSS</label>
<input type="checkbox" id="node-config-input-useWSS" ng-model="node.useWSS">
</div>
<div class="form-row">
<label for="node-config-input-maxConcurrentDownloads"><i class="icon-tasks"></i> Max Concurrent Downloads</label>
<input type="number" id="node-config-input-maxConcurrentDownloads" placeholder="Enter Max Concurrent Downloads" style="width:70%" ng-model="node.maxConcurrentDownloads">
</div>
<div class="form-row">
<label for="node-config-input-securityChecks"><i class="icon-tasks"></i> Security Checks</label>
<input type="checkbox" id="node-config-input-securityChecks" ng-model="node.securityChecks">
</div>
<div class="form-row">
<label for="node-config-input-testServers"><i class="icon-tasks"></i> Test Servers</label>
<input type="checkbox" id="node-config-input-testServers" ng-model="node.testServers">
</div>
</script>

58
sample/config.js Normal file
View File

@ -0,0 +1,58 @@
const { TelegramClient } = require("telegram");
const { StringSession } = require("telegram/sessions");
module.exports = function (RED) {
function TelegramClientConfig(config) {
RED.nodes.createNode(this, config);
this.apiId = config.api_id;
this.apiHash = config.api_hash;
this.session = new StringSession(config.session);
this.useIPV6 = config.useIPV6;
this.timeout = config.timeout;
this.requestRetries = config.requestRetries;
this.connectionRetries = config.connectionRetries;
this.proxy = config.proxy;
this.downloadRetries = config.downloadRetries;
this.retryDelay = config.retryDelay;
this.autoReconnect = config.autoReconnect;
this.sequentialUpdates = config.sequentialUpdates;
this.floodSleepThreshold = config.floodSleepThreshold;
this.deviceModel = config.deviceModel;
this.systemVersion = config.systemVersion;
this.appVersion = config.appVersion;
this.langCode = config.langCode;
this.systemLangCode = config.systemLangCode;
this.useWSS = config.useWSS;
this.maxConcurrentDownloads = config.maxConcurrentDownloads;
this.securityChecks = config.securityChecks;
this.testServers = config.testServers;
const node = this;
this.client = new TelegramClient(this.session, parseInt(this.apiId), this.apiHash, {
});
try {
this.client.connect().then(async () => {
let isAuthorized = await this.client.isUserAuthorized();
if (!isAuthorized) {
node.error(`Session is invalid`);
} else {
node.status({ fill: "green", shape: "dot", text: "Connected" });
}
});
} catch (err) {
node.error('Authorisation error: ' + err.message);
}
this.on("close", () => {
if (this.client) {
this.client.disconnect();
node.status({ fill: "red", shape: "ring", text: "Disconnected" });
}
});
}
RED.nodes.registerType('config', TelegramClientConfig);
};

View File

@ -0,0 +1,47 @@
<script type="text/javascript">
RED.nodes.registerType('delete-message', {
category: 'telegram-account',
color: '#FF5733',
icon: 'tg.png',
align: 'right',
defaults: {
name: { value: '' },
config: { type: 'config', required: false },
},
inputs: 1,
outputs: 1,
label: function () {
return this.name || 'Delete Message';
},
});
</script>
<script type="text/html" data-template-name="delete-message">
<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"
style="width: 60%"
/>
</div>
<div class="form-row">
<label for="node-input-config">
<i class="fa fa-gear"></i> Config
</label>
<input
type="hidden"
id="node-input-config"
placeholder="Config"
style="width: 60%"
/>
</div>
</script>
<script type="text/html" data-help-name="delete-message">
input config, chatId, messageIds
</script>

27
sample/delete-message.js Normal file
View File

@ -0,0 +1,27 @@
module.exports = function (RED) {
function DeleteMessage(config) {
RED.nodes.createNode(this, config);
this.config = RED.nodes.getNode(config.config);
var node = this;
this.on('input', async function (msg) {
const chatId = msg.payload.chatId || config.chatId;
const messageIds = msg.payload.messageIds || config.messageIds;
const revoke = msg.payload.revoke || config.revoke || { revoke: true };
/** @type {TelegramClient} */
const client = msg.payload?.client ? msg.payload.client : this.config.client;
try {
const response = await client.deleteMessages(chatId, messageIds, revoke);
node.send({
payload: response,
});
} catch (err) {
node.error('Error deleting message: ' + err.message);
}
});
}
RED.nodes.registerType('delete-message', DeleteMessage);
};

42
sample/get-entity.html Normal file
View File

@ -0,0 +1,42 @@
<script type="text/javascript">
RED.nodes.registerType('get-entity', {
category: 'telegram-account',
color: '#229ED9',
icon: 'tg.png',
align: "right",
defaults: {
name: { value: '' },
config: { type: 'config', required: false },
},
inputs: 1,
outputs: 1,
label: function () {
return this.name || 'Get Entity';
}
});
</script>
<script type="text/html" data-template-name="get-entity">
<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"
style="width: 60%"
/>
</div>
<div class="form-row">
<label for="node-input-config">
<i class="fa fa-tag"></i> Config
</label>
<input
type="text"
id="node-input-config"
placeholder="Config"
style="width: 60%"
/>
</div>
</script>

36
sample/get-entity.js Normal file
View File

@ -0,0 +1,36 @@
module.exports = function (RED) {
function GetEntity(config) {
RED.nodes.createNode(this, config);
this.config = RED.nodes.getNode(config.config);
var node = this;
this.on('input', async function (msg) {
const input = msg.payload.input || config.input;
/** @type {TelegramClient} */
const client = msg.payload?.client ? msg.payload.client : this.config.client;
try {
let entity;
// Check if the input is a URL
if (input.includes('https://t.me/')) {
const username = input.split('/').pop();
entity = await client.getEntity(username);
} else {
entity = await client.getEntity(input);
}
node.send({
payload: {input:entity},
});
} catch (err) {
node.error('Error getting entity: ' + err.message);
node.send({
payload:{ input: null}
})
}
});
}
RED.nodes.registerType('get-entity', GetEntity);
};

BIN
sample/icons/tg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 635 B

128
sample/iter-dialogs.html Normal file
View File

@ -0,0 +1,128 @@
<script type="text/javascript">
RED.nodes.registerType('iter-dialogs', {
category: 'telegram',
color: '#32a3e0',
defaults: {
name: { value: '' },
config: { type: 'config', required: true },
limit: { value: "" },
offsetDate: { value: ""},
offsetId: { value: "" },
ignorePinned: { value: false },
ignoreMigrated: { value: false },
folder: { value: 0 },
archived: { value: "" },
},
inputs: 1,
outputs: 1,
paletteLabel: 'Iterate Dialogs',
label: function () {
return this.name || 'Iterate Dialogs';
},
});
</script>
<script type="text/html" data-template-name="iter-dialogs">
<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"
style="width: 60%"
ng-model="name"
/>
</div>
<div class="form-row">
<label for="node-input-config">
<i class="fa fa-tag"></i> Config
</label>
<input
type="text"
id="node-input-config"
placeholder="Config"
style="width: 60%"
ng-model="config"
/>
</div>
<div class="form-row">
<label for="node-input-limit">
<i class="fa fa-tag"></i> Limit
</label>
<input
type="text"
id="node-input-limit"
placeholder="Limit"
style="width: 60%"
ng-model="limit"
/>
</div>
<div class="form-row">
<label for="node-input-offsetDate">
<i class="fa fa-tag"></i> Offset Date
</label>
<input
type="datetime-local"
id="node-input-offsetDate"
placeholder="Offset Date"
style="width: 60%"
ng-model="offsetDate"
/>
</div>
<div class="form-row">
<label for="node-input-offsetId">
<i class="fa fa-tag"></i> Offset ID
</label>
<input
type="text"
id="node-input-offsetId"
placeholder="Offset ID"
style="width: 60%"
ng-model="offsetId"
/>
</div>
<div class="form-row">
<label for="node-input-ignorePinned">
<i class="fa fa-tag"></i> Ignore Pinned
</label>
<input
type="checkbox"
id="node-input-ignorePinned"
ng-model="ignorePinned"
/>
</div>
<div class="form-row">
<label for="node-input-ignoreMigrated">
<i class="fa fa-tag"></i> Ignore Migrated
</label>
<input
type="checkbox"
id="node-input-ignoreMigrated"
ng-model="ignoreMigrated"
/>
</div>
<div class="form-row">
<label for="node-input-folder">
<i class="fa fa-tag"></i> Folder
</label>
<input
type="text"
id="node-input-folder"
placeholder="Folder"
style="width: 60%"
ng-model="folder"
/>
</div>
<div class="form-row">
<label for="node-input-archived">
<i class="fa fa-tag"></i> Archived
</label>
<input
type="checkbox"
id="node-input-archived"
ng-model="archived"
/>
</div>
</script>

54
sample/iter-dialogs.js Normal file
View File

@ -0,0 +1,54 @@
const { TelegramClient } = require("telegram");
module.exports = function (RED) {
function IterDialogs(config) {
RED.nodes.createNode(this, config);
this.config = RED.nodes.getNode(config.config);
var node = this;
this.on('input', async function (msg) {
/** @type {TelegramClient} */
const client = msg.payload?.client ? msg.payload.client : this.config.client;
const limit = msg.payload.limit || config.limit;
const offsetDate = msg.payload.offsetDate || config.offsetDate;
const offsetId = msg.payload.offsetId || config.offsetId;
const offsetPeer = msg.payload?.offsetPeer || undefined;
const ignorePinned = msg.payload.ignorePinned || config.ignorePinned;
const ignoreMigrated = msg.payload.ignoreMigrated || config.ignoreMigrated;
const folder = msg.payload.folder || config.folder;
const archived = msg.payload.archived || config.archived;
const params = {
limit: limit !== ""? parseInt(limit) : undefined,
offsetDate: offsetDate !== "" ? offsetDate:undefined,
offsetId: offsetId !== "" ? parseInt(offsetId):undefined,
offsetPeer: offsetPeer,
ignorePinned: ignorePinned,
ignoreMigrated: ignoreMigrated,
folder: folder !== "" ? parseInt(folder):undefined,
archived: archived,
}
if (offsetDate) {
params.offsetDate = new Date(offsetDate).getTime() / 1000;
}
try {
const dialogs = {};
for await (const dialog of client.iterDialogs(params)){
dialogs[dialog.id] = dialog;
console.log(`${dialog.id}: ${dialog.title}`);
}
node.send({
payload: { dialogs },
});
} catch (err) {
node.error('Error iter dialogs: ' + err.message);
}
});
}
RED.nodes.registerType('iter-dialogs', IterDialogs);
};

256
sample/iter-messages.html Normal file
View File

@ -0,0 +1,256 @@
<script type="text/javascript">
RED.nodes.registerType('iter-messages', {
category: 'telegram',
color: '#32a3e0',
defaults: {
name: { value: '' },
config: { type: 'config', required: true },
chatId: { value: '', required: false },
limit: { value: '', required: false },
offsetDate: { value: '', required: false },
offsetId: { value: '', required: false },
maxId: { value: '', required: false },
minId: { value: '', required: false },
addOffset: { value: '', required: false },
search: { value: '', required: false },
filter: { value: '', required: false },
fromUser: { value: '', required: false },
waitTime: { value: '', required: false },
ids: { value: '', required: false },
reverse: { value: '', required: false },
replyTo: { value: '', required: false },
scheduled: { value: '', required: false }
},
inputs: 1,
outputs: 1,
paletteLabel: 'Iterate Messages',
label: function () {
return this.name || 'Iterate Messages';
},
oneditprepare: function(){
const node = this;
$("#node-input-ids").val(node.ids.join(","))
},
oneditsave:function(){
const node = this;
ids = $("#node-input-ids").val();
if(ids){
node.ids = ids.split(",").map(id => parseInt(id))
}
},
});
</script>
<script type="text/html" data-template-name="iter-messages">
<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"
style="width: 60%"
ng-model="name"
/>
</div>
<div class="form-row">
<label for="node-input-config">
<i class="fa fa-tag"></i> Config
</label>
<input
type="text"
id="node-input-config"
placeholder="Config"
style="width: 60%"
ng-model="config"
/>
</div>
<div class="form-row">
<label for="node-input-chatId">
<i class="fa fa-tag"></i> Chat ID
</label>
<input
type="text"
id="node-input-chatId"
placeholder="Chat ID"
style="width: 60%"
ng-model="chatId"
/>
</div>
<div class="form-row">
<label for="node-input-limit">
<i class="fa fa-tag"></i> Limit
</label>
<input
type="number"
id="node-input-limit"
placeholder="Limit"
style="width: 60%"
ng-model="limit"
/>
</div>
<div class="form-row">
<label for="node-input-offsetDate">
<i class="fa fa-tag"></i> Offset Date
</label>
<input
type="datetime-local"
id="node-input-offsetDate"
placeholder="Offset Date"
style="width: 60%"
ng-model="offsetDate"
/>
</div>
<div class="form-row">
<label for="node-input-offsetId">
<i class="fa fa-tag"></i> Offset ID
</label>
<input
type="number"
id="node-input-offsetId"
placeholder="Offset ID"
style="width: 60%"
ng-model="offsetId"
/>
</div>
<div class="form-row">
<label for="node-input-maxId">
<i class="fa fa-tag"></i> Max ID
</label>
<input
type="number"
id="node-input-maxId"
placeholder="Max ID"
style="width: 60%"
ng-model="maxId"
/>
</div>
<div class="form-row">
<label for="node-input-minId">
<i class="fa fa-tag"></i> Min ID
</label>
<input
type="number"
id="node-input-minId"
placeholder="Min ID"
style="width: 60%"
ng-model="minId"
/>
</div>
<div class="form-row">
<label for="node-input-addOffset">
<i class="fa fa-tag"></i> Add Offset
</label>
<input
type="number"
id="node-input-addOffset"
placeholder="Add Offset"
style="width: 60%"
ng-model="addOffset"
/>
</div>
<div class="form-row">
<label for="node-input-search">
<i class="fa fa-tag"></i> Search
</label>
<input
type="text"
id="node-input-search"
placeholder="Search"
style="width: 60%"
ng-model="search"
/>
</div>
<div class="form-row">
<label for="node-input-filter">
<i class="fa fa-tag"></i> Filter
</label>
<input type="checkbox" name="filter" value="InputMessagesFilterEmpty">Empty<br>
<input type="checkbox" name="filter" value="InputMessagesFilterPhotos">Photos<br>
<input type="checkbox" name="filter" value="InputMessagesFilterVideo">Video<br>
<input type="checkbox" name="filter" value="InputMessagesFilterPhotoVideo">Photo and Video<br>
<input type="checkbox" name="filter" value="InputMessagesFilterDocument">Document<br>
<input type="checkbox" name="filter" value="InputMessagesFilterUrl">URL<br>
<input type="checkbox" name="filter" value="InputMessagesFilterGif">GIF<br>
<input type="checkbox" name="filter" value="InputMessagesFilterVoice">Voice<br>
<input type="checkbox" name="filter" value="InputMessagesFilterMusic">Music<br>
<input type="checkbox" name="filter" value="InputMessagesFilterChatPhotos">Chat Photos<br>
<input type="checkbox" name="filter" value="InputMessagesFilterPhoneCalls">Phone Calls<br>
<input type="checkbox" name="filter" value="InputMessagesFilterRoundVoice">Round Voice<br>
<input type="checkbox" name="filter" value="InputMessagesFilterRoundVideo">Round Video<br>
<input type="checkbox" name="filter" value="InputMessagesFilterMyMentions">My Mentions<br>
<input type="checkbox" name="filter" value="InputMessagesFilterGeo">Geo<br>
<input type="checkbox" name="filter" value="InputMessagesFilterContacts">Contacts<br>
<input type="checkbox" name="filter" value="InputMessagesFilterPinned">Pinned<br>
</div>
<div class="form-row">
<label for="node-input-fromUser">
<i class="fa fa-tag"></i> From User
</label>
<input
type="text"
id="node-input-fromUser"
placeholder="From User"
style="width: 60%"
ng-model="fromUser"
/>
</div>
<div class="form-row">
<label for="node-input-waitTime">
<i class="fa fa-tag"></i> Wait Time
</label>
<input
type="number"
id="node-input-waitTime"
placeholder="Wait Time"
style="width: 60%"
ng-model="waitTime"
/>
</div>
<div class="form-row">
<label for="node-input-ids">
<i class="fa fa-tag"></i> IDs
</label>
<input
type="text"
id="node-input-ids"
placeholder="123,1245"
style="width: 60%"
ng-model="ids"
/>
</div>
<div class="form-row">
<label for="node-input-reverse">
<i class="fa fa-tag"></i> Reverse
</label>
<input
type="checkbox"
id="node-input-reverse"
ng-model="reverse"
/>
</div>
<div class="form-row">
<label for="node-input-replyTo">
<i class="fa fa-tag"></i> Reply To
</label>
<input
type="number"
id="node-input-replyTo"
placeholder="Reply To"
style="width: 60%"
ng-model="replyTo"
/>
</div>
<div class="form-row">
<label for="node-input-scheduled">
<i class="fa fa-tag"></i> Scheduled
</label>
<input
type="checkbox"
id="node-input-scheduled"
ng-model="scheduled"
/>
</div>
</script>

96
sample/iter-messages.js Normal file
View File

@ -0,0 +1,96 @@
const { TelegramClient, utils, Api } = require("telegram");
module.exports = function (RED) {
function IterMessages(config) {
RED.nodes.createNode(this, config);
this.config = RED.nodes.getNode(config.config);
var node = this;
this.on('input', async function (msg) {
/** @type {TelegramClient} */
const client = msg.payload?.client ? msg.payload.client : this.config.client;
const chatId = msg.payload?.chatId ? msg.payload.chatId : config.chatId;
let peerId = chatId === "me" ? chatId : utils.parseID(chatId);
// Получаем параметры из входного сообщения или из конфигурации узла
const limit = msg.payload?.limit || config.limit;
const offsetDate = msg.payload?.offsetDate || config.offsetDate;
const offsetId = msg.payload?.offsetId || config.offsetId;
const maxId = msg.payload?.maxId || config.maxId;
const minId = msg.payload?.minId || config.minId;
const addOffset = msg.payload?.addOffset || config.addOffset;
const search = msg.payload?.search || config.search;
const filter = msg.payload?.filter || config.filter;
const fromUser = msg.payload?.fromUser || config.fromUser;
const waitTime = msg.payload?.waitTime || config.waitTime;
const ids = msg.payload?.ids || config.ids;
const reverse = msg.payload?.reverse || config.reverse;
const replyTo = msg.payload?.replyTo || config.replyTo;
const scheduled = msg.payload?.scheduled || config.scheduled;
try {
const params = {
limit: limit !== ""? parseInt(limit) : undefined,
offsetDate: offsetDate !== "" ? offsetDate:undefined,
offsetId: offsetId !== "" ? parseInt(offsetId):undefined,
maxId: maxId,
minId: minId,
addOffset: addOffset,
search: search !== "" ? search : undefined,
filter: filter,
// fromUser: fromUser,
waitTime: waitTime,
ids: ids,
reverse: reverse,
replyTo: replyTo,
scheduled: scheduled,
};
if (offsetDate) {
params.offsetDate = new Date(offsetDate).getTime() / 1000;
}
console.log("🚀 ~ file: iter-messages.js:58 ~ params:", params)
console.log(chatId)
if (chatId[0] === "@") {
peerId = await client.getEntity(chatId);
}
const messages = {};
const filters = msg.payload?.filters || config.filters || [];
// Обработка выбранных фильтров
if (filters.length > 0) {
params.filter = [];
filters.forEach((filter) => {
params.filter.push( Api[filter]);
});
}
try {
for await (const message of client.iterMessages(peerId, params)){
messages[message.id] = message;
console.log(message.id, message.text);
}
} catch (error) {
const entity = await client.getInputEntity(peerId)
for await (const message of client.iterMessages(entity, params)){
messages[message.id] = message;
console.log(message.id, message.text);
}
}
node.send({
payload: { messages },
});
} catch (err) {
node.error('Error iter messages: ' + err.message);
}
});
}
RED.nodes.registerType('iter-messages', IterMessages);
};

56
sample/receiver.html Normal file
View File

@ -0,0 +1,56 @@
<script type="text/javascript">
RED.nodes.registerType('receiver', {
category: 'telegram-account',
color: '#229ED9',
icon: 'tg.png',
align:"right",
defaults: {
name: { value: '' },
config: { type: 'config', required: false },
ignore: { value:""}
},
inputs: 1,
outputs: 1,
label: function () {
return this.name || 'Receiver';
},
});
</script>
<script type="text/html" data-template-name="receiver">
<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"
style="width: 60%"
/>
</div>
<div class="form-row">
<label for="node-input-config">
<i class="fa fa-tag"></i> Config
</label>
<input
type="text"
id="node-input-config"
placeholder="Config"
style="width: 60%"
/>
</div>
<div class="form-row">
<label for="node-input-ignore">
<i class="fa fa-tag"></i> Config
</label>
<textarea
type="text"
id="node-input-ignore"
placeholder="Config"
style="width: 60%"
></textarea>
</div>
</script>

33
sample/receiver.js Normal file
View File

@ -0,0 +1,33 @@
const { NewMessage } = require("telegram/events");
// event.js
module.exports = function (RED) {
function Receiver(config) {
RED.nodes.createNode(this, config);
this.config = RED.nodes.getNode(config.config);
var node = this;
const client = this.config.client;
const ignore = config.ignore.split(/\n/);
try {
client.addEventHandler((update) => {
if(update.message.fromId != null && !ignore.includes(update.message.fromId.userId.toString())){
node.send({
payload:{
update
}
} )
}
}, new NewMessage());
} catch (err) {
node.error('Ошибка авторизации: ' + err.message);
}
}
RED.nodes.registerType('receiver', Receiver);
};

316
sample/send-file.html Normal file
View File

@ -0,0 +1,316 @@
<script type="text/javascript">
RED.nodes.registerType('send-files', {
category: 'telegram',
color: '#32a3e0',
defaults: {
name: { value: '' },
config: { type: 'config', required: true },
chatId: { value: '', required: true },
files: { value: '', required: true },
caption: { value: '' },
forceDocument: { value: false },
fileSize: { value: 0 },
clearDraft: { value: false },
progressCallback: { value: '' },
replyTo: { value: '' },
attributes: { value: '' },
thumb: { value: '' },
voiceNote: { value: false },
videoNote: { value: false },
supportsStreaming: { value: false },
parseMode: { value: '' },
formattingEntities: { value: '' },
silent: { value: false },
scheduleDate: { value: 0 },
buttons: { value: '' },
workers: { value: 0 },
noforwards: { value: false },
commentTo: { value: '' },
topMsgId: { value: '' },
},
inputs: 1,
outputs: 1,
icon: 'file.png',
paletteLabel: 'Send Files',
label: function () {
return this.name || 'Send Files';
},
});
</script>
<script type="text/html" data-template-name="send-files">
<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"
style="width: 60%"
ng-model="name"
/>
</div>
<div class="form-row">
<label for="node-input-config">
<i class="fa fa-tag"></i> Config
</label>
<input
type="text"
id="node-input-config"
placeholder="Config"
style="width: 60%"
ng-model="config"
/>
</div>
<div class="form-row">
<label for="node-input-chatId">
<i class="fa fa-tag"></i> Chat ID
</label>
<input
type="text"
id="node-input-chatId"
placeholder="Chat ID"
style="width: 60%"
ng-model="chatId"
/>
</div>
<div class="form-row">
<label for="node-input-files">
<i class="fa fa-tag"></i> Files (comma-separated)
</label>
<input
type="text"
id="node-input-files"
placeholder="url"
style="width: 60%"
ng-model="files"
/>
</div>
<div class="form-row">
<label for="node-input-caption">
<i class="fa fa-tag"></i> Caption
</label>
<input
type="text"
id="node-input-caption"
placeholder="Caption"
style="width: 60%"
ng-model="caption"
/>
</div>
<div class="form-row">
<label for="node-input-forceDocument">
<i class="fa fa-tag"></i> Force Document
</label>
<input
type="checkbox"
id="node-input-forceDocument"
ng-model="forceDocument"
/>
</div>
<div class="form-row">
<label for="node-input-fileSize">
<i class="fa fa-tag"></i> File Size
</label>
<input
type="number"
id="node-input-fileSize"
placeholder="File Size"
style="width: 60%"
ng-model="fileSize"
/>
</div>
<div class="form-row">
<label for="node-input-clearDraft">
<i class="fa fa-tag"></i> Clear Draft
</label>
<input
type="checkbox"
id="node-input-clearDraft"
ng-model="clearDraft"
/>
</div>
<div class="form-row">
<label for="node-input-progressCallback">
<i class="fa fa-tag"></i> Progress Callback
</label>
<input
type="text"
id="node-input-progressCallback"
placeholder="Progress Callback"
style="width: 60%"
ng-model="progressCallback"
/>
</div>
<div class="form-row">
<label for="node-input-replyTo">
<i class="fa fa-tag"></i> Reply To
</label>
<input
type="text"
id="node-input-replyTo"
placeholder="Reply To"
style="width: 60%"
ng-model="replyTo"
/>
</div>
<div class="form-row">
<label for="node-input-attributes">
<i class="fa fa-tag"></i> Attributes
</label>
<input
type="text"
id="node-input-attributes"
placeholder="Attributes"
style="width: 60%"
ng-model="attributes"
/>
</div>
<div class="form-row">
<label for="node-input-thumb">
<i class="fa fa-tag"></i> Thumbnail
</label>
<input
type="text"
id="node-input-thumb"
placeholder="Thumbnail"
style="width: 60%"
ng-model="thumb"
/>
</div>
<div class="form-row">
<label for="node-input-voiceNote">
<i class="fa fa-tag"></i> Voice Note
</label>
<input
type="checkbox"
id="node-input-voiceNote"
ng-model="voiceNote"
/>
</div>
<div class="form-row">
<label for="node-input-videoNote">
<i class="fa fa-tag"></i> Video Note
</label>
<input
type="checkbox"
id="node-input-videoNote"
ng-model="videoNote"
/>
</div>
<div class="form-row">
<label for="node-input-supportsStreaming">
<i class="fa fa-tag"></i> Supports Streaming
</label>
<input
type="checkbox"
id="node-input-supportsStreaming"
ng-model="supportsStreaming"
/>
</div>
<div class="form-row">
<label for="node-input-parseMode">
<i class="fa fa-tag"></i> Parse Mode
</label>
<input
type="text"
id="node-input-parseMode"
placeholder="Parse Mode"
style="width: 60%"
ng-model="parseMode"
/>
</div>
<div class="form-row">
<label for="node-input-formattingEntities">
<i class="fa fa-tag"></i> Formatting Entities
</label>
<input
type="text"
id="node-input-formattingEntities"
placeholder="Formatting Entities"
style="width: 60%"
ng-model="formattingEntities"
/>
</div>
<div class="form-row">
<label for="node-input-silent">
<i class="fa fa-tag"></i> Silent
</label>
<input
type="checkbox"
id="node-input-silent"
ng-model="silent"
/>
</div>
<div class="form-row">
<label for="node-input-scheduleDate">
<i class="fa fa-tag"></i> Schedule Date
</label>
<input
type="number"
id="node-input-scheduleDate"
placeholder="Schedule Date"
style="width: 60%"
ng-model="scheduleDate"
/>
</div>
<div class="form-row">
<label for="node-input-buttons">
<i class="fa fa-tag"></i> Buttons
</label>
<input
type="text"
id="node-input-buttons"
placeholder="Buttons"
style="width: 60%"
ng-model="buttons"
/>
</div>
<div class="form-row">
<label for="node-input-workers">
<i class="fa fa-tag"></i> Workers
</label>
<input
type="number"
id="node-input-workers"
placeholder="Workers"
style="width: 60%"
ng-model="workers"
/>
</div>
<div class="form-row">
<label for="node-input-noforwards">
<i class="fa fa-tag"></i> No Forwards
</label>
<input
type="checkbox"
id="node-input-noforwards"
ng-model="noforwards"
/>
</div>
<div class="form-row">
<label for="node-input-commentTo">
<i class="fa fa-tag"></i> Comment To
</label>
<input
type="text"
id="node-input-commentTo"
placeholder="Comment To"
style="width: 60%"
ng-model="commentTo"
/>
</div>
<div class="form-row">
<label for="node-input-topMsgId">
<i class="fa fa-tag"></i> Top Message ID
</label>
<input
type="text"
id="node-input-topMsgId"
placeholder="Top Message ID"
style="width: 60%"
ng-model="topMsgId"
/>
</div>
</script>

72
sample/send-file.js Normal file
View File

@ -0,0 +1,72 @@
module.exports = function (RED) {
function SendFile(config) {
RED.nodes.createNode(this, config);
this.config = RED.nodes.getNode(config.config);
var node = this;
this.on('input', async function (msg) {
const chatId = msg.payload.chatId || config.chatId;
const files = msg.payload.files || config.files.split(',').map(file => file.trim());
const caption = msg.payload.caption || config.caption;
const forceDocument = msg.payload.forceDocument || config.forceDocument;
const fileSize = msg.payload.fileSize || config.fileSize;
const clearDraft = msg.payload.clearDraft || config.clearDraft;
const progressCallback = msg.payload.progressCallback || config.progressCallback;
const replyTo = msg.payload.replyTo || config.replyTo;
const attributes = msg.payload.attributes || config.attributes;
const thumb = msg.payload.thumb || config.thumb;
const voiceNote = msg.payload.voiceNote || config.voiceNote;
const videoNote = msg.payload.videoNote || config.videoNote;
const supportsStreaming = msg.payload.supportsStreaming || config.supportsStreaming;
const parseMode = msg.payload.parseMode || config.parseMode;
const formattingEntities = msg.payload.formattingEntities || config.formattingEntities;
const silent = msg.payload.silent || config.silent;
const scheduleDate = msg.payload.scheduleDate || config.scheduleDate;
const buttons = msg.payload.buttons || config.buttons;
const workers = msg.payload.workers || config.workers;
const noforwards = msg.payload.noforwards || config.noforwards;
const commentTo = msg.payload.commentTo || config.commentTo;
const topMsgId = msg.payload.topMsgId || config.topMsgId;
/** @type {TelegramClient} */
const client = msg.payload?.client ? msg.payload.client : this.config.client;
try {
const params = {
file: files,
caption: caption,
forceDocument: forceDocument,
fileSize: fileSize,
clearDraft: clearDraft,
progressCallback: progressCallback,
replyTo: replyTo,
attributes: attributes,
thumb: thumb,
voiceNote: voiceNote,
videoNote: videoNote,
supportsStreaming: supportsStreaming,
parseMode: parseMode,
formattingEntities: formattingEntities,
silent: silent,
scheduleDate: scheduleDate,
buttons: buttons,
workers: workers,
noforwards: noforwards,
commentTo: commentTo,
topMsgId: topMsgId,
};
// Отправка файлов
const response = await client.sendFile(chatId, params);
node.send({
payload: response,
});
} catch (err) {
node.error('Error sending files: ' + err.message);
}
});
}
RED.nodes.registerType('send-files', SendFile);
};

212
sample/send-message.html Normal file
View File

@ -0,0 +1,212 @@
<script type="text/javascript">
RED.nodes.registerType('send-message', {
category: 'telegram-account',
color: '#229ED9',
icon: 'tg.png',
align: "right",
defaults: {
name: { value: '' },
chatId: { value: '' },
message: { value: '' },
config: { type: 'config', required: false },
parseMode: { value: 'md' }, // Default parse mode is Markdown
schedule: { value: '' }, // Default schedule is empty
replyTo: { value: '' }, // Reply to a message
attributes: { value: '' }, // Message attributes
formattingEntities: { value: '' }, // Message formatting entities
linkPreview: { value: false }, // Show link preview
file: { value: [] }, // File to be sent
thumb: { value: '' }, // Thumbnail for the file
forceDocument: { value: false }, // Send the file as a document
clearDraft: { value: false }, // Clear existing draft
buttons: { value: '' }, // Buttons to be shown after sending
silent: { value: false }, // Whether to notify in a broadcast channel
supportStreaming: { value: false }, // Whether the sent video supports streaming
noforwards: { value: false }, // Disable forwarding
commentTo: { value: '' }, // Comment to a message in a broadcast channel
topMsgId: { value: '' }, // Reply to a specific thread
},
inputs: 1,
outputs: 1,
label: function () {
return this.name || 'Send Message';
},
oneditprepare: function () {
const node = this;
$("#node-input-parseMode").change(function () {
if ($(this).val() === "html") {
$("#node-linkPreview-row").show();
} else {
$("#node-linkPreview-row").hide();
}
});
// const filesContainer = $("#node-input-files-container");
// if (Array.isArray(node.file)) {
// node.file.forEach(file => {
// const fileInput = `
// <div class="node-input-file-container">
// <input type="text" class="node-input-file" style="display: block; margin-top: 5px;" value="${file}">
// <button class="node-input-remove-file editor-button editor-button-small editor-button-delete" type="button">Remove</button>
// </div>
// `;
// filesContainer.append(fileInput);
// });
// }
// $("#node-input-add-file").click(function () {
// const filesContainer = $("#node-input-files-container");
// const fileInput = `
// <div class="node-input-file-container">
// <input type="text" class="node-input-file" style="display: block; margin-top: 5px;">
// <button class="node-input-remove-file editor-button editor-button-small editor-button-delete" type="button">Remove</button>
// </div>
// `;
// filesContainer.append(fileInput);
// });
// $("#node-input-files-container").on("click", ".node-input-remove-file", function () {
// $(this).closest(".node-input-file-container").remove();
// const removedIndex = $(this).closest(".node-input-file-container").index();
// const updatedFiles = node.file || [];
// updatedFiles.splice(removedIndex, 1);
// node.file = updatedFiles;
// });
// $("#node-input-files-container").on("change", ".node-input-file", function () {
// const fileInput = $(this);
// const updatedFiles = node.file || [];
// updatedFiles.push(fileInput.val());
// node.file = updatedFiles;
// });
},
});
</script>
<script type="text/html" data-template-name="send-message">
<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-config">
<i class="fa fa-gear"></i> Config
</label>
<input type="hidden" id="node-input-config">
</div>
<div class="form-row">
<label for="node-input-chat_id">
<i class="fa fa-user"></i> Chat ID
</label>
<input type="text" id="node-input-chatId" placeholder="Peer ID">
</div>
<div class="form-row">
<label for="node-input-message">
<i class="fa fa-pencil"></i> Message
</label>
<textarea type="text" id="node-input-message" placeholder="Message"></textarea>
</div>
<div class="form-row">
<label for="node-input-parseMode">
<i class="fa fa-code"></i> Parse Mode
</label>
<select id="node-input-parseMode">
<option value="md" selected>Markdown</option>
<option value="html">HTML</option>
</select>
</div>
<div class="form-row">
<label for="node-input-schedule">
<i class="fa fa-clock"></i> Schedule
</label>
<input type="datetime-local" id="node-input-schedule" placeholder="Schedule">
</div>
<div class="form-row" id="node-linkPreview-row">
<label for="node-input-linkPreview">
<i class="fa fa-link"></i> Show Link Preview
</label>
<input type="checkbox" id="node-input-linkPreview">
</div>
<div class="form-row">
<label>
<i class="fa fa-file"></i> Files
</label>
<div id="node-input-files-container">
</div>
<button id="node-input-add-file" class="editor-button editor-button-large editor-button-add" style="margin-top: 1rem;" type="button">Add File</button>
</div>
<div class="form-row" id="node-thumb-row">
<label for="node-input-thumb">
<i class="fa fa-file-image"></i> Thumbnail (Optional)
</label>
<input type="text" id="node-input-thumb">
</div>
<div class="form-row">
<label for="node-input-forceDocument">
<i class="fa fa-file"></i> Force Send as Document
</label>
<input type="checkbox" id="node-input-forceDocument">
</div>
<div class="form-row">
<label for="node-input-clearDraft">
<i class="fa fa-trash"></i> Clear Existing Draft
</label>
<input type="checkbox" id="node-input-clearDraft">
</div>
<div class="form-row">
<label for="node-input-buttons">
<i class="fa fa-th"></i> Buttons
</label>
<textarea type="text" id="node-input-buttons" placeholder="Buttons"></textarea>
</div>
<div class="form-row">
<label for="node-input-silent">
<i class="fa fa-bell-slash"></i> Silent Notification
</label>
<input type="checkbox" id="node-input-silent">
</div>
<div class="form-row">
<label for="node-input-supportStreaming">
<i class="fa fa-video"></i> Support Streaming
</label>
<input type="checkbox" id="node-input-supportStreaming">
</div>
<div class="form-row">
<label for="node-input-noforwards">
<i class="fa fa-forward"></i> Disable Forwarding
</label>
<input type="checkbox" id="node-input-noforwards">
</div>
<div class="form-row">
<label for="node-input-commentTo">
<i class="fa fa-comments"></i> Comment To Message
</label>
<input type="text" id="node-input-commentTo" placeholder="Comment To">
</div>
<div class="form-row">
<label for="node-input-topMsgId">
<i class="fa fa-reply"></i> Reply To Thread
</label>
<input type="text" id="node-input-topMsgId" placeholder="Top Msg ID">
</div>
</script>

83
sample/send-message.js Normal file
View File

@ -0,0 +1,83 @@
const { TelegramClient } = require("telegram");
const { parseID } = require("telegram/Utils");
module.exports = function (RED) {
function SendMessage(config) {
RED.nodes.createNode(this, config);
this.config = RED.nodes.getNode(config.config);
var node = this;
this.on('input', async function (msg) {
let chatId = msg.payload.chatId || config.chatId;
const message = msg.payload.message || config.message;
const parseMode = msg.payload.parseMode || config.parseMode;
const schedule = msg.payload.schedule || config.schedule;
const replyTo = msg.payload.replyTo || config.replyTo;
const attributes = msg.payload.attributes || config.attributes;
const formattingEntities = msg.payload.formattingEntities || config.formattingEntities;
const linkPreview = msg.payload.linkPreview || config.linkPreview;
const file = msg.payload.file || config.file;
const thumb = msg.payload.thumb || config.thumb;
const forceDocument = msg.payload.forceDocument || config.forceDocument;
const clearDraft = msg.payload.clearDraft || config.clearDraft;
const buttons = msg.payload.buttons || config.buttons;
const silent = msg.payload.silent || config.silent;
const supportStreaming = msg.payload.supportStreaming || config.supportStreaming;
const noforwards = msg.payload.noforwards || config.noforwards;
const commentTo = msg.payload.commentTo || config.commentTo;
const topMsgId = msg.payload.topMsgId || config.topMsgId;
/** @type {TelegramClient} */
const client = msg.payload?.client ? msg.payload.client : this.config.client;
let peerId = chatId === "me" ? chatId : parseID(chatId);
try {
const params = {
message: message,
parseMode: parseMode,
replyTo: replyTo !== ""? replyTo:undefined,
attributes: attributes,
formattingEntities: formattingEntities !== ""? formattingEntities:undefined,
linkPreview: linkPreview,
file: file !== "" && file.length > 1? file:undefined,
thumb: thumb,
forceDocument: forceDocument,
clearDraft: clearDraft,
buttons: buttons !== "" ? buttons : undefined,
silent: silent,
supportStreaming: supportStreaming,
noforwards: noforwards,
commentTo: commentTo !== "" ? commentTo : undefined,
topMsgId: topMsgId !== topMsgId ? commentTo : undefined,
};
console.log("🚀 ~ file: send-message.js:60 ~ params:", params)
if (schedule) {
params.schedule = new Date(schedule).getTime() / 1000;
}
let response;
if (chatId[0] === "@") {
peerId = await client.getEntity(chatId);
}
try {
response = await client.sendMessage(peerId, params);
} catch (error) {
const entity = await client.getInputEntity(peerId)
await client.sendMessage(entity, params);
}
node.send({
payload: { response },
});
} catch (err) {
node.error('Error send message: ' + err.message);
}
});
}
RED.nodes.registerType('send-message', SendMessage);
};