Skip to content

Commit 5b24519

Browse files
committed
Initial commit: Complete MTProto 2.0 Ruby implementation
Features: - Complete DH handshake implementation - AES-IGE encryption/decryption - TL schema parser with api.tl and mtproto.tl - auth.sendCode and auth.signIn methods - contacts.getContacts method - messages.sendMessage method - updates.getDifference for incoming messages - Background updates polling - Production-ready error handling - Full test suite and examples
0 parents  commit 5b24519

33 files changed

Lines changed: 7187 additions & 0 deletions

.github/workflows/main.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: Ruby
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
8+
pull_request:
9+
10+
jobs:
11+
build:
12+
runs-on: ubuntu-latest
13+
name: Ruby ${{ matrix.ruby }}
14+
strategy:
15+
matrix:
16+
ruby:
17+
- '3.4.5'
18+
19+
steps:
20+
- uses: actions/checkout@v4
21+
with:
22+
persist-credentials: false
23+
- name: Set up Ruby
24+
uses: ruby/setup-ruby@v1
25+
with:
26+
ruby-version: ${{ matrix.ruby }}
27+
bundler-cache: true
28+
- name: Run the default task
29+
run: bundle exec rake

.gitignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/.bundle/
2+
/.yardoc
3+
/_yardoc/
4+
/coverage/
5+
/doc/
6+
/pkg/
7+
/spec/reports/
8+
/tmp/
9+
10+
# rspec failure tracking
11+
.rspec_status

.rspec

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
--format documentation
2+
--color
3+
--require spec_helper

Gemfile

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# frozen_string_literal: true
2+
3+
source "https://rubygems.org"
4+
5+
# Specify your gem's dependencies in telegram-mtproto-ruby.gemspec
6+
gemspec
7+
8+
gem "irb"
9+
gem "rake", "~> 13.0"
10+
11+
gem "rspec", "~> 3.0"

README.md

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
# telegram-mtproto-ruby
2+
3+
🚀 **Pure Ruby MTProto 2.0 implementation for Telegram API**
4+
5+
A complete, production-ready Ruby implementation of Telegram's MTProto 2.0 protocol with full support for:
6+
7+
-**Complete DH Handshake** - Secure key exchange with Telegram servers
8+
-**AES-IGE Encryption/Decryption** - Full MTProto 2.0 cryptography
9+
-**TL Schema Parser** - Dynamic parsing of Telegram Type Language
10+
-**auth.sendCode & auth.signIn** - Full authentication flow
11+
-**contacts.getContacts** - Retrieve user contacts
12+
-**messages.sendMessage** - Send messages to users
13+
-**updates.getDifference** - Receive incoming messages
14+
-**Background Polling** - Continuous message reception
15+
16+
## Installation
17+
18+
Add this line to your application's Gemfile:
19+
20+
```ruby
21+
gem 'telegram-mtproto-ruby'
22+
```
23+
24+
And then execute:
25+
26+
$ bundle install
27+
28+
Or install it yourself as:
29+
30+
$ gem install telegram-mtproto-ruby
31+
32+
## Quick Start
33+
34+
### 1. Get Telegram API Credentials
35+
36+
1. Go to https://my.telegram.org/apps
37+
2. Login with your Telegram account
38+
3. Create a new app and get your `api_id` and `api_hash`
39+
40+
### 2. Basic Authentication
41+
42+
```ruby
43+
require 'telegram_mtproto'
44+
45+
# Initialize client
46+
client = TelegramMtproto.new(
47+
api_id, # Your API ID (integer)
48+
api_hash, # Your API Hash (string)
49+
phone_number # Your phone number with country code (e.g., "+1234567890")
50+
)
51+
52+
# Send verification code
53+
result = client.send_code
54+
if result[:success]
55+
puts "✅ Code sent! Check your Telegram app"
56+
phone_code_hash = result[:phone_code_hash]
57+
58+
# Sign in with PIN code
59+
print "Enter PIN: "
60+
pin_code = gets.chomp
61+
62+
auth_result = client.sign_in(phone_code_hash, pin_code)
63+
if auth_result[:success]
64+
puts "🎉 Successfully authenticated!"
65+
else
66+
puts "❌ Authentication failed: #{auth_result[:error]}"
67+
end
68+
else
69+
puts "❌ Failed to send code: #{result[:error]}"
70+
end
71+
```
72+
73+
### 3. Send Messages
74+
75+
```ruby
76+
# Get contacts
77+
contacts = client.get_contacts
78+
if contacts[:success]
79+
puts "📋 Found #{contacts[:users].length} contacts"
80+
81+
# Send message to first contact
82+
first_user = contacts[:users].first
83+
result = client.send_message(
84+
first_user[:id],
85+
"Hello from telegram-mtproto-ruby! 🚀"
86+
)
87+
88+
if result[:success]
89+
puts "✅ Message sent successfully!"
90+
end
91+
end
92+
```
93+
94+
### 4. Receive Messages
95+
96+
```ruby
97+
# Start polling for incoming messages
98+
client.start_updates_polling do |message|
99+
puts "📥 New message: '#{message[:message]}' from user #{message[:from_id]}"
100+
end
101+
102+
# Keep the script running
103+
sleep(60)
104+
105+
# Stop polling
106+
client.stop_updates_polling
107+
```
108+
109+
## Features
110+
111+
### Core MTProto 2.0 Support
112+
113+
- **Diffie-Hellman Handshake**: Complete implementation matching Telethon
114+
- **AES-IGE Encryption**: Full MTProto 2.0 cryptographic support
115+
- **Message ID Generation**: Proper timing and monotonicity
116+
- **Salt Management**: Automatic bad_server_salt handling
117+
- **Connection Management**: TCP Full connection with CRC32
118+
119+
### Telegram API Methods
120+
121+
| Method | Description | Status |
122+
|--------|-------------|--------|
123+
| `auth.sendCode` | Send verification code to phone ||
124+
| `auth.signIn` | Authenticate with PIN code ||
125+
| `contacts.getContacts` | Get user contact list ||
126+
| `messages.sendMessage` | Send message to user ||
127+
| `updates.getDifference` | Get incoming updates ||
128+
129+
### TL Schema Support
130+
131+
- **Dynamic parsing** of `api.tl` and `mtproto.tl`
132+
- **Type-safe serialization** of all Telegram objects
133+
- **Automatic parameter validation**
134+
- **Zero hardcoded values** - everything uses official TL schemas
135+
136+
## Advanced Usage
137+
138+
### Error Handling
139+
140+
```ruby
141+
result = client.send_code
142+
case result[:error]
143+
when "PHONE_NUMBER_INVALID"
144+
puts "Invalid phone number format"
145+
when "API_ID_INVALID"
146+
puts "Check your API credentials"
147+
when "FLOOD_WAIT_X"
148+
puts "Rate limited, wait #{result[:error].match(/\d+/)[0]} seconds"
149+
end
150+
```
151+
152+
### 2FA Support
153+
154+
```ruby
155+
auth_result = client.sign_in(phone_code_hash, pin_code)
156+
if auth_result[:requires_2fa]
157+
print "Enter 2FA password: "
158+
password = gets.chomp
159+
# TODO: Implement auth.checkPassword
160+
end
161+
```
162+
163+
### Background Message Processing
164+
165+
```ruby
166+
client.start_updates_polling do |message|
167+
# Process message in background
168+
Thread.new do
169+
process_message(message)
170+
end
171+
end
172+
```
173+
174+
## Development
175+
176+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt.
177+
178+
## Contributing
179+
180+
Bug reports and pull requests are welcome on GitHub at https://github.com/mikefluff/telegram-mtproto-ruby.
181+
182+
## License
183+
184+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
185+
186+
## Credits
187+
188+
This implementation was inspired by [Telethon](https://github.com/LonamiWebs/Telethon) and follows Telegram's official [MTProto documentation](https://core.telegram.org/mtproto).

Rakefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# frozen_string_literal: true
2+
3+
require "bundler/gem_tasks"
4+
require "rspec/core/rake_task"
5+
6+
RSpec::Core::RakeTask.new(:spec)
7+
8+
task default: :spec

bin/console

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/usr/bin/env ruby
2+
# frozen_string_literal: true
3+
4+
require "bundler/setup"
5+
require "telegram/mtproto/ruby"
6+
7+
# You can add fixtures and/or initialization code here to make experimenting
8+
# with your gem easier. You can also use a different console, if you like.
9+
10+
require "irb"
11+
IRB.start(__FILE__)

bin/setup

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
IFS=$'\n\t'
4+
set -vx
5+
6+
bundle install
7+
8+
# Do any other automated setup that you need to do here

0 commit comments

Comments
 (0)