Class: Telegram::Client

Inherits:
API
  • Object
show all
Includes:
Logging
Defined in:
lib/telegram/client.rb

Overview

Telegram Client

See Also:

Version:

  • 0.1.1

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Logging

configure_logger_for, #logger, logger_for

Methods inherited from API

#add_contact, #chat_add_user, #chat_del_user, #create_group_chat, #disconnect, #download_attachment, #mark_read, #msg, #send_contact, #send_file, #send_photo, #send_typing, #send_typing_abort, #send_video, #update!, #update_chats!, #update_contacts!, #update_profile!

Constructor Details

#initialize {|config| ... } ⇒ Client

Initialize Telegram Client

Yields:

  • (config)

    Given configuration struct to the block

Yield Parameters:

  • block (Block)


60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/telegram/client.rb', line 60

def initialize(&block)
  @config = Telegram::Config.new
  @auth_properties = Telegram::AuthProperties.new
  yield @config, @auth_properties
  @logger = @config.logger if @config.logger
  @connected = 0
  @stdout = nil
  @connect_callback = nil
  @on = {}

  @profile = nil
  @contacts = []
  @chats = []
  @starts_at = nil
  @events = EM::Queue.new

  logger.info("Initialized")
end

Instance Attribute Details

#auth_propertiesObject

Event listeners that can respond to the event arrives

See Also:

Since:

  • 0.1.0


54
55
56
# File 'lib/telegram/client.rb', line 54

def auth_properties
  @auth_properties
end

#chatsArray<TelegramChat> (readonly)

Returns Chats that current user joined.

Returns:

Since:

  • 0.1.0


46
47
48
# File 'lib/telegram/client.rb', line 46

def chats
  @chats
end

#connectionConnectionPool (readonly)

Returns Socket connection pool, includes Telegram::Connection.

Returns:

Since:

  • 0.1.0


34
35
36
# File 'lib/telegram/client.rb', line 34

def connection
  @connection
end

#contactsArray<TelegramContact> (readonly)

Returns Current user’s contact list.

Returns:

Since:

  • 0.1.0


42
43
44
# File 'lib/telegram/client.rb', line 42

def contacts
  @contacts
end

#onObject

Event listeners that can respond to the event arrives

See Also:

Since:

  • 0.1.0


54
55
56
# File 'lib/telegram/client.rb', line 54

def on
  @on
end

#profileTelegramContact (readonly)

Returns Current user’s profile.

Returns:

Since:

  • 0.1.0


38
39
40
# File 'lib/telegram/client.rb', line 38

def profile
  @profile
end

#stdoutObject (readonly)

Returns the value of attribute stdout.



48
49
50
# File 'lib/telegram/client.rb', line 48

def stdout
  @stdout
end

Instance Method Details

#connect { ... } ⇒ Object

Start telegram-cli daemon

Yields:

  • This block will be executed when all connections have responded



144
145
146
147
148
149
# File 'lib/telegram/client.rb', line 144

def connect(&block)
  logger.info("Trying to start telegram-cli and then connect")
  @connect_callback = block
  process_data
  EM.defer(method(:execute), method(:create_pool), method(:execution_failed))
end

#connected?bool

Returns Connection pool status.

Returns:

  • (bool)

    Connection pool status

Since:

  • 0.1.0


193
194
195
# File 'lib/telegram/client.rb', line 193

def connected?
  @connected == @config.size
end

#create_poolObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Create a connection pool based on the Telegram::Connection and given configuration



154
155
156
157
158
159
160
161
# File 'lib/telegram/client.rb', line 154

def create_pool(*)
  @connection = ConnectionPool.new(@config.size) do
    client = EM.connect_unix_domain(@config.sock, Connection)
    client.on_connect = self.method(:on_connect)
    client.on_disconnect = self.method(:on_disconnect)
    client
  end
end

#executeObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Execute telegram-cli daemon and wait for the response



82
83
84
85
86
87
# File 'lib/telegram/client.rb', line 82

def execute
  cli_arguments = Telegram::CLIArguments.new(@config)
  command = "'#{@config.daemon}' #{cli_arguments.to_s}"
  @stdout = IO.popen(command, 'a+')
  initialize_stdout_reading
end

#on_connectObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

A event listener that will be called if the Telegram::Connection successes on either of Telegram::ConnectionPool



166
167
168
169
170
171
172
173
# File 'lib/telegram/client.rb', line 166

def on_connect
  @connected += 1
  if connected?
    logger.info("Successfully connected to the Telegram CLI")
    EM.defer(&method(:poll))
    update!(&@connect_callback)
  end
end

#on_disconnectObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

A event listener that will be called if the Telegram::Connection closes on either of Telegram::ConnectionPool



178
179
180
181
182
183
184
185
# File 'lib/telegram/client.rb', line 178

def on_disconnect
  @connected -= 1
  if @connected == 0
    logger.info("Disconnected from Telegram CLI")
    close_stdout
    @disconnect_callback.call if @disconnect_callback
  end
end

#on_disconnect=(callback) ⇒ Object



187
188
189
# File 'lib/telegram/client.rb', line 187

def on_disconnect=(callback)
  @disconnect_callback = callback
end

#pollObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Do the long-polling from stdout of the telegram-cli



92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/telegram/client.rb', line 92

def poll
  logger.info("Start polling for events")
  while (data = @stdout.gets)
    begin
      brace = data.index('{')
      data = data[brace..-2]
      data = Oj.load(data, mode: :compat)
      @events << data
    rescue
    end
  end
end

#process_dataObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Process given data to make Event instance



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/telegram/client.rb', line 108

def process_data
  process = Proc.new { |data|
    begin
      type = case data['event']
      when 'message'
        if data['from']['peer_id'] != @profile.id
          EventType::RECEIVE_MESSAGE
        else
          EventType::SEND_MESSAGE
        end
      end

      action = data.has_key?('action') ? case data['action']
        when 'chat_add_user'
          ActionType::CHAT_ADD_USER
        when 'create_group_chat'
          ActionType::CREATE_GROUP_CHAT
         when 'add_contact'
           ActionType::ADD_CONTACT
        else
          ActionType::UNKNOWN_ACTION
        end : ActionType::NO_ACTION

      event = Event.new(self, type, action, data)
      @on[type].call(event) if @on.has_key?(type)
    rescue Exception => e
      logger.error("Error occurred during the processing: #{data}\n #{e.inspect} #{e.backtrace}")
    end
    @events.pop(&process)
  }
  @events.pop(&process)
end