telegram-rb 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []