Compare commits
18 Commits
de9a189d57
...
v0.1.2
| Author | SHA1 | Date | |
|---|---|---|---|
| c4a74152d6 | |||
| 0f5b17fd2c | |||
| 87d1ff8086 | |||
| 8c8f7beb5c | |||
| 259bed9823 | |||
| a94176f65c | |||
| bfda135c19 | |||
| 806d8db44c | |||
| 60835022fb | |||
| cebc91d13a | |||
| 81eee54695 | |||
| e4381e7daf | |||
| d020c0c9bf | |||
| caca0b1398 | |||
| 4eaaaa28b7 | |||
| 1183ee7bc7 | |||
| d02b25d026 | |||
| cb1c4f2e54 |
@@ -1,5 +1,5 @@
|
||||
name: telepathy
|
||||
version: 0.1.0
|
||||
version: 0.1.2
|
||||
|
||||
authors:
|
||||
- Danila Fedorin <danila.fedorin@gmail.com>
|
||||
|
||||
@@ -1,30 +1,115 @@
|
||||
require "http"
|
||||
require "./utils.cr"
|
||||
|
||||
module Telepathy
|
||||
class Bot
|
||||
enum Control
|
||||
Done
|
||||
end
|
||||
|
||||
def initialize(@api_token : String)
|
||||
@request_base = "https://api.telegram.org/bot#{@api_token}"
|
||||
@this_user = uninitialized User?
|
||||
@this_user = get_me
|
||||
@last_update_id = uninitialized Int64?
|
||||
@last_update_id = nil
|
||||
@command_hooks = {} of String => Update, Array(String) -> Void
|
||||
@message_hooks = [] of Update -> Void
|
||||
@poll_start_hooks = [] of -> Void
|
||||
@poll_end_hooks = [] of -> Void
|
||||
@poll_channel = Channel(Int64?|Control).new
|
||||
@update_channel = Channel(Array(Update)|Control).new
|
||||
@poll_running = false
|
||||
end
|
||||
|
||||
def get_me
|
||||
response = HTTP::Client.get(@request_base + "/getMe",
|
||||
headers: HTTP::Headers{"User-agent" => "Telepathy"})
|
||||
return Response(User).from_json(response.body).result
|
||||
Utils.get_me(@api_token)
|
||||
end
|
||||
|
||||
def get_updates
|
||||
update_data = {} of String => Int64 | String
|
||||
@last_update_id.try { |id| update_data["offset"] = id }
|
||||
response = HTTP::Client.get(@request_base + "/getUpdates",
|
||||
headers: HTTP::Headers{"User-agent" => "Telepathy", "Content-type" => "application/json" },
|
||||
body: update_data.to_json)
|
||||
updates = Response(Array(Update)).from_json(response.body).result
|
||||
updates.last?.try { |update| @last_update_id = update.update_id + 1 }
|
||||
return updates
|
||||
def get_updates(timeout = 0)
|
||||
Utils.get_updates(@api_token, timeout, @last_update_id)
|
||||
end
|
||||
|
||||
def send_message(chat_id : String | Int64, text : String,
|
||||
parse_mode : Utils::ParseMode = Utils::ParseMode::Normal,
|
||||
disable_web_preview : Bool = false,
|
||||
disable_notification : Bool = false,
|
||||
reply_to_message_id : Int64? = nil)
|
||||
Utils.send_message(@api_token, chat_id, text,
|
||||
parse_mode, disable_web_preview,
|
||||
disable_notification, reply_to_message_id)
|
||||
end
|
||||
|
||||
def send_photo(chat_id : String | Int64, photo : String | File, caption : String? = nil,
|
||||
disable_notification : Bool = false,
|
||||
reply_to_message_id : Int64? = nil)
|
||||
Utils.send_photo(@api_token, chat_id, photo, caption, disable_notification, reply_to_message_id)
|
||||
end
|
||||
|
||||
def command(command_name, &block: Update, Array(String) -> Void)
|
||||
@command_hooks[command_name] = block
|
||||
end
|
||||
|
||||
def message(&block: Update -> Void)
|
||||
@message_hooks.push(block)
|
||||
end
|
||||
|
||||
def poll_start(&block: -> Void)
|
||||
@poll_start_hooks.push(block);
|
||||
end
|
||||
|
||||
def poll_end(&block: -> Void)
|
||||
@poll_end_hooks.push(block);
|
||||
end
|
||||
|
||||
private def process_updates(updates)
|
||||
updates.each do |update|
|
||||
if message = update.message
|
||||
@message_hooks.each &.call(update)
|
||||
if entity = message.entities.try { |it| it.first? }
|
||||
text = message.text.as String
|
||||
if entity.offset == 0 && entity.type == "bot_command"
|
||||
divider_index = (text.index /\s|@/) || text.size
|
||||
first_space_index = (text.index /\s/) || text.size
|
||||
command = text[1...divider_index]
|
||||
remaining = text[first_space_index..text.size]
|
||||
params = remaining.empty? ? ([] of String) : (remaining[1...remaining.size].split ' ')
|
||||
@command_hooks[command]?.try { |command| command.call(update, params) }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private def spawn_worker
|
||||
spawn do
|
||||
while @poll_running
|
||||
begin
|
||||
updates = get_updates 10
|
||||
process_updates updates
|
||||
@last_update_id = updates.last?.try &.update_id.+(1) || @last_update_id
|
||||
rescue
|
||||
end
|
||||
end
|
||||
|
||||
@poll_end_hooks.each do |hook|
|
||||
hook.call
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def poll
|
||||
if !@poll_running
|
||||
@poll_running = true
|
||||
@poll_start_hooks.each do |hook|
|
||||
hook.call
|
||||
end
|
||||
spawn_worker
|
||||
end
|
||||
end
|
||||
|
||||
def end_poll
|
||||
@poll_running = false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
require "json"
|
||||
require "./user.cr"
|
||||
require "./char.cr"
|
||||
require "./chat.cr"
|
||||
require "./message_entity.cr"
|
||||
require "./audio.cr"
|
||||
require "./document.cr"
|
||||
|
||||
83
src/telepathy/utils.cr
Normal file
83
src/telepathy/utils.cr
Normal file
@@ -0,0 +1,83 @@
|
||||
module Telepathy::Utils
|
||||
extend self
|
||||
API_URL = "https://api.telegram.org/bot"
|
||||
|
||||
enum ParseMode
|
||||
Normal
|
||||
Markdown
|
||||
HTML
|
||||
end
|
||||
|
||||
def get_me(api_key : String)
|
||||
response = HTTP::Client.get(API_URL + api_key + "/getMe",
|
||||
headers: HTTP::Headers{"User-agent" => "Telepathy"})
|
||||
return Response(User).from_json(response.body).result
|
||||
end
|
||||
|
||||
def get_updates(api_key : String, timeout = 0, last_update_id : Int? = nil)
|
||||
update_data = {} of String => Int64 | Int32 | String
|
||||
update_data["timeout"] = timeout
|
||||
last_update_id.try { |id| update_data["offset"] = id }
|
||||
response = HTTP::Client.get(API_URL + api_key + "/getUpdates",
|
||||
headers: HTTP::Headers{"User-agent" => "Telepathy",
|
||||
"Content-type" => "application/json" },
|
||||
body: update_data.to_json)
|
||||
return Response(Array(Update)).from_json(response.body).result
|
||||
end
|
||||
|
||||
def send_message(api_key : String, chat_id : String | Int64, text : String,
|
||||
parse_mode : ParseMode = ParseMode::Normal,
|
||||
disable_web_preview : Bool = false,
|
||||
disable_notification : Bool = false,
|
||||
reply_to_message_id : Int64? = nil)
|
||||
message_data = { "chat_id" => chat_id, "text" => text } of String => Int64 | String | Bool
|
||||
message_data["disable_web_preview"] = true if disable_web_preview
|
||||
message_data["disable_notification"] = true if disable_notification
|
||||
if parse_mode == ParseMode::Markdown
|
||||
message_data["parse_mode"] = "Markdown"
|
||||
elsif parse_mode == ParseMode::HTML
|
||||
message_data["parse_mode"] = "HTML"
|
||||
end
|
||||
reply_to_message_id.try { |id| message_data["reply_to_message_id"] = id }
|
||||
HTTP::Client.get(API_URL + api_key + "/sendMessage",
|
||||
headers: HTTP::Headers{"User-agent" => "Telepathy", "Content-type" => "application/json" },
|
||||
body: message_data.to_json)
|
||||
end
|
||||
|
||||
def send_photo(api_key : String, chat_id : String | Int64, photo : String | File, caption : String? = nil,
|
||||
disable_notification : Bool = false,
|
||||
reply_to_message_id : Int64? = nil)
|
||||
IO.pipe do |reader, writer|
|
||||
channel = Channel(String).new(1)
|
||||
spawn do
|
||||
HTTP::FormData.build(writer) do |formdata|
|
||||
channel.send(formdata.content_type)
|
||||
case chat_id
|
||||
when String
|
||||
formdata.field("chat_id", chat_id.as(String))
|
||||
when Int64
|
||||
formdata.field("chat_id", chat_id.as(Int64).to_s)
|
||||
end
|
||||
formdata.field("disable_notification", disable_notification.to_s)
|
||||
caption.try { |caption| formdata.field("caption", caption) }
|
||||
reply_to_message_id.try { |id| formdata.field("reply_to_message_id", id) }
|
||||
case photo
|
||||
when String
|
||||
formdata.field("photo", photo.as(String))
|
||||
when File
|
||||
photo_file = photo.as(File)
|
||||
formdata.file("photo", photo_file,
|
||||
HTTP::FormData::FileMetadata.new(filename: File.basename(photo_file.path)))
|
||||
end
|
||||
end
|
||||
|
||||
writer.close
|
||||
end
|
||||
|
||||
response = HTTP::Client.get(API_URL + api_key + "/sendPhoto",
|
||||
headers: HTTP::Headers{"User-agent" => "Telepathy",
|
||||
"Content-type" => channel.receive },
|
||||
body: reader)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,3 +1,3 @@
|
||||
module Telepathy
|
||||
VERSION = "0.1.0"
|
||||
VERSION = "0.1.1"
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user