Skip to content

Commit 89a3b7f

Browse files
committed
add blocking io supports
1 parent b2db269 commit 89a3b7f

File tree

4 files changed

+282
-145
lines changed

4 files changed

+282
-145
lines changed

private/async.nim

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
import asyncdispatch
2+
3+
proc makeRequestAsync(endpoint: string, data: MultipartData = nil): Future[JsonNode] {.async.} =
4+
let client = newAsyncHttpClient()
5+
let r = await client.post(endpoint, multipart=data)
6+
if r.status.startsWith("200"):
7+
var obj = parseJson(r.body)
8+
if obj["ok"].bval == true:
9+
result = obj["result"]
10+
else:
11+
raise newException(IOError, r.status)
12+
client.close()
13+
14+
proc getMeAsync*(b: TeleBot): Future[User] {.async.} =
15+
## Returns basic information about the bot in form of a ``User`` object.
16+
let endpoint = API_URL % [b.token, "getMe"]
17+
let res = await makeRequestAsync(endpoint)
18+
result = parseUser(res)
19+
20+
proc sendMessageAsync*(b: TeleBot, chatId: int, text: string, disableWebPagePreview = false, replyToMessageId = 0, replyMarkup: KeyboardMarkup = nil): Future[Message] {.async.} =
21+
let endpoint = API_URL % [b.token, "sendMessage"]
22+
var data = newMultipartData()
23+
data["chat_id"] = $chatId
24+
data["text"] = text
25+
if disableWebPagePreview:
26+
data["disable_web_page_preview"] = "true"
27+
if replyToMessageId != 0:
28+
data["reply_to_message_id"] = $replyToMessageId
29+
if not replyMarkup.isNil:
30+
data["reply_markup"] = $replyMarkup
31+
32+
let res = await makeRequestAsync(endpoint, data)
33+
result = parseMessage(res)
34+
35+
proc forwardMessageAsync*(b: TeleBot, chatId: int, fromChatId: int, messageId: int): Future[Message] {.async.} =
36+
let endpoint = API_URL % [b.token, "forwardMessage"]
37+
var data = newMultipartData()
38+
data["chat_id"] = $chatId
39+
data["from_chat_id"] = $fromChatId
40+
data["message_id"] = $messageId
41+
42+
let res = await makeRequestAsync(endpoint, data)
43+
result = parseMessage(res)
44+
45+
proc sendFileAsync(b: TeleBot, m: string, chatId: int, key, val: string, resend = false, rtmId = 0, rM: KeyboardMarkup = nil): Future[Message] {.async.} =
46+
let endpoint = API_URL % [b.token, m]
47+
48+
var data = newMultipartData()
49+
data["chat_id"] = $chatId
50+
51+
if resend:
52+
data[key] = val
53+
else:
54+
if val.startsWith("http"):
55+
let u = parseUri(val)
56+
var (_, _, ext) = u.path.splitFile()
57+
let tmp = mktemp(suffix=ext)
58+
downloadFile(val, tmp)
59+
data.addFiles({key: tmp})
60+
tmp.removeFile
61+
else:
62+
data.addFiles({key: val})
63+
64+
if rtmId != 0:
65+
data["reply_to_message_id"] = $rtmId
66+
if not rM.isNil:
67+
data["reply_markup"] = $rM
68+
69+
let res = await makeRequestAsync(endpoint, data)
70+
result = parseMessage(res)
71+
72+
proc sendPhotoAsync*(b: TeleBot, chatId: int, photo: string, resend = false, cap = "", rtmId = 0, rM: KeyboardMarkup = nil): Future[Message] {.async.} =
73+
result = await b.sendFileAsync("sendPhoto", chatId, "photo", photo, resend, rtmId, rM)
74+
75+
proc sendAudioAsync*(b: TeleBot, chatId: int, audio: string, resend = false, rtmId = 0, rM: KeyboardMarkup = nil): Future[Message] {.async.} =
76+
result = await b.sendFileAsync("sendAudio", chatId, "audio", audio, resend, rtmId, rM)
77+
78+
proc sendDocumentAsync*(b: TeleBot, chatId: int, document: string, resend = false, rtmId = 0, rM: KeyboardMarkup = nil): Future[Message] {.async.} =
79+
result = await b.sendFileAsync("sendDocument", chatId, "document", document, resend, rtmId, rM)
80+
81+
proc sendStickerAsync*(b: TeleBot, chatId: int, sticker: string, resend = false, rtmId = 0, rM: KeyboardMarkup = nil): Future[Message] {.async.} =
82+
result = await b.sendFileAsync("sendSticker", chatId, "sticker", sticker, resend, rtmId, rM)
83+
84+
proc sendVideoAsync*(b: TeleBot, chatId: int, video: string, resend = false, rtmId = 0, rM: KeyboardMarkup = nil): Future[Message] {.async.} =
85+
result = await b.sendFileAsync("sendVideo", chatId, "video", video, resend, rtmId, rM)
86+
87+
proc sendLocationAsync*(b: TeleBot, chatId: int, lat, long: float, rtmId = 0, rM: KeyboardMarkup = nil): Future[Message] {.async.} =
88+
let endpoint = API_URL % [b.token, "sendLocation"]
89+
90+
var data = newMultipartData()
91+
data["chat_id"] = $chatId
92+
data["longitude"] = $long
93+
data["latitude"] = $lat
94+
95+
if rtmId != 0:
96+
data["reply_to_message_id"] = $rtmId
97+
if not rM.isNil:
98+
data["reply_markup"] = $rM
99+
100+
let res = await makeRequestAsync(endpoint, data)
101+
result = parseMessage(res)
102+
103+
proc sendChatActionAsync*(b: TeleBot, chatId: int, action: string): Future[void] {.async.} =
104+
let endpoint = API_URL % [b.token, "sendChatAction"]
105+
var data = newMultipartData()
106+
data["chat_id"] = $chatId
107+
data["action"] = action
108+
109+
discard makeRequestAsync(endpoint, data)
110+
111+
proc getUserProfilePhotosAsync*(b: TeleBot, userId: int, offset = 0, limit = 100): Future[UserProfilePhotos] {.async.} =
112+
let endpoint = API_URL % [b.token, "getUserProfilePhotos"]
113+
var data = newMultipartData()
114+
data["user_id"] = $userId
115+
data["limit"] = $limit
116+
117+
if offset != 0:
118+
data["offset"] = $offset
119+
let res = await makeRequestAsync(endpoint, data)
120+
result = parseUserProfilePhotos(res)
121+
122+
proc getUpdatesAsync*(b: TeleBot, offset, limit, timeout = 0): Future[seq[Update]] {.async.} =
123+
let endpoint = API_URL % [b.token, "getUpdates"]
124+
var data = newMultipartData()
125+
126+
if offset != 0:
127+
data["offset"] = $offset
128+
else:
129+
data["offset"] = $(b.lastUpdateId+1)
130+
if limit != 0:
131+
data["limit"] = $limit
132+
if timeout != 0:
133+
data["timeout"] = $timeout
134+
135+
let res = await makeRequestAsync(endpoint, data)
136+
result = parseUpdates(b, res)
137+
138+
proc setWebhookAsync*(b: TeleBot, url: string) {.async.} =
139+
let endpoint = API_URL % [b.token, "setWebhook"]
140+
var data = newMultipartData()
141+
data["url"] = url
142+
143+
discard await makeRequestAsync(endpoint, data)

private/sync.nim

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
proc makeRequest(endpoint: string, data: MultipartData = nil): JsonNode =
2+
let body = postContent(endpoint, multipart=data)
3+
let obj = parseJson(body)
4+
if obj["ok"].bval == true:
5+
result = obj["result"]
6+
7+
proc getMe*(b: Telebot): User =
8+
let endpoint = API_URL % [b.token, "getMe"]
9+
let body = makeRequest(endpoint)
10+
result = parseUser(body)
11+
12+
proc sendMessage*(b: TeleBot, chatId: int, text: string, disableWebPagePreview = false, replyToMessageId = 0, replyMarkup: KeyboardMarkup = nil): Message =
13+
let endpoint = API_URL % [b.token, "sendMessage"]
14+
var data = newMultipartData()
15+
data["chat_id"] = $chatId
16+
data["text"] = text
17+
if disableWebPagePreview:
18+
data["disable_web_page_preview"] = "true"
19+
if replyToMessageId != 0:
20+
data["reply_to_message_id"] = $replyToMessageId
21+
if not replyMarkup.isNil:
22+
data["reply_markup"] = $replyMarkup
23+
24+
let res = makeRequest(endpoint, data)
25+
result = parseMessage(res)
26+
27+
proc forwardMessage*(b: TeleBot, chatId: int, fromChatId: int, messageId: int): Message=
28+
let endpoint = API_URL % [b.token, "forwardMessage"]
29+
var data = newMultipartData()
30+
data["chat_id"] = $chatId
31+
data["from_chat_id"] = $fromChatId
32+
data["message_id"] = $messageId
33+
34+
let res = makeRequest(endpoint, data)
35+
result = parseMessage(res)
36+
37+
proc sendFile(b: TeleBot, m: string, chatId: int, key, val: string, resend = false, rtmId = 0, rM: KeyboardMarkup = nil): Message=
38+
let endpoint = API_URL % [b.token, m]
39+
40+
var data = newMultipartData()
41+
data["chat_id"] = $chatId
42+
43+
if resend:
44+
data[key] = val
45+
else:
46+
if val.startsWith("http"):
47+
let u = parseUri(val)
48+
var (_, _, ext) = u.path.splitFile()
49+
let tmp = mktemp(suffix=ext)
50+
downloadFile(val, tmp)
51+
data.addFiles({key: tmp})
52+
tmp.removeFile
53+
else:
54+
data.addFiles({key: val})
55+
56+
if rtmId != 0:
57+
data["reply_to_message_id"] = $rtmId
58+
if not rM.isNil:
59+
data["reply_markup"] = $rM
60+
61+
let res = makeRequest(endpoint, data)
62+
result = parseMessage(res)
63+
64+
proc sendPhoto*(b: TeleBot, chatId: int, photo: string, resend = false, cap = "", rtmId = 0, rM: KeyboardMarkup = nil): Message=
65+
result = b.sendFile("sendPhoto", chatId, "photo", photo, resend, rtmId, rM)
66+
67+
proc sendAudio*(b: TeleBot, chatId: int, audio: string, resend = false, rtmId = 0, rM: KeyboardMarkup = nil): Message=
68+
result = b.sendFile("sendAudio", chatId, "audio", audio, resend, rtmId, rM)
69+
70+
proc sendDocument*(b: TeleBot, chatId: int, document: string, resend = false, rtmId = 0, rM: KeyboardMarkup = nil): Message=
71+
result = b.sendFile("sendDocument", chatId, "document", document, resend, rtmId, rM)
72+
73+
proc sendSticker*(b: TeleBot, chatId: int, sticker: string, resend = false, rtmId = 0, rM: KeyboardMarkup = nil): Message =
74+
result = b.sendFile("sendSticker", chatId, "sticker", sticker, resend, rtmId, rM)
75+
76+
proc sendVideo*(b: TeleBot, chatId: int, video: string, resend = false, rtmId = 0, rM: KeyboardMarkup = nil): Message=
77+
result = b.sendFile("sendVideo", chatId, "video", video, resend, rtmId, rM)
78+
79+
proc sendLocation*(b: TeleBot, chatId: int, lat, long: float, rtmId = 0, rM: KeyboardMarkup = nil): Message=
80+
let endpoint = API_URL % [b.token, "sendLocation"]
81+
82+
var data = newMultipartData()
83+
data["chat_id"] = $chatId
84+
data["longitude"] = $long
85+
data["latitude"] = $lat
86+
87+
if rtmId != 0:
88+
data["reply_to_message_id"] = $rtmId
89+
if not rM.isNil:
90+
data["reply_markup"] = $rM
91+
92+
let res = makeRequest(endpoint, data)
93+
result = parseMessage(res)
94+
95+
proc sendChatAction*(b: TeleBot, chatId: int, action: string) =
96+
let endpoint = API_URL % [b.token, "sendChatAction"]
97+
var data = newMultipartData()
98+
data["chat_id"] = $chatId
99+
data["action"] = action
100+
101+
discard makeRequest(endpoint, data)
102+
103+
proc getUserProfilePhotos*(b: TeleBot, userId: int, offset = 0, limit = 100): UserProfilePhotos =
104+
let endpoint = API_URL % [b.token, "getUserProfilePhotos"]
105+
var data = newMultipartData()
106+
data["user_id"] = $userId
107+
data["limit"] = $limit
108+
109+
if offset != 0:
110+
data["offset"] = $offset
111+
let res = makeRequest(endpoint, data)
112+
result = parseUserProfilePhotos(res)
113+
114+
proc getUpdates*(b: TeleBot, offset, limit, timeout = 0): seq[Update] =
115+
let endpoint = API_URL % [b.token, "getUpdates"]
116+
var data = newMultipartData()
117+
118+
if offset != 0:
119+
data["offset"] = $offset
120+
else:
121+
data["offset"] = $(b.lastUpdateId+1)
122+
if limit != 0:
123+
data["limit"] = $limit
124+
if timeout != 0:
125+
data["timeout"] = $timeout
126+
127+
let res = makeRequest(endpoint, data)
128+
result = parseUpdates(b, res)
129+
130+
proc setWebhook*(b: TeleBot, url: string) =
131+
let endpoint = API_URL % [b.token, "setWebhook"]
132+
var data = newMultipartData()
133+
data["url"] = url
134+
135+
discard makeRequest(endpoint, data)

0 commit comments

Comments
 (0)