teh-bot 1.0.4 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1228 -323
- package/{index.js → dist/index.cjs} +95 -167
- package/{index.d.ts → dist/index.d.ts} +518 -23
- package/dist/index.mjs +1002 -0
- package/package.json +25 -10
|
@@ -65,7 +65,7 @@ class TelegramBot extends EventEmitter {
|
|
|
65
65
|
method: "POST",
|
|
66
66
|
headers: {
|
|
67
67
|
...headers,
|
|
68
|
-
"User-Agent": "TehBot/1.0.
|
|
68
|
+
"User-Agent": "TehBot/1.0.5 (Modern; High-Performance)",
|
|
69
69
|
},
|
|
70
70
|
timeout: this.options.requestTimeout,
|
|
71
71
|
}
|
|
@@ -100,8 +100,32 @@ class TelegramBot extends EventEmitter {
|
|
|
100
100
|
})
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
+
async getMe() {
|
|
104
|
+
return this.request("getMe")
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async getUpdates(params = {}) {
|
|
108
|
+
return this.request("getUpdates", {
|
|
109
|
+
offset: this.offset,
|
|
110
|
+
timeout: this.options.pollingTimeout,
|
|
111
|
+
allowed_updates: this.options.allowedUpdates,
|
|
112
|
+
...params,
|
|
113
|
+
})
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
async setWebhook(url, params = {}) {
|
|
117
|
+
return this.request("setWebhook", { url, ...params })
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async deleteWebhook(params = {}) {
|
|
121
|
+
return this.request("deleteWebhook", params)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
async getWebhookInfo() {
|
|
125
|
+
return this.request("getWebhookInfo")
|
|
126
|
+
}
|
|
127
|
+
|
|
103
128
|
async sendMessage(chatId, content, options = {}) {
|
|
104
|
-
// content can be string (text) or object { image: ..., caption: ... }
|
|
105
129
|
if (typeof content === "string") {
|
|
106
130
|
return this.request("sendMessage", { chat_id: chatId, text: content, ...options })
|
|
107
131
|
}
|
|
@@ -607,7 +631,6 @@ class TelegramBot extends EventEmitter {
|
|
|
607
631
|
_createContext(update) {
|
|
608
632
|
const message = update.message || update.edited_message || update.channel_post || update.callback_query?.message
|
|
609
633
|
|
|
610
|
-
// Fallback logic for chat extraction from various update types
|
|
611
634
|
const chat =
|
|
612
635
|
update.message?.chat ||
|
|
613
636
|
update.callback_query?.message?.chat ||
|
|
@@ -642,7 +665,6 @@ class TelegramBot extends EventEmitter {
|
|
|
642
665
|
chatMember: update.chat_member,
|
|
643
666
|
}
|
|
644
667
|
|
|
645
|
-
// Baileys-style simplified response
|
|
646
668
|
ctx.send = (content, opts) => {
|
|
647
669
|
const chatId =
|
|
648
670
|
ctx.chat?.id ||
|
|
@@ -652,7 +674,7 @@ class TelegramBot extends EventEmitter {
|
|
|
652
674
|
from?.id
|
|
653
675
|
|
|
654
676
|
if (!chatId) {
|
|
655
|
-
console.error("[
|
|
677
|
+
console.error("[Teh] Context update without valid chatId destination:", JSON.stringify(update))
|
|
656
678
|
throw new Error("[Teh] Cannot send message: chat_id could not be resolved from this update context")
|
|
657
679
|
}
|
|
658
680
|
return this.sendMessage(chatId, content, opts)
|
|
@@ -669,13 +691,11 @@ class TelegramBot extends EventEmitter {
|
|
|
669
691
|
})
|
|
670
692
|
}
|
|
671
693
|
|
|
672
|
-
// Context helpers for media
|
|
673
694
|
ctx.replyWithPhoto = (photo, opts) => ctx.send({ image: photo, ...opts })
|
|
674
695
|
ctx.replyWithVideo = (video, opts) => ctx.send({ video, ...opts })
|
|
675
696
|
ctx.replyWithAudio = (audio, opts) => ctx.send({ audio, ...opts })
|
|
676
697
|
ctx.replyWithDocument = (doc, opts) => ctx.send({ document: doc, ...opts })
|
|
677
698
|
|
|
678
|
-
// Helper methods for callback queries
|
|
679
699
|
ctx.answerCallbackQuery = (options = {}) => {
|
|
680
700
|
if (!ctx.callbackQuery?.id) return Promise.resolve(false)
|
|
681
701
|
return this.answerCallbackQuery(ctx.callbackQuery.id, options)
|
|
@@ -683,7 +703,6 @@ class TelegramBot extends EventEmitter {
|
|
|
683
703
|
|
|
684
704
|
ctx.editMessageText = (text, options = {}) => {
|
|
685
705
|
if (!ctx.callbackQuery?.message) {
|
|
686
|
-
// If it's an inline message (no message object), we need the inline_message_id
|
|
687
706
|
if (ctx.callbackQuery?.inline_message_id) {
|
|
688
707
|
return this.editMessageText(text, {
|
|
689
708
|
inline_message_id: ctx.callbackQuery.inline_message_id,
|
|
@@ -741,163 +760,86 @@ class TelegramBot extends EventEmitter {
|
|
|
741
760
|
stream.push(`Content-Type: ${contentType}${nl}${nl}`)
|
|
742
761
|
|
|
743
762
|
if (fileData instanceof Stream) {
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
}
|
|
763
|
+
fileData.pipe(stream, { end: false })
|
|
764
|
+
await new Promise((resolve, reject) => {
|
|
765
|
+
fileData.on("end", resolve)
|
|
766
|
+
fileData.on("error", reject)
|
|
767
|
+
})
|
|
750
768
|
} else {
|
|
751
769
|
stream.push(fileData)
|
|
752
770
|
}
|
|
753
771
|
} else {
|
|
754
772
|
stream.push(`Content-Disposition: form-data; name="${key}"${nl}${nl}`)
|
|
755
|
-
stream.push(
|
|
773
|
+
stream.push(String(value))
|
|
756
774
|
}
|
|
757
|
-
stream.push(nl)
|
|
775
|
+
stream.push(`${nl}`)
|
|
758
776
|
}
|
|
759
777
|
stream.push(`--${boundary}--${nl}`)
|
|
760
|
-
} catch (err) {
|
|
761
|
-
console.error("[v0] Error building multipart stream:", err)
|
|
762
|
-
} finally {
|
|
763
778
|
stream.push(null)
|
|
779
|
+
} catch (err) {
|
|
780
|
+
stream.destroy(err)
|
|
764
781
|
}
|
|
765
782
|
})()
|
|
766
|
-
|
|
767
783
|
return stream
|
|
768
784
|
}
|
|
769
785
|
|
|
770
|
-
|
|
771
|
-
const
|
|
772
|
-
|
|
773
|
-
if (source instanceof Stream) return { data: source, contentType: defaultMime }
|
|
774
|
-
if (Buffer.isBuffer(source)) return { data: source, contentType: defaultMime }
|
|
775
|
-
|
|
776
|
-
if (typeof source === "string") {
|
|
777
|
-
if (source.startsWith("http")) {
|
|
778
|
-
return new Promise((resolve, reject) => {
|
|
779
|
-
https
|
|
780
|
-
.get(source, (res) => {
|
|
781
|
-
const filename = basename(new URL(source).pathname) || `file_${Date.now()}.jpg`
|
|
782
|
-
const contentType = res.headers["content-type"] || defaultMime
|
|
783
|
-
resolve({
|
|
784
|
-
data: res,
|
|
785
|
-
filename: filename,
|
|
786
|
-
contentType: contentType,
|
|
787
|
-
})
|
|
788
|
-
})
|
|
789
|
-
.on("error", reject)
|
|
790
|
-
})
|
|
791
|
-
}
|
|
792
|
-
|
|
793
|
-
// Local file
|
|
794
|
-
const filename = basename(source)
|
|
795
|
-
return {
|
|
796
|
-
data: createReadStream(source),
|
|
797
|
-
filename: filename,
|
|
798
|
-
contentType: this._getMime(extname(filename)) || defaultMime,
|
|
799
|
-
}
|
|
800
|
-
}
|
|
801
|
-
return source
|
|
802
|
-
}
|
|
803
|
-
|
|
804
|
-
_getMime(extOrType) {
|
|
805
|
-
const mimes = {
|
|
806
|
-
photo: "image/jpeg",
|
|
807
|
-
image: "image/jpeg",
|
|
808
|
-
video: "video/mp4",
|
|
809
|
-
audio: "audio/mpeg",
|
|
810
|
-
document: "application/octet-stream",
|
|
786
|
+
_getMime(ext) {
|
|
787
|
+
const mimeTypes = {
|
|
811
788
|
".jpg": "image/jpeg",
|
|
812
789
|
".jpeg": "image/jpeg",
|
|
813
790
|
".png": "image/png",
|
|
814
791
|
".gif": "image/gif",
|
|
815
792
|
".mp4": "video/mp4",
|
|
793
|
+
".avi": "video/x-msvideo",
|
|
794
|
+
".webm": "video/webm",
|
|
816
795
|
".mp3": "audio/mpeg",
|
|
796
|
+
".ogg": "audio/ogg",
|
|
797
|
+
".wav": "audio/wav",
|
|
817
798
|
".pdf": "application/pdf",
|
|
818
|
-
".
|
|
799
|
+
".doc": "application/msword",
|
|
800
|
+
".txt": "text/plain",
|
|
819
801
|
}
|
|
820
|
-
|
|
821
|
-
return mimes[key] || (key?.startsWith(".") ? "application/octet-stream" : mimes.photo)
|
|
802
|
+
return mimeTypes[ext.toLowerCase()] || "application/octet-stream"
|
|
822
803
|
}
|
|
823
804
|
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
flat[key] = JSON.stringify(value)
|
|
829
|
-
} else {
|
|
830
|
-
flat[key] = value
|
|
805
|
+
async _prepareFile(source, type) {
|
|
806
|
+
if (typeof source === "string") {
|
|
807
|
+
if (source.startsWith("http://") || source.startsWith("https://")) {
|
|
808
|
+
return source
|
|
831
809
|
}
|
|
832
|
-
}
|
|
833
|
-
return flat
|
|
834
|
-
}
|
|
835
810
|
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
async setWebhook(url, options = {}) {
|
|
850
|
-
return this.request("setWebhook", {
|
|
851
|
-
url,
|
|
852
|
-
...options,
|
|
853
|
-
})
|
|
854
|
-
}
|
|
855
|
-
|
|
856
|
-
async getWebhookInfo() {
|
|
857
|
-
return this.request("getWebhookInfo")
|
|
858
|
-
}
|
|
859
|
-
|
|
860
|
-
async getMe() {
|
|
861
|
-
return this.request("getMe")
|
|
862
|
-
}
|
|
863
|
-
|
|
864
|
-
async _sendFile(method, chatId, source, type, options = {}) {
|
|
865
|
-
const formData = {
|
|
866
|
-
chat_id: chatId,
|
|
867
|
-
[type]: await this._prepareFile(source, type),
|
|
868
|
-
...this._flattenOptions(options),
|
|
811
|
+
try {
|
|
812
|
+
const stat = statSync(source)
|
|
813
|
+
if (stat.isFile()) {
|
|
814
|
+
return {
|
|
815
|
+
data: createReadStream(source),
|
|
816
|
+
filename: basename(source),
|
|
817
|
+
contentType: this._getMime(extname(source)),
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
} catch (e) {
|
|
821
|
+
return source
|
|
822
|
+
}
|
|
869
823
|
}
|
|
870
|
-
return this.request(method, {}, formData)
|
|
871
|
-
}
|
|
872
|
-
|
|
873
|
-
async setMyCommands(commands, options = {}) {
|
|
874
|
-
return this.request("setMyCommands", { commands, ...options })
|
|
875
|
-
}
|
|
876
824
|
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
async getChatMenuButton(options = {}) {
|
|
886
|
-
return this.request("getChatMenuButton", options)
|
|
887
|
-
}
|
|
825
|
+
if (Buffer.isBuffer(source) || source instanceof Stream) {
|
|
826
|
+
return {
|
|
827
|
+
data: source,
|
|
828
|
+
filename: `file_${Date.now()}.jpg`,
|
|
829
|
+
contentType: "image/jpeg",
|
|
830
|
+
}
|
|
831
|
+
}
|
|
888
832
|
|
|
889
|
-
|
|
890
|
-
return this.request("getUserProfilePhotos", { user_id: userId, ...options })
|
|
833
|
+
return source
|
|
891
834
|
}
|
|
892
835
|
|
|
893
|
-
|
|
894
|
-
|
|
836
|
+
_formatError(response) {
|
|
837
|
+
const error = new Error(response.description || "Telegram API Error")
|
|
838
|
+
error.response = response
|
|
839
|
+
error.errorCode = response.error_code
|
|
840
|
+
return error
|
|
895
841
|
}
|
|
896
842
|
|
|
897
|
-
async revokeChatInviteLink(chatId, inviteLink) {
|
|
898
|
-
return this.request("revokeChatInviteLink", { chat_id: chatId, invite_link: inviteLink })
|
|
899
|
-
}
|
|
900
|
-
|
|
901
843
|
static InlineKeyboard() {
|
|
902
844
|
return new InlineKeyboardBuilder()
|
|
903
845
|
}
|
|
@@ -906,25 +848,22 @@ class TelegramBot extends EventEmitter {
|
|
|
906
848
|
return new ReplyKeyboardBuilder()
|
|
907
849
|
}
|
|
908
850
|
|
|
909
|
-
static RemoveKeyboard(
|
|
910
|
-
return { remove_keyboard: true
|
|
851
|
+
static RemoveKeyboard() {
|
|
852
|
+
return { remove_keyboard: true }
|
|
911
853
|
}
|
|
912
854
|
|
|
913
|
-
static ForceReply(
|
|
914
|
-
|
|
915
|
-
if (placeholder) obj.input_field_placeholder = placeholder
|
|
916
|
-
return obj
|
|
855
|
+
static ForceReply() {
|
|
856
|
+
return { force_reply: true }
|
|
917
857
|
}
|
|
918
858
|
}
|
|
919
859
|
|
|
920
860
|
class InlineKeyboardBuilder {
|
|
921
861
|
constructor() {
|
|
922
|
-
this.keyboard = []
|
|
923
|
-
this.currentRow = []
|
|
862
|
+
this.keyboard = [[]]
|
|
924
863
|
}
|
|
925
864
|
|
|
926
865
|
text(text, callbackData) {
|
|
927
|
-
this.
|
|
866
|
+
this.keyboard[this.keyboard.length - 1].push({
|
|
928
867
|
text,
|
|
929
868
|
callback_data: callbackData,
|
|
930
869
|
})
|
|
@@ -932,7 +871,7 @@ class InlineKeyboardBuilder {
|
|
|
932
871
|
}
|
|
933
872
|
|
|
934
873
|
url(text, url) {
|
|
935
|
-
this.
|
|
874
|
+
this.keyboard[this.keyboard.length - 1].push({
|
|
936
875
|
text,
|
|
937
876
|
url,
|
|
938
877
|
})
|
|
@@ -940,7 +879,7 @@ class InlineKeyboardBuilder {
|
|
|
940
879
|
}
|
|
941
880
|
|
|
942
881
|
login(text, loginUrl) {
|
|
943
|
-
this.
|
|
882
|
+
this.keyboard[this.keyboard.length - 1].push({
|
|
944
883
|
text,
|
|
945
884
|
login_url: loginUrl,
|
|
946
885
|
})
|
|
@@ -948,7 +887,7 @@ class InlineKeyboardBuilder {
|
|
|
948
887
|
}
|
|
949
888
|
|
|
950
889
|
switchInline(text, query = "") {
|
|
951
|
-
this.
|
|
890
|
+
this.keyboard[this.keyboard.length - 1].push({
|
|
952
891
|
text,
|
|
953
892
|
switch_inline_query: query,
|
|
954
893
|
})
|
|
@@ -956,7 +895,7 @@ class InlineKeyboardBuilder {
|
|
|
956
895
|
}
|
|
957
896
|
|
|
958
897
|
switchInlineCurrent(text, query = "") {
|
|
959
|
-
this.
|
|
898
|
+
this.keyboard[this.keyboard.length - 1].push({
|
|
960
899
|
text,
|
|
961
900
|
switch_inline_query_current_chat: query,
|
|
962
901
|
})
|
|
@@ -964,7 +903,7 @@ class InlineKeyboardBuilder {
|
|
|
964
903
|
}
|
|
965
904
|
|
|
966
905
|
game(text) {
|
|
967
|
-
this.
|
|
906
|
+
this.keyboard[this.keyboard.length - 1].push({
|
|
968
907
|
text,
|
|
969
908
|
callback_game: {},
|
|
970
909
|
})
|
|
@@ -972,7 +911,7 @@ class InlineKeyboardBuilder {
|
|
|
972
911
|
}
|
|
973
912
|
|
|
974
913
|
pay(text) {
|
|
975
|
-
this.
|
|
914
|
+
this.keyboard[this.keyboard.length - 1].push({
|
|
976
915
|
text,
|
|
977
916
|
pay: true,
|
|
978
917
|
})
|
|
@@ -980,35 +919,28 @@ class InlineKeyboardBuilder {
|
|
|
980
919
|
}
|
|
981
920
|
|
|
982
921
|
row() {
|
|
983
|
-
|
|
984
|
-
this.keyboard.push([...this.currentRow])
|
|
985
|
-
this.currentRow = []
|
|
986
|
-
}
|
|
922
|
+
this.keyboard.push([])
|
|
987
923
|
return this
|
|
988
924
|
}
|
|
989
925
|
|
|
990
926
|
build() {
|
|
991
|
-
this.
|
|
992
|
-
return {
|
|
993
|
-
inline_keyboard: this.keyboard,
|
|
994
|
-
}
|
|
927
|
+
return { inline_keyboard: this.keyboard }
|
|
995
928
|
}
|
|
996
929
|
}
|
|
997
930
|
|
|
998
931
|
class ReplyKeyboardBuilder {
|
|
999
932
|
constructor() {
|
|
1000
|
-
this.keyboard = []
|
|
1001
|
-
this.currentRow = []
|
|
933
|
+
this.keyboard = [[]]
|
|
1002
934
|
this.options = {}
|
|
1003
935
|
}
|
|
1004
936
|
|
|
1005
937
|
text(text) {
|
|
1006
|
-
this.
|
|
938
|
+
this.keyboard[this.keyboard.length - 1].push({ text })
|
|
1007
939
|
return this
|
|
1008
940
|
}
|
|
1009
941
|
|
|
1010
942
|
requestContact(text) {
|
|
1011
|
-
this.
|
|
943
|
+
this.keyboard[this.keyboard.length - 1].push({
|
|
1012
944
|
text,
|
|
1013
945
|
request_contact: true,
|
|
1014
946
|
})
|
|
@@ -1016,15 +948,15 @@ class ReplyKeyboardBuilder {
|
|
|
1016
948
|
}
|
|
1017
949
|
|
|
1018
950
|
requestLocation(text) {
|
|
1019
|
-
this.
|
|
951
|
+
this.keyboard[this.keyboard.length - 1].push({
|
|
1020
952
|
text,
|
|
1021
953
|
request_location: true,
|
|
1022
954
|
})
|
|
1023
955
|
return this
|
|
1024
956
|
}
|
|
1025
957
|
|
|
1026
|
-
requestPoll(text, type) {
|
|
1027
|
-
this.
|
|
958
|
+
requestPoll(text, type = "quiz") {
|
|
959
|
+
this.keyboard[this.keyboard.length - 1].push({
|
|
1028
960
|
text,
|
|
1029
961
|
request_poll: { type },
|
|
1030
962
|
})
|
|
@@ -1032,10 +964,7 @@ class ReplyKeyboardBuilder {
|
|
|
1032
964
|
}
|
|
1033
965
|
|
|
1034
966
|
row() {
|
|
1035
|
-
|
|
1036
|
-
this.keyboard.push([...this.currentRow])
|
|
1037
|
-
this.currentRow = []
|
|
1038
|
-
}
|
|
967
|
+
this.keyboard.push([])
|
|
1039
968
|
return this
|
|
1040
969
|
}
|
|
1041
970
|
|
|
@@ -1060,7 +989,6 @@ class ReplyKeyboardBuilder {
|
|
|
1060
989
|
}
|
|
1061
990
|
|
|
1062
991
|
build() {
|
|
1063
|
-
this.row()
|
|
1064
992
|
return {
|
|
1065
993
|
keyboard: this.keyboard,
|
|
1066
994
|
...this.options,
|