telegram-rb 0.1.0

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5eca42b752465bba38de5c76c31efdc2782c402f
4
+ data.tar.gz: 4dc3258d4b4d17c4b245320e3eb37e1f6458bb91
5
+ SHA512:
6
+ metadata.gz: fd11d9f7e7db37260933db545884a9306f54317fd727d24dbdb6fc9007f78b2181dc8d4eb0d89275d6fec334bb6c69e491f8f8bd218735417f8af82470ddc818
7
+ data.tar.gz: c3572018df7cba228ec57c5d6f82c133efcaf5aad283e31112ec0bd8e52069e0c5fe2ff36eaf0ed8b9ef8699174bd16808bfcbe802cff8d7e80616b1858e0522
@@ -0,0 +1,42 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /test/tmp/
9
+ /test/version_tmp/
10
+ /tmp/
11
+
12
+ ## Specific to RubyMotion:
13
+ .dat*
14
+ .repl_history
15
+ build/
16
+
17
+ ## Documentation cache and generated files:
18
+ /.yardoc/
19
+ /_yardoc/
20
+ /doc/
21
+ /rdoc/
22
+
23
+ ## Environment normalisation:
24
+ /.bundle/
25
+ /vendor/bundle
26
+ /lib/bundler/man/
27
+
28
+ # for a library or gem, you might want to ignore these files since the code is
29
+ # intended to run in multiple environments; otherwise, check them in:
30
+ # Gemfile.lock
31
+ # .ruby-version
32
+ # .ruby-gemset
33
+
34
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
35
+ .rvmrc
36
+
37
+ # OS X
38
+ .DS_Store
39
+
40
+ # Telegram
41
+ telegram-cli
42
+ tg-server.pub
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'eventmachine'
4
+ gem 'em-synchrony'
5
+ gem 'oj'
6
+
7
+ # irb
8
+ gem 'rubysl-irb'
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 SuHun Han
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
@@ -0,0 +1,14 @@
1
+ # Telegram API for Ruby!
2
+
3
+ [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/ssut/telegram-rb?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
4
+
5
+ [![Code Climate](https://codeclimate.com/github/ssut/telegram-rb/badges/gpa.svg)](https://codeclimate.com/github/ssut/telegram-rb)
6
+
7
+ A Ruby wrapper that communicates with the [Telegram-CLI](https://github.com/vysheng/tg).
8
+
9
+ ## Installation
10
+
11
+ ### Requirements
12
+
13
+ * You need to install the [Telegram-CLI](https://github.com/vysheng/tg) first.
14
+
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+ lib = File.join(File.dirname(__FILE__), 'lib')
3
+ $:.unshift lib unless $:.include?(lib)
4
+
5
+ require 'eventmachine'
6
+ require 'telegram'
7
+
8
+ EM.run do
9
+ telegram = Telegram::Client.new do |cfg|
10
+ cfg.daemon = './telegram-cli'
11
+ cfg.key = '/Users/ssut/tmp/tg/tg-server.pub'
12
+ end
13
+
14
+ telegram.connect do
15
+ puts telegram.profile
16
+ telegram.contacts.each do |contact|
17
+ puts contact
18
+ end
19
+ telegram.chats.each do |chat|
20
+ puts chat
21
+ end
22
+
23
+ telegram.on[Telegram::EventType::RECEIVE_MESSAGE] = Proc.new { |ev|
24
+
25
+ }
26
+
27
+ end
28
+ end
@@ -0,0 +1,3 @@
1
+ require 'telegram/version'
2
+ require 'telegram/client'
3
+
@@ -0,0 +1,115 @@
1
+ module Telegram
2
+ class API
3
+ def update!(&cb)
4
+ done = false
5
+ EM.synchrony do
6
+ multi = EM::Synchrony::Multi.new
7
+ multi.add :profile, update_profile!
8
+ multi.add :contacts, update_contacts!
9
+ multi.add :chats, update_chats!
10
+ multi.perform
11
+ done = true
12
+ end
13
+
14
+ check_done = Proc.new {
15
+ if done
16
+ @starts_at = Time.now
17
+ cb.call unless cb.nil?
18
+ logger.info("Successfully loaded all information")
19
+ else
20
+ EM.next_tick(&check_done)
21
+ end
22
+ }
23
+ EM.add_timer(0, &check_done)
24
+ end
25
+
26
+ def update_profile!
27
+ assert!
28
+ callback = Callback.new
29
+ @profile = nil
30
+ @connection.communicate('get_self') do |success, data|
31
+ if success
32
+ callback.trigger(:success)
33
+ contact = TelegramContact.pick_or_new(self, data)
34
+ @contacts << contact unless self.contacts.include?(contact)
35
+ @profile = contact
36
+ else
37
+ raise "Couldn't fetch the user profile."
38
+ end
39
+ end
40
+ callback
41
+ end
42
+
43
+ def update_contacts!
44
+ assert!
45
+ callback = Callback.new
46
+ @contacts = []
47
+ @connection.communicate('contact_list') do |success, data|
48
+ if success and data.class == Array
49
+ callback.trigger(:success)
50
+ data.each { |contact|
51
+ contact = TelegramContact.pick_or_new(self, contact)
52
+ @contacts << contact unless self.contacts.include?(contact)
53
+ }
54
+ else
55
+ raise "Couldn't fetch the contact list."
56
+ end
57
+ end
58
+ callback
59
+ end
60
+
61
+ def update_chats!
62
+ assert!
63
+ callback = Callback.new
64
+ collected = 0
65
+
66
+ collect_done = Proc.new { |id, data, count|
67
+ collected += 1
68
+ @chats << TelegramChat.new(self, data)
69
+ callback.trigger(:success) if collected == count
70
+ }
71
+ collect = Proc.new { |id, count|
72
+ @connection.communicate(['chat_info', "chat\##{id}"]) do |success, data|
73
+ collect_done.call(id, data, count) if success
74
+ end
75
+ }
76
+
77
+ @chats = []
78
+ @connection.communicate('dialog_list') do |success, data|
79
+ if success and data.class == Array
80
+ chatsize = data.count { |chat| chat['type'] == 'chat' }
81
+ data.each { |chat|
82
+ if chat['type'] == 'chat'
83
+ collect.call(chat['id'], chatsize)
84
+ elsif chat['type'] == 'user'
85
+ @chats << TelegramChat.new(self, chat)
86
+ end
87
+ }
88
+ else
89
+ raise "Couldn't fetch the dialog(chat) list."
90
+ end
91
+ end
92
+ callback
93
+ end
94
+
95
+ def msg(target, text, &callback)
96
+ assert!
97
+ @connection.communicate(['msg', target, text], &callback)
98
+ end
99
+
100
+ def chat_add_user(chat, user, &callback)
101
+ assert!
102
+ @connection.communicate(['chat_add_user', chat.to_tg, user.to_tg], &callback)
103
+ end
104
+
105
+ def chat_del_user(chat, user, &callback)
106
+ assert!
107
+ @connection.communicate(['chat_del_user', chat.to_tg, user.to_tg], &callback)
108
+ end
109
+
110
+ protected
111
+ def assert!
112
+ raise "It appears that the connection to the telegram-cli is disconnected." unless connected?
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,29 @@
1
+ module Telegram
2
+ class Callback
3
+ attr_reader :data
4
+
5
+ def initialize
6
+ @success = nil
7
+ @fail = nil
8
+ @data = nil
9
+ end
10
+
11
+ def callback(&cb)
12
+ @success = cb
13
+ end
14
+
15
+ def errback(&cb)
16
+ @fail = cb
17
+ end
18
+
19
+ def trigger(type = :success, data = nil)
20
+ @data = data
21
+ case type
22
+ when :success
23
+ @success.call
24
+ when :fail
25
+ @fail.call
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,148 @@
1
+ # encoding: utf-8
2
+ require 'eventmachine'
3
+ require "em-synchrony"
4
+ require 'em-synchrony/fiber_iterator'
5
+ require 'ostruct'
6
+ require 'oj'
7
+ require 'shellwords'
8
+ require 'date'
9
+
10
+ require 'telegram/logger'
11
+ require 'telegram/connection'
12
+ require 'telegram/connection_pool'
13
+ require 'telegram/callback'
14
+ require 'telegram/api'
15
+ require 'telegram/models'
16
+ require 'telegram/events'
17
+
18
+ module Telegram
19
+ class Client < API
20
+ include Logging
21
+
22
+ attr_reader :connection
23
+
24
+ attr_reader :profile
25
+ attr_reader :contacts
26
+ attr_reader :chats
27
+
28
+ attr_accessor :on
29
+
30
+ def initialize(&b)
31
+ @config = OpenStruct.new(:daemon => 'bin/telegram', :key => 'tg-server.pub', :sock => 'tg.sock', :size => 5)
32
+ yield @config
33
+ @connected = 0
34
+ @stdout = nil
35
+ @connect_callback = nil
36
+ @on = {}
37
+
38
+ @profile = nil
39
+ @contacts = []
40
+ @chats = []
41
+ @starts_at = nil
42
+ @events = EM::Queue.new
43
+
44
+ logger.info("Initialized")
45
+ end
46
+
47
+ def execute
48
+ command = "'#{@config.daemon}' -Ck '#{@config.key}' -I -WS '#{@config.sock}' --json"
49
+ @stdout = IO.popen(command)
50
+ loop do
51
+ if t = @stdout.readline then
52
+ break if t.include?('I: config')
53
+ end
54
+ end
55
+ proc {}
56
+ end
57
+
58
+ def poll
59
+ data = ''
60
+ logger.info("Start polling for events")
61
+ loop do
62
+ begin
63
+ byte = @stdout.read_nonblock 1
64
+ rescue IO::WaitReadable
65
+ IO.select([@stdout])
66
+ retry
67
+ rescue EOFError
68
+ logger.error("EOFError occurred during the polling")
69
+ return
70
+ end
71
+ data << byte unless @starts_at.nil?
72
+ if byte.include?("\n")
73
+ begin
74
+ brace = data.index('{')
75
+ data = data[brace..-2]
76
+ data = Oj.load(data)
77
+ @events << data
78
+ rescue
79
+ end
80
+ data = ''
81
+ end
82
+ end
83
+ end
84
+
85
+ def process_data
86
+ process = Proc.new { |data|
87
+ begin
88
+ type = case data['event']
89
+ when 'message'
90
+ if data['from']['id'] != @profile.id
91
+ EventType::RECEIVE_MESSAGE
92
+ else
93
+ EventType::SEND_MESSAGE
94
+ end
95
+ end
96
+
97
+ action = data.has_key?('action') ? case data['action']
98
+ when 'chat_add_user'
99
+ ActionType::CHAT_ADD_USER
100
+ else
101
+ ActionType::UNKNOWN_ACTION
102
+ end : ActionType::NO_ACTION
103
+
104
+ event = Event.new(self, type, action, data)
105
+ @on[type].call(event) if @on.has_key?(type)
106
+ rescue Exception => e
107
+ logger.error("Error occurred during the processing: #{data}\n #{e.inspect} #{e.backtrace}")
108
+ end
109
+ @events.pop(&process)
110
+ }
111
+ @events.pop(&process)
112
+ end
113
+
114
+ def connect(&block)
115
+ logger.info("Trying to start telegram-cli and then connect")
116
+ @connect_callback = block
117
+ process_data
118
+ EM.defer(execute, create_pool)
119
+ end
120
+
121
+ def create_pool
122
+ @connection = ConnectionPool.new(@config.size) do
123
+ client = EM.connect_unix_domain(@config.sock, Connection)
124
+ client.on_connect = self.method(:on_connect)
125
+ client.on_disconnect = self.method(:on_disconnect)
126
+ client
127
+ end
128
+ proc {}
129
+ end
130
+
131
+ def on_connect
132
+ @connected += 1
133
+ if connected?
134
+ logger.info("Successfully connected to the Telegram CLI")
135
+ EM.defer(&method(:poll))
136
+ update!(&@connect_callback)
137
+ end
138
+ end
139
+
140
+ def on_disconnect
141
+ @connected -= 1
142
+ end
143
+
144
+ def connected?
145
+ @connected == @config.size
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,73 @@
1
+ module Telegram
2
+ class Connection < EM::Connection
3
+ def initialize
4
+ super
5
+ @connected = false
6
+ @on_connect = nil
7
+ @on_disconnect = nil
8
+ @callback = nil
9
+ @available = true
10
+ end
11
+
12
+ def available?
13
+ @available
14
+ end
15
+
16
+ def communicate(*messages, &callback)
17
+ @available = false
18
+ @callback = callback
19
+ messages = messages.each_with_index.map { |m, i|
20
+ if i > 0
21
+ m = "\"#{m}\""
22
+ end
23
+ m
24
+ }.join(' ') << "\n"
25
+ send_data(messages)
26
+ end
27
+
28
+ def on_connect=(block)
29
+ @on_connect = block
30
+ end
31
+
32
+ def on_disconnect=(block)
33
+ @on_disconnect = block
34
+ end
35
+
36
+ # @api private
37
+ def connection_completed
38
+ @connected = true
39
+ @on_connect.call unless @on_connect.nil?
40
+ end
41
+
42
+ def unbind
43
+ @connected = false
44
+ @on_disconnect.call unless @on_disconnect.nil?
45
+ end
46
+
47
+ def connected?
48
+ @connected
49
+ end
50
+
51
+ def receive_data(data)
52
+ begin
53
+ result = _receive_data(data)
54
+ rescue
55
+ result = nil
56
+ end
57
+ @callback.call(!result.nil?, result) unless @callback.nil?
58
+ @callback = nil
59
+ @available = true
60
+ end
61
+
62
+ protected
63
+ def _receive_data(data)
64
+ if data[0..6] == 'ANSWER '
65
+ lf = data.index("\n") + 1
66
+ lflf = data.index("\n\n", lf) - 1
67
+ data = data[lf..lflf]
68
+ data = Oj.load(data)
69
+ end
70
+ data
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,37 @@
1
+ module Telegram
2
+ class ConnectionPool < Array
3
+ include Logging
4
+
5
+ attr_reader :size
6
+
7
+ def initialize(size=10, &block)
8
+ size.times do
9
+ self << block.call if block_given?
10
+ end
11
+ end
12
+
13
+ def communicate(*messages, &block)
14
+ begin
15
+ acquire do |conn|
16
+ conn.communicate(*messages, &block)
17
+ end
18
+ rescue Exception => e
19
+ logger.error("Error occurred during the communicating: #{e.inspect} #{e.backtrace}")
20
+ end
21
+
22
+ end
23
+
24
+ def acquire(&callback)
25
+ acq = Proc.new {
26
+ conn = self.find { |conn| conn.available? }
27
+ if not conn.nil? and conn.connected?
28
+ callback.call(conn)
29
+ else
30
+ logger.warning("Failed to acquire available connection, retry after 0.1 second")
31
+ EM.add_timer(0.1, &acq)
32
+ end
33
+ }
34
+ EM.add_timer(0, &acq)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,117 @@
1
+ module Telegram
2
+ module EventType
3
+ UNKNOWN_EVENT = -1
4
+ SERVICE = 0
5
+ RECEIVE_MESSAGE = 1
6
+ SEND_MESSAGE = 2
7
+ ONLINE_STATUS = 3
8
+ end
9
+
10
+ module ActionType
11
+ UNKNOWN_ACTION = -1
12
+ NO_ACTION = 0
13
+ CHAT_ADD_USER = 1
14
+ CHAT_DEL_USER = 2
15
+ CHAT_RENAME = 3
16
+ end
17
+
18
+ class Message < Struct.new(:text, :type, :from, :from_type, :raw_from, :to, :to_type, :raw_to); end
19
+
20
+ class Event
21
+ # @return [Number]
22
+ attr_reader :id
23
+
24
+ # @return [EventType]
25
+ attr_reader :event
26
+
27
+ # @return [ActionType]
28
+ attr_reader :action
29
+
30
+ # @return [Time]
31
+ attr_reader :time
32
+
33
+ # @return [Message]
34
+ attr_reader :message
35
+
36
+ # @return [TelegramMessage]
37
+ attr_reader :tgmessage
38
+
39
+ def initialize(client, event = EventType::UNKNOWN_EVENT, action = ActionType::NO_ACTION, data = {})
40
+ @client = client
41
+ @message = nil
42
+ @tgmessage = nil
43
+ @raw_data = data
44
+ @time = nil
45
+
46
+ @event = event
47
+ @action = action
48
+
49
+ @time = Time.at(data['date'].to_i) if data.has_key?('date')
50
+ @time = DateTime.strptime(data['when'], "%Y-%m-%d %H:%M:%S") if @time.nil? and data.has_key?('when')
51
+
52
+ case event
53
+ when EventType::SERVICE
54
+ foramt_service
55
+ when EventType::RECEIVE_MESSAGE, EventType::SEND_MESSAGE
56
+ format_message
57
+ @tgmessage = TelegramMessage.new(@client, self)
58
+ when EventType::ONLINE_STATUS
59
+ foramt_status
60
+ end
61
+ end
62
+
63
+ def format_service
64
+
65
+ end
66
+
67
+ def format_message
68
+ message = Message.new
69
+ message.text = @raw_data['text']
70
+ message.type = @raw_data.has_key?('media') ? @raw_data['media']['type'] : 'text'
71
+ message.raw_from = @raw_data['from']['id']
72
+ message.from_type = @raw_data['from']['type']
73
+ message.raw_to = @raw_data['to']['id']
74
+ message.to_type = @raw_data['to']['type']
75
+
76
+ from = @client.contacts.find { |c| c.id == message.raw_from }
77
+ to = @client.contacts.find { |c| c.id == message.raw_to }
78
+ to = @client.chats.find { |c| c.id == message.raw_to } if to.nil?
79
+
80
+ message.from = from
81
+ message.to = to
82
+
83
+ @message = message
84
+
85
+ if @message.from.nil?
86
+ user = @raw_data['from']
87
+ user = TelegramContact.pick_or_new(@client, user)
88
+ @client.contacts << user unless @client.contacts.include?(user)
89
+ @message.from = user
90
+ end
91
+
92
+ if @message.to.nil?
93
+ type = @raw_data['to']['type']
94
+ if type == 'chat'
95
+ chat = @raw_data['to']
96
+ chat = TelegramChat.pick_or_new(@client, chat)
97
+ @client.chats << chat unless @client.chats.include?(chat)
98
+ @message.from = chat
99
+ elsif type == 'user'
100
+ user = @raw_data['to']
101
+ user = TelegramContact.pick_or_new(@client, user)
102
+ @client.contacts << user unless @client.contacts.include?(user)
103
+ @message.to = user
104
+ elsif type == 'encr_chat'
105
+ chat = @raw_data['to']
106
+ chat = TelegramChat.pick_or_new(@client, chat)
107
+ @client.chats << chat unless @client.chats.include?(chat)
108
+ @message.to = chat
109
+ end
110
+ end
111
+ end
112
+
113
+ def to_s
114
+ "<Event Type=#{@event} Action=#{@action} Time=#{@time} Message=#{@message}>"
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,29 @@
1
+ require 'logger'
2
+
3
+ module Telegram
4
+ module Logging
5
+ def logger
6
+ @logger ||= Logging.logger_for(self.class.name)
7
+ end
8
+
9
+ @loggers = {}
10
+ class << self
11
+ def logger_for(klass)
12
+ @loggers[klass] ||= configure_logger_for(klass)
13
+ end
14
+
15
+ def configure_logger_for(klass)
16
+ logger = Logger.new(STDOUT)
17
+ logger.progname = klass
18
+ logger.level = Logger::DEBUG
19
+ logger.formatter = proc do |severity, datetime, progname, msg|
20
+ date_format = datetime.strftime('%Y-%m-%d %H:%M:%S')
21
+ blanks = severity.size == 4 ? ' ' : ' '
22
+ "[#{date_format}] #{severity}#{blanks}(#{progname}): #{msg}\n"
23
+ end
24
+
25
+ logger
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,167 @@
1
+ module Telegram
2
+ class TelegramBase
3
+ attr_reader :client
4
+ attr_reader :id
5
+
6
+ def send_message(text, refer)
7
+ target = case @type
8
+ when 'encr_chat'
9
+ "#{@title}"
10
+ else
11
+ to_tg
12
+ end
13
+ @client.msg(target, text)
14
+ end
15
+
16
+ def send_sticker()
17
+
18
+ end
19
+
20
+ def send_image(path, refer, &callback)
21
+
22
+ end
23
+
24
+ def send_image_url(url, refer, &callback)
25
+
26
+ end
27
+ end
28
+
29
+ class TelegramChat < TelegramBase
30
+ attr_reader :name
31
+ attr_reader :members
32
+ attr_reader :type
33
+
34
+ def self.pick_or_new(client, chat)
35
+ ct = client.chats.find { |c| c.id == chat['id'] }
36
+ return ct unless ct.nil?
37
+ TelegramChat.new(client, chat)
38
+ end
39
+
40
+ def initialize(client, chat)
41
+ @client = client
42
+ @chat = chat
43
+
44
+ @id = chat['id']
45
+ @title = chat.has_key?('title') ? chat['title'] : chat['print_name']
46
+ @type = chat['type']
47
+
48
+ @members = []
49
+ if chat.has_key?('members')
50
+ chat['members'].each { |user|
51
+ @members << TelegramContact.pick_or_new(client, user)
52
+ }
53
+ elsif @type == 'user' and chat['user']
54
+ @members << TelegramContact.pick_or_new(client, chat)
55
+ end
56
+ end
57
+
58
+ def leave!
59
+ @client.chat_del_user(self, @client.profile)
60
+ end
61
+
62
+ def to_tg
63
+ "#{@type}\##{@id}"
64
+ end
65
+
66
+ def to_s
67
+ "<TelegramChat #{@title}(#{@type}\##{@id}) members=#{@members.size}>"
68
+ end
69
+ end
70
+
71
+ class TelegramContact < TelegramBase
72
+ attr_reader :name
73
+ attr_reader :phone
74
+ attr_reader :type
75
+
76
+ def self.pick_or_new(client, contact)
77
+ ct = client.contacts.find { |c| c.id == contact['id'] }
78
+ return ct unless ct.nil?
79
+ TelegramContact.new(client, contact)
80
+ end
81
+
82
+ def initialize(client, contact)
83
+ @client = client
84
+ @contact = contact
85
+
86
+ @id = contact['id']
87
+ @type = 'user'
88
+ @username = contact.has_key?('username') ? contact['username'] : ''
89
+ @name = contact['print_name']
90
+ @phone = contact.has_key?('phone') ? contact['phone'] : ''
91
+
92
+ @client.contacts << self unless @client.contacts.include?(self)
93
+ end
94
+
95
+ def chats
96
+ @client.chats.select { |c| c.member.include?(self) }
97
+ end
98
+
99
+ def to_tg
100
+ "#{@type}\##{@id}"
101
+ end
102
+
103
+ def to_s
104
+ "<TelegramContact #{@name}(#{@id}) username=#{@username}>"
105
+ end
106
+ end
107
+
108
+ class TelegramMessage
109
+ # @return [Telegram]
110
+ attr_reader :client
111
+
112
+ # @return [String]
113
+ attr_reader :raw
114
+
115
+ # @return [Integer]
116
+ attr_reader :id
117
+
118
+ # @return [Time]
119
+ attr_reader :time
120
+
121
+ # @return [TelegramContact] The user who sent this message
122
+ attr_reader :user
123
+
124
+ # targets to send a message
125
+ attr_reader :raw_target
126
+ attr_reader :target
127
+
128
+ # @return [TelegramChat]
129
+ attr_reader :chat
130
+
131
+ def initialize(client, event)
132
+ @event = event
133
+
134
+ @id = event.id
135
+ @raw = event.message.text
136
+ @time = event.time
137
+ @content_type = event.message.type
138
+
139
+ @raw_sender = event.message.raw_from
140
+ @raw_receiver = event.message.raw_to
141
+
142
+ @user = @sender = event.message.from
143
+ @receiver = event.message.to
144
+
145
+ @target = case @receiver.type
146
+ when 'user'
147
+ @sender
148
+ when 'chat', 'encr_chat'
149
+ @receiver
150
+ end
151
+ end
152
+
153
+ def reply_user(type, content)
154
+
155
+ end
156
+
157
+ def reply(type, content, target=nil, &cb)
158
+ target = @target if target.nil?
159
+ if type == :text
160
+ target.send_message(content, self)
161
+ elsif type == :sticker
162
+ elsif type == :image
163
+ end
164
+
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,4 @@
1
+ module Telegram
2
+ # version of the library
3
+ VERSION = '0.1.0'
4
+ end
@@ -0,0 +1,17 @@
1
+ lib = File.join(File.dirname(__FILE__), 'lib')
2
+ $:.unshift lib unless $:.include?(lib)
3
+
4
+ require 'telegram/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.date = Date.today.to_s
8
+ s.name = 'telegram-rb'
9
+ s.version = Telegram::VERSION
10
+ s.licenses = ['MIT']
11
+ s.summary = 'A Ruby wrapper that communicates with the telegram-cli.'
12
+ s.description = "A Ruby wrapper that communicates with the telegram-cli."
13
+ s.authors = ["SuHun Han (ssut)"]
14
+ s.email = 'ssut@ssut.me'
15
+ s.files = `git ls-files`.split("\n")
16
+ s.homepage = 'https://github.com/ssut/telegram-rb'
17
+ end
metadata ADDED
@@ -0,0 +1,59 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: telegram-rb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - SuHun Han (ssut)
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-07-06 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A Ruby wrapper that communicates with the telegram-cli.
14
+ email: ssut@ssut.me
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - ".gitignore"
20
+ - Gemfile
21
+ - LICENSE
22
+ - README.md
23
+ - example.rb
24
+ - lib/telegram.rb
25
+ - lib/telegram/api.rb
26
+ - lib/telegram/callback.rb
27
+ - lib/telegram/client.rb
28
+ - lib/telegram/connection.rb
29
+ - lib/telegram/connection_pool.rb
30
+ - lib/telegram/events.rb
31
+ - lib/telegram/logger.rb
32
+ - lib/telegram/models.rb
33
+ - lib/telegram/version.rb
34
+ - telegram-rb.gemspec
35
+ homepage: https://github.com/ssut/telegram-rb
36
+ licenses:
37
+ - MIT
38
+ metadata: {}
39
+ post_install_message:
40
+ rdoc_options: []
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ required_rubygems_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
53
+ requirements: []
54
+ rubyforge_project:
55
+ rubygems_version: 2.4.5
56
+ signing_key:
57
+ specification_version: 4
58
+ summary: A Ruby wrapper that communicates with the telegram-cli.
59
+ test_files: []