6 Commits

20 changed files with 364 additions and 190 deletions

View File

@@ -1,9 +1,9 @@
name: telepathy name: telepathy
version: 0.1.0 version: 0.2.0
authors: authors:
- Danila Fedorin <danila.fedorin@gmail.com> - Danila Fedorin <danila.fedorin@gmail.com>
crystal: 0.23.1 crystal: 1.0.0
license: MIT license: MIT

View File

@@ -1,9 +1,7 @@
require "./spec_helper" require "./spec_helper"
describe Telepathy do describe Telepathy do
# TODO: Write tests it "loads the library" do
Telepathy.should be_truthy
it "works" do
false.should eq(true)
end end
end end

View File

@@ -46,19 +46,19 @@ module Telepathy
Utils.send_photo(@api_token, chat_id, photo, caption, disable_notification, reply_to_message_id) Utils.send_photo(@api_token, chat_id, photo, caption, disable_notification, reply_to_message_id)
end end
def command(command_name, &block: Update, Array(String) -> Void) def command(command_name, &block : Update, Array(String) -> Void)
@command_hooks[command_name] = block @command_hooks[command_name] = block
end end
def message(&block: Update -> Void) def message(&block : Update -> Void)
@message_hooks.push(block) @message_hooks.push(block)
end end
def poll_start(&block: -> Void) def poll_start(&block : -> Void)
@poll_start_hooks.push(block); @poll_start_hooks.push(block);
end end
def poll_end(&block: -> Void) def poll_end(&block : -> Void)
@poll_end_hooks.push(block); @poll_end_hooks.push(block);
end end
@@ -81,30 +81,19 @@ module Telepathy
end end
end end
private def spawn_workers private def spawn_worker
spawn do spawn do
loop do while @poll_running
action = @poll_channel.receive begin
case action updates = get_updates 10
when Int64? process_updates updates
@last_update_id = action.nil? ? @last_update_id : action + 1 @last_update_id = updates.last?.try &.update_id.+(1) || @last_update_id
@update_channel.send get_updates 10 rescue
when Control
break
end end
end end
end
spawn do @poll_end_hooks.each do |hook|
loop do hook.call
item = @update_channel.receive
case item
when Array(Update)
process_updates(item)
@poll_channel.send item.last?.try &.update_id
when Control
@poll_channel.send item
break
end
end end
end end
end end
@@ -112,18 +101,15 @@ module Telepathy
def poll def poll
if !@poll_running if !@poll_running
@poll_running = true @poll_running = true
spawn_workers @poll_start_hooks.each do |hook|
@poll_channel.send nil hook.call
@poll_start_hooks.each &.call end
spawn_worker
end end
end end
def end_poll def end_poll
if @poll_running @poll_running = false
@poll_running = false
@poll_channel.send Control::Done
@poll_end_hooks.each &.call
end
end end
end end
end end

View File

@@ -2,13 +2,24 @@ require "json"
module Telepathy module Telepathy
class Audio class Audio
JSON.mapping( include JSON::Serializable
file_id: String,
duration: Int64, @[JSON::Field(key: "file_id")]
performer: String?, property file_id : String
title: String?,
mime_type: String?, @[JSON::Field(key: "duration")]
file_size: Int64? property duration : Int64
)
@[JSON::Field(key: "performer")]
property performer : String?
@[JSON::Field(key: "title")]
property title : String?
@[JSON::Field(key: "mime_type")]
property mime_type : String?
@[JSON::Field(key: "file_size")]
property file_size : Int64?
end end
end end

View File

@@ -3,20 +3,42 @@ require "./message.cr"
module Telepathy module Telepathy
class Chat class Chat
JSON.mapping( include JSON::Serializable
id: Int64,
type: String, @[JSON::Field(key: "id")]
title: String?, property id : Int64
username: String?,
first_name: String?, @[JSON::Field(key: "type")]
last_name: String?, property type : String
all_members_are_administrators: Bool?,
# TODO photo @[JSON::Field(key: "title")]
description: String?, property title : String?
invite_link: String?,
pinned_message: Message?, @[JSON::Field(key: "username")]
sticker_set_name: String?, property username : String?
can_set_sticker_set: Bool?
) @[JSON::Field(key: "first_name")]
property first_name : String?
@[JSON::Field(key: "last_name")]
property last_name : String?
@[JSON::Field(key: "all_members_are_administrators")]
property all_members_are_administrators : Bool?
@[JSON::Field(key: "description")]
property description : String?
@[JSON::Field(key: "invite_link")]
property invite_link : String?
@[JSON::Field(key: "pinned_message")]
property pinned_message : Message?
@[JSON::Field(key: "sticker_set_name")]
property sticker_set_name : String?
@[JSON::Field(key: "can_set_sticker_set")]
property can_set_sticker_set : Bool?
end end
end end

View File

@@ -2,11 +2,18 @@ require "json"
module Telepathy module Telepathy
class Contact class Contact
JSON.mapping( include JSON::Serializable
phone_number: String,
first_name: String, @[JSON::Field(key: "phone_number")]
last_name: String?, property phone_number : String
user_id: Int64?
) @[JSON::Field(key: "first_name")]
property first_name : String
@[JSON::Field(key: "last_name")]
property last_name : String?
@[JSON::Field(key: "user_id")]
property user_id : Int64?
end end
end end

View File

@@ -3,12 +3,21 @@ require "./photo_size.cr"
module Telepathy module Telepathy
class Document class Document
JSON.mapping( include JSON::Serializable
file_id: String,
thumb: PhotoSize?, @[JSON::Field(key: "file_id")]
file_name: String?, property file_id : String
mime_type: String?,
file_size: Int64? @[JSON::Field(key: "thumb")]
) property thumb : PhotoSize?
@[JSON::Field(key: "file_name")]
property file_name : String?
@[JSON::Field(key: "mime_type")]
property mime_type : String?
@[JSON::Field(key: "file_size")]
property file_size : Int64?
end end
end end

View File

@@ -2,9 +2,12 @@ require "json"
module Telepathy module Telepathy
class Location class Location
JSON.mapping( include JSON::Serializable
longitude: Float32,
latitude: Float32 @[JSON::Field(key: "longitude")]
) property longitude : Float32
@[JSON::Field(key: "latitude")]
property latitude : Float32
end end
end end

View File

@@ -14,48 +14,114 @@ require "./venue.cr"
module Telepathy module Telepathy
class Message class Message
JSON.mapping( include JSON::Serializable
message_id: Int64,
from: User?, @[JSON::Field(key: "message_id")]
date: Int64, property message_id : Int64
chat: Chat,
forward_from: User?, @[JSON::Field(key: "from")]
forward_from_chat: Chat?, property from : User?
forward_from_message_id: Int64?,
forward_signature: String?, @[JSON::Field(key: "date")]
forward_date: Int64?, property date : Int64
reply_to_message: Message?,
edit_date: Int64?, @[JSON::Field(key: "chat")]
media_group_id: String?, property chat : Chat
author_signature: String?,
text: String?, @[JSON::Field(key: "forward_from")]
entities: Array(MessageEntity)?, property forward_from : User?
caption_entities: Array(MessageEntity)?,
audio: Audio?, @[JSON::Field(key: "forward_from_chat")]
document: Document?, property forward_from_chat : Chat?
photo: Array(PhotoSize)?,
video: Video?, @[JSON::Field(key: "forward_from_message_id")]
voice: Voice?, property forward_from_message_id : Int64?
video_note: VideoNote?,
# TODO game @[JSON::Field(key: "forward_signature")]
# TODO sticker property forward_signature : String?
caption: String?,
contact: Contact?, @[JSON::Field(key: "forward_date")]
location: Location?, property forward_date : Int64?
venue: Venue?,
new_chat_members: Array(User)?, @[JSON::Field(key: "reply_to_message")]
left_chat_member: User?, property reply_to_message : Message?
new_chat_title: String?,
# new_chat_photo @[JSON::Field(key: "edit_date")]
delete_chat_photo: Bool?, property edit_date : Int64?
group_chat_created: Bool?,
supergroup_chat_created: Bool?, @[JSON::Field(key: "media_group_id")]
channel_chat_created: Bool?, property media_group_id : String?
migrate_to_chat_id: Int64?,
migrate_from_chat_id: Int64?, @[JSON::Field(key: "author_signature")]
pinned_message: Message? property author_signature : String?
# invoice
# successful_payment @[JSON::Field(key: "text")]
) property text : String?
@[JSON::Field(key: "entities")]
property entities : Array(MessageEntity)?
@[JSON::Field(key: "caption_entities")]
property caption_entities : Array(MessageEntity)?
@[JSON::Field(key: "audio")]
property audio : Audio?
@[JSON::Field(key: "document")]
property document : Document?
@[JSON::Field(key: "photo")]
property photo : Array(PhotoSize)?
@[JSON::Field(key: "video")]
property video : Video?
@[JSON::Field(key: "voice")]
property voice : Voice?
@[JSON::Field(key: "video_note")]
property video_note : VideoNote?
@[JSON::Field(key: "caption")]
property caption : String?
@[JSON::Field(key: "contact")]
property contact : Contact?
@[JSON::Field(key: "location")]
property location : Location?
@[JSON::Field(key: "venue")]
property venue : Venue?
@[JSON::Field(key: "new_chat_members")]
property new_chat_members : Array(User)?
@[JSON::Field(key: "left_chat_member")]
property left_chat_member : User?
@[JSON::Field(key: "new_chat_title")]
property new_chat_title : String?
@[JSON::Field(key: "delete_chat_photo")]
property delete_chat_photo : Bool?
@[JSON::Field(key: "group_chat_created")]
property group_chat_created : Bool?
@[JSON::Field(key: "supergroup_chat_created")]
property supergroup_chat_created : Bool?
@[JSON::Field(key: "channel_chat_created")]
property channel_chat_created : Bool?
@[JSON::Field(key: "migrate_to_chat_id")]
property migrate_to_chat_id : Int64?
@[JSON::Field(key: "migrate_from_chat_id")]
property migrate_from_chat_id : Int64?
@[JSON::Field(key: "pinned_message")]
property pinned_message : Message?
end end
end end

View File

@@ -3,12 +3,21 @@ require "./user.cr"
module Telepathy module Telepathy
class MessageEntity class MessageEntity
JSON.mapping( include JSON::Serializable
type: String,
offset: Int64, @[JSON::Field(key: "type")]
length: Int64, property type : String
url: String?,
user: User? @[JSON::Field(key: "offset")]
) property offset : Int64
@[JSON::Field(key: "length")]
property length : Int64
@[JSON::Field(key: "url")]
property url : String?
@[JSON::Field(key: "user")]
property user : User?
end end
end end

View File

@@ -2,11 +2,18 @@ require "json"
module Telepathy module Telepathy
class PhotoSize class PhotoSize
JSON.mapping( include JSON::Serializable
file_id: String?,
width: Int64, @[JSON::Field(key: "file_id")]
height: Int64, property file_id : String?
file_size: Int64?
) @[JSON::Field(key: "width")]
property width : Int64
@[JSON::Field(key: "height")]
property height : Int64
@[JSON::Field(key: "file_size")]
property file_size : Int64?
end end
end end

View File

@@ -2,9 +2,12 @@ require "json"
module Telepathy module Telepathy
class Response(T) class Response(T)
JSON.mapping( include JSON::Serializable
ok: Bool,
result: T @[JSON::Field(key: "ok")]
) property ok : Bool
@[JSON::Field(key: "result")]
property result : T
end end
end end

View File

@@ -2,17 +2,21 @@ require "json"
module Telepathy module Telepathy
class Update class Update
JSON.mapping( include JSON::Serializable
update_id: Int64,
message: Message?, @[JSON::Field(key: "update_id")]
edited_message: Message?, property update_id : Int64
channel_post: Message?,
edited_channel_post: Message? @[JSON::Field(key: "message")]
# TODO inline_query property message : Message?
# TODO chosen_inline_result
# TODO callback_query @[JSON::Field(key: "edited_message")]
# shipping_query property edited_message : Message?
# pre_checkout_query
) @[JSON::Field(key: "channel_post")]
property channel_post : Message?
@[JSON::Field(key: "edited_channel_post")]
property edited_channel_post : Message?
end end
end end

View File

@@ -2,13 +2,24 @@ require "json"
module Telepathy module Telepathy
class User class User
JSON.mapping( include JSON::Serializable
id: Int64,
is_bot: Bool, @[JSON::Field(key: "id")]
first_name: String, property id : Int64
last_name: String?,
username: String?, @[JSON::Field(key: "is_bot")]
language_code: String? property is_bot : Bool
)
@[JSON::Field(key: "first_name")]
property first_name : String
@[JSON::Field(key: "last_name")]
property last_name : String?
@[JSON::Field(key: "username")]
property username : String?
@[JSON::Field(key: "language_code")]
property language_code : String?
end end
end end

View File

@@ -3,11 +3,18 @@ require "./location.cr"
module Telepathy module Telepathy
class Venue class Venue
JSON.mapping( include JSON::Serializable
location: Location,
title: String, @[JSON::Field(key: "location")]
address: String, property location : Location
foursquare_id: String?
) @[JSON::Field(key: "title")]
property title : String
@[JSON::Field(key: "address")]
property address : String
@[JSON::Field(key: "foursquare_id")]
property foursquare_id : String?
end end
end end

View File

@@ -3,14 +3,27 @@ require "./photo_size.cr"
module Telepathy module Telepathy
class Video class Video
JSON.mapping( include JSON::Serializable
file_id: String,
width: Int64, @[JSON::Field(key: "file_id")]
height: Int64, property file_id : String
duration: Int64,
thumb: PhotoSize?, @[JSON::Field(key: "width")]
mime_type: String?, property width : Int64
file_size: Int64?
) @[JSON::Field(key: "height")]
property height : Int64
@[JSON::Field(key: "duration")]
property duration : Int64
@[JSON::Field(key: "thumb")]
property thumb : PhotoSize?
@[JSON::Field(key: "mime_type")]
property mime_type : String?
@[JSON::Field(key: "file_size")]
property file_size : Int64?
end end
end end

View File

@@ -3,12 +3,21 @@ require "./photo_size.cr"
module Telepathy module Telepathy
class VideoNote class VideoNote
JSON.mapping( include JSON::Serializable
file_id: String,
length: Int64, @[JSON::Field(key: "file_id")]
duration: Int64, property file_id : String
thumb: PhotoSize?,
file_size: Int64? @[JSON::Field(key: "length")]
) property length : Int64
@[JSON::Field(key: "duration")]
property duration : Int64
@[JSON::Field(key: "thumb")]
property thumb : PhotoSize?
@[JSON::Field(key: "file_size")]
property file_size : Int64?
end end
end end

View File

@@ -3,11 +3,18 @@ require "./photo_size.cr"
module Telepathy module Telepathy
class Voice class Voice
JSON.mapping( include JSON::Serializable
file_id: String,
duration: Int64, @[JSON::Field(key: "file_id")]
mime_type: String?, property file_id : String
file_size: Int64?
) @[JSON::Field(key: "duration")]
property duration : Int64
@[JSON::Field(key: "mime_type")]
property mime_type : String?
@[JSON::Field(key: "file_size")]
property file_size : Int64?
end end
end end

View File

@@ -3,7 +3,9 @@ module Telepathy::Utils
API_URL = "https://api.telegram.org/bot" API_URL = "https://api.telegram.org/bot"
enum ParseMode enum ParseMode
Normal, Markdown, HTML Normal
Markdown
HTML
end end
def get_me(api_key : String) def get_me(api_key : String)

View File

@@ -1,3 +1,3 @@
module Telepathy module Telepathy
VERSION = "0.1.0" VERSION = "0.1.1"
end end