telegem 3.3.1 → 3.4.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,702 @@
1
+ # Deployment
2
+
3
+ Deploy Telegem bots to production with proper configuration, monitoring, and scaling.
4
+
5
+ ## Environment Setup
6
+
7
+ ### Production Environment Variables
8
+
9
+ ```bash
10
+ # Required
11
+ export TELEGRAM_BOT_TOKEN="your_bot_token_here"
12
+ export TELEGEM_ENV="production"
13
+
14
+ # Optional
15
+ export REDIS_URL="redis://localhost:6379/0"
16
+ export LOG_LEVEL="info"
17
+ export WEBHOOK_URL="https://your-domain.com/webhook"
18
+ export SSL_CERT_PATH="/path/to/cert.pem"
19
+ export SSL_KEY_PATH="/path/to/key.pem"
20
+ ```
21
+
22
+ ### Ruby Version Management
23
+
24
+ ```ruby
25
+ # Gemfile
26
+ ruby '3.1.0'
27
+
28
+ # Use specific Ruby version
29
+ source 'https://rubygems.org'
30
+
31
+ gem 'telegem'
32
+ ```
33
+
34
+ ### System Dependencies
35
+
36
+ ```bash
37
+ # Ubuntu/Debian
38
+ sudo apt-get update
39
+ sudo apt-get install ruby ruby-dev build-essential redis-server
40
+
41
+ # macOS
42
+ brew install ruby redis
43
+
44
+ # Install bundler
45
+ gem install bundler
46
+ ```
47
+
48
+ ## Webhook Deployment
49
+
50
+ ### Basic Webhook Setup
51
+
52
+ ```ruby
53
+ require 'telegem'
54
+
55
+ bot = Telegem.new(token: ENV['TELEGRAM_BOT_TOKEN'])
56
+
57
+ # Configure webhook
58
+ bot.webhook_url = ENV['WEBHOOK_URL']
59
+ bot.webhook_cert = ENV['SSL_CERT_PATH'] if ENV['SSL_CERT_PATH']
60
+
61
+ # Add handlers
62
+ bot.command('start') do |ctx|
63
+ ctx.reply("Bot is running!")
64
+ end
65
+
66
+ # Start webhook server
67
+ bot.start_webhook
68
+ ```
69
+
70
+ ### SSL Configuration
71
+
72
+ ```ruby
73
+ # Self-signed certificate (development only)
74
+ bot.webhook_cert = './ssl/cert.pem'
75
+ bot.webhook_key = './ssl/key.pem'
76
+
77
+ # Let's Encrypt certificate (production)
78
+ bot.webhook_cert = '/etc/letsencrypt/live/yourdomain.com/fullchain.pem'
79
+ bot.webhook_key = '/etc/letsencrypt/live/yourdomain.com/privkey.pem'
80
+ ```
81
+
82
+ ### Webhook Server Configuration
83
+
84
+ ```ruby
85
+ # Custom server configuration
86
+ server = Telegem::Webhook::Server.new(
87
+ host: '0.0.0.0',
88
+ port: 8443,
89
+ ssl_cert: cert_path,
90
+ ssl_key: key_path,
91
+ max_connections: 100,
92
+ timeout: 30
93
+ )
94
+
95
+ bot.start_webhook(server: server)
96
+ ```
97
+
98
+ ## Polling Deployment
99
+
100
+ ### Long-Running Process
101
+
102
+ ```ruby
103
+ require 'telegem'
104
+
105
+ bot = Telegem.new(token: ENV['TELEGRAM_BOT_TOKEN'])
106
+
107
+ # Configure polling
108
+ bot.poll_timeout = 30
109
+ bot.poll_limit = 100
110
+
111
+ # Add handlers
112
+ bot.command('ping') do |ctx|
113
+ ctx.reply("Pong!")
114
+ end
115
+
116
+ # Start polling
117
+ bot.start_polling
118
+ ```
119
+
120
+ ### Process Management
121
+
122
+ ```bash
123
+ # systemd service file (/etc/systemd/system/telegem-bot.service)
124
+ [Unit]
125
+ Description=Telegem Bot
126
+ After=network.target redis.service
127
+
128
+ [Service]
129
+ Type=simple
130
+ User=telegem
131
+ WorkingDirectory=/path/to/bot
132
+ ExecStart=/usr/local/bin/bundle exec ruby bot.rb
133
+ Restart=always
134
+ RestartSec=5
135
+ Environment=TELEGEM_ENV=production
136
+
137
+ [Install]
138
+ WantedBy=multi-user.target
139
+ ```
140
+
141
+ ```bash
142
+ # Enable and start service
143
+ sudo systemctl enable telegem-bot
144
+ sudo systemctl start telegem-bot
145
+ sudo systemctl status telegem-bot
146
+ ```
147
+
148
+ ## Docker Deployment
149
+
150
+ ### Dockerfile
151
+
152
+ ```dockerfile
153
+ FROM ruby:3.1-slim
154
+
155
+ # Install system dependencies
156
+ RUN apt-get update && apt-get install -y \
157
+ build-essential \
158
+ && rm -rf /var/lib/apt/lists/*
159
+
160
+ # Set working directory
161
+ WORKDIR /app
162
+
163
+ # Copy Gemfile and install dependencies
164
+ COPY Gemfile Gemfile.lock ./
165
+ RUN bundle install --without development test
166
+
167
+ # Copy application code
168
+ COPY . .
169
+
170
+ # Create non-root user
171
+ RUN useradd --create-home --shell /bin/bash telegem
172
+ USER telegem
173
+
174
+ # Expose port for webhook
175
+ EXPOSE 8443
176
+
177
+ # Health check
178
+ HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
179
+ CMD curl -f http://localhost:8443/health || exit 1
180
+
181
+ # Start the bot
182
+ CMD ["bundle", "exec", "ruby", "bot.rb"]
183
+ ```
184
+
185
+ ### Docker Compose
186
+
187
+ ```yaml
188
+ version: '3.8'
189
+
190
+ services:
191
+ bot:
192
+ build: .
193
+ environment:
194
+ - TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN}
195
+ - REDIS_URL=redis://redis:6379/0
196
+ - TELEGEM_ENV=production
197
+ depends_on:
198
+ - redis
199
+ restart: unless-stopped
200
+
201
+ redis:
202
+ image: redis:7-alpine
203
+ volumes:
204
+ - redis_data:/data
205
+ restart: unless-stopped
206
+
207
+ volumes:
208
+ redis_data:
209
+ ```
210
+
211
+ ### Multi-Stage Build
212
+
213
+ ```dockerfile
214
+ # Build stage
215
+ FROM ruby:3.1-slim as builder
216
+
217
+ RUN apt-get update && apt-get install -y build-essential
218
+ WORKDIR /app
219
+ COPY Gemfile Gemfile.lock ./
220
+ RUN bundle install --without development test && bundle clean --force
221
+
222
+ # Runtime stage
223
+ FROM ruby:3.1-slim
224
+
225
+ RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/*
226
+ COPY --from=builder /usr/local/bundle /usr/local/bundle
227
+ WORKDIR /app
228
+ COPY . .
229
+
230
+ USER nobody
231
+ EXPOSE 8443
232
+ CMD ["bundle", "exec", "ruby", "bot.rb"]
233
+ ```
234
+
235
+ ## Cloud Deployment
236
+
237
+ ### Heroku
238
+
239
+ ```ruby
240
+ # Gemfile
241
+ source 'https://rubygems.org'
242
+ ruby '3.1.0'
243
+
244
+ gem 'telegem'
245
+ gem 'redis'
246
+ ```
247
+
248
+ ```yaml
249
+ # Procfile
250
+ web: bundle exec ruby bot.rb
251
+ ```
252
+
253
+ ```ruby
254
+ # bot.rb
255
+ require 'telegem'
256
+
257
+ bot = Telegem.new(token: ENV['TELEGRAM_BOT_TOKEN'])
258
+
259
+ # Use Redis for sessions
260
+ bot.session_store = Telegem::Session::RedisStore.new(ENV['REDIS_URL'])
261
+
262
+ # Webhook for Heroku
263
+ bot.webhook_url = "https://#{ENV['HEROKU_APP_NAME']}.herokuapp.com/webhook"
264
+
265
+ bot.command('start') do |ctx|
266
+ ctx.reply("Bot deployed on Heroku!")
267
+ end
268
+
269
+ bot.start_webhook
270
+ ```
271
+
272
+ ```bash
273
+ # Deploy
274
+ heroku create your-bot-name
275
+ heroku config:set TELEGRAM_BOT_TOKEN=your_token_here
276
+ git push heroku main
277
+ ```
278
+
279
+ ### AWS ECS
280
+
281
+ ```json
282
+ {
283
+ "family": "telegem-bot",
284
+ "taskRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
285
+ "executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
286
+ "networkMode": "awsvpc",
287
+ "requiresCompatibilities": ["FARGATE"],
288
+ "cpu": "256",
289
+ "memory": "512",
290
+ "containerDefinitions": [
291
+ {
292
+ "name": "telegem-bot",
293
+ "image": "your-registry/telegem-bot:latest",
294
+ "essential": true,
295
+ "environment": [
296
+ {"name": "TELEGRAM_BOT_TOKEN", "value": "your_token"},
297
+ {"name": "TELEGEM_ENV", "value": "production"}
298
+ ],
299
+ "logConfiguration": {
300
+ "logDriver": "awslogs",
301
+ "options": {
302
+ "awslogs-group": "/ecs/telegem-bot",
303
+ "awslogs-region": "us-east-1",
304
+ "awslogs-stream-prefix": "ecs"
305
+ }
306
+ }
307
+ }
308
+ ]
309
+ }
310
+ ```
311
+
312
+ ### Google Cloud Run
313
+
314
+ ```yaml
315
+ apiVersion: serving.knative.dev/v1
316
+ kind: Service
317
+ metadata:
318
+ name: telegem-bot
319
+ spec:
320
+ template:
321
+ spec:
322
+ containers:
323
+ - image: gcr.io/your-project/telegem-bot:latest
324
+ env:
325
+ - name: TELEGRAM_BOT_TOKEN
326
+ value: "your_token"
327
+ - name: TELEGEM_ENV
328
+ value: "production"
329
+ ports:
330
+ - containerPort: 8443
331
+ resources:
332
+ limits:
333
+ cpu: 1000m
334
+ memory: 512Mi
335
+ ```
336
+
337
+ ### Railway
338
+
339
+ ```toml
340
+ # railway.toml
341
+ [build]
342
+ builder = "dockerfile"
343
+
344
+ [deploy]
345
+ healthcheckPath = "/health"
346
+ healthcheckTimeout = 300
347
+ restartPolicyType = "ON_FAILURE"
348
+ restartPolicyMaxRetries = 10
349
+ ```
350
+
351
+ ## Monitoring and Logging
352
+
353
+ ### Structured Logging
354
+
355
+ ```ruby
356
+ require 'logger'
357
+
358
+ class ProductionLogger
359
+ def initialize
360
+ @logger = Logger.new(STDOUT)
361
+ @logger.level = ENV['LOG_LEVEL'] == 'debug' ? Logger::DEBUG : Logger::INFO
362
+ @logger.formatter = proc do |severity, datetime, progname, msg|
363
+ {
364
+ timestamp: datetime.iso8601,
365
+ level: severity,
366
+ message: msg,
367
+ service: 'telegem-bot'
368
+ }.to_json + "\n"
369
+ end
370
+ end
371
+
372
+ def info(msg); @logger.info(msg); end
373
+ def error(msg); @logger.error(msg); end
374
+ def debug(msg); @logger.debug(msg); end
375
+ end
376
+
377
+ bot.logger = ProductionLogger.new
378
+ ```
379
+
380
+ ### Health Checks
381
+
382
+ ```ruby
383
+ bot.get('/health') do |ctx|
384
+ # Check database connectivity
385
+ redis_ping = begin
386
+ bot.session_store.redis.ping == 'PONG'
387
+ rescue
388
+ false
389
+ end
390
+
391
+ # Check bot API
392
+ api_check = begin
393
+ bot.api.call('getMe')['ok']
394
+ rescue
395
+ false
396
+ end
397
+
398
+ status = redis_ping && api_check ? 200 : 503
399
+ ctx.response.status = status
400
+ ctx.response.body = {
401
+ status: status == 200 ? 'healthy' : 'unhealthy',
402
+ timestamp: Time.now.to_i,
403
+ checks: {
404
+ redis: redis_ping,
405
+ telegram_api: api_check
406
+ }
407
+ }.to_json
408
+ end
409
+ ```
410
+
411
+ ### Metrics Collection
412
+
413
+ ```ruby
414
+ class MetricsMiddleware
415
+ def initialize
416
+ @metrics = {
417
+ requests_total: 0,
418
+ errors_total: 0,
419
+ response_time_sum: 0
420
+ }
421
+ end
422
+
423
+ def call(ctx, next_middleware)
424
+ start_time = Time.now
425
+
426
+ begin
427
+ @metrics[:requests_total] += 1
428
+ next_middleware.call(ctx)
429
+ rescue => e
430
+ @metrics[:errors_total] += 1
431
+ raise
432
+ ensure
433
+ response_time = Time.now - start_time
434
+ @metrics[:response_time_sum] += response_time
435
+ end
436
+ end
437
+
438
+ def stats
439
+ avg_response_time = @metrics[:requests_total] > 0 ?
440
+ @metrics[:response_time_sum] / @metrics[:requests_total] : 0
441
+
442
+ {
443
+ requests_total: @metrics[:requests_total],
444
+ errors_total: @metrics[:errors_total],
445
+ avg_response_time: avg_response_time
446
+ }
447
+ end
448
+ end
449
+
450
+ metrics = MetricsMiddleware.new
451
+ bot.use metrics
452
+
453
+ bot.get('/metrics') do |ctx|
454
+ ctx.response.body = metrics.stats.to_json
455
+ end
456
+ ```
457
+
458
+ ## Scaling Considerations
459
+
460
+ ### Horizontal Scaling
461
+
462
+ ```ruby
463
+ # Multiple bot instances
464
+ instances = ENV['INSTANCES']&.to_i || 1
465
+
466
+ instances.times do |i|
467
+ fork do
468
+ bot = Telegem.new(token: ENV['TELEGRAM_BOT_TOKEN'])
469
+ # Configure instance-specific settings
470
+ bot.instance_id = i
471
+ bot.start_polling
472
+ end
473
+ end
474
+
475
+ Process.waitall
476
+ ```
477
+
478
+ ### Load Balancing
479
+
480
+ ```ruby
481
+ # Use Redis for distributed sessions
482
+ bot.session_store = Telegem::Session::RedisStore.new(ENV['REDIS_URL'])
483
+
484
+ # Distributed locks for critical operations
485
+ require 'redis-mutex'
486
+
487
+ bot.command('critical') do |ctx|
488
+ Redis::Mutex.with_lock('critical_operation') do
489
+ # Critical operation
490
+ ctx.reply("Operation completed")
491
+ end
492
+ end
493
+ ```
494
+
495
+ ### Database Connection Pooling
496
+
497
+ ```ruby
498
+ # For database-backed session stores
499
+ bot.session_store = Telegem::Session::DatabaseStore.new(
500
+ pool_size: ENV['DB_POOL_SIZE']&.to_i || 5,
501
+ timeout: 5
502
+ )
503
+ ```
504
+
505
+ ## Security Best Practices
506
+
507
+ ### Environment Variables
508
+
509
+ ```bash
510
+ # Never commit secrets
511
+ echo ".env" >> .gitignore
512
+
513
+ # Use strong tokens
514
+ export TELEGRAM_BOT_TOKEN="$(openssl rand -hex 32)"
515
+ ```
516
+
517
+ ### SSL/TLS
518
+
519
+ ```ruby
520
+ # Force HTTPS in production
521
+ bot.use SSLMiddleware.new if ENV['TELEGEM_ENV'] == 'production'
522
+
523
+ class SSLMiddleware
524
+ def call(ctx, next_middleware)
525
+ if ctx.request.scheme != 'https'
526
+ ctx.response.status = 301
527
+ ctx.response.headers['Location'] = ctx.request.url.sub('http:', 'https:')
528
+ return
529
+ end
530
+ next_middleware.call(ctx)
531
+ end
532
+ end
533
+ ```
534
+
535
+ ### Input Validation
536
+
537
+ ```ruby
538
+ bot.use InputValidationMiddleware.new
539
+
540
+ class InputValidationMiddleware
541
+ def call(ctx, next_middleware)
542
+ # Sanitize input
543
+ if ctx.text
544
+ ctx.text = sanitize_input(ctx.text)
545
+ end
546
+
547
+ # Rate limiting
548
+ if rate_limited?(ctx.from.id)
549
+ ctx.response.status = 429
550
+ return
551
+ end
552
+
553
+ next_middleware.call(ctx)
554
+ end
555
+
556
+ private
557
+
558
+ def sanitize_input(text)
559
+ # Remove dangerous characters
560
+ text.gsub(/[<>'"&]/, '')
561
+ end
562
+
563
+ def rate_limited?(user_id)
564
+ # Implement rate limiting logic
565
+ false
566
+ end
567
+ end
568
+ ```
569
+
570
+ ## Performance Optimization
571
+
572
+ ### Connection Pooling
573
+
574
+ ```ruby
575
+ # HTTP client configuration
576
+ bot.api.http_client = Async::HTTP::Client.new(
577
+ pool_size: 10,
578
+ timeout: 30
579
+ )
580
+ ```
581
+
582
+ ### Caching
583
+
584
+ ```ruby
585
+ require 'redis'
586
+
587
+ class CacheMiddleware
588
+ def initialize(redis_url)
589
+ @redis = Redis.new(url: redis_url)
590
+ end
591
+
592
+ def call(ctx, next_middleware)
593
+ cache_key = "response:#{ctx.update.update_id}"
594
+
595
+ if cached = @redis.get(cache_key)
596
+ ctx.response.body = cached
597
+ return
598
+ end
599
+
600
+ next_middleware.call(ctx)
601
+
602
+ # Cache successful responses
603
+ if ctx.response.status == 200
604
+ @redis.setex(cache_key, 300, ctx.response.body) # 5 min cache
605
+ end
606
+ end
607
+ end
608
+ ```
609
+
610
+ ### Background Processing
611
+
612
+ ```ruby
613
+ require 'async'
614
+
615
+ bot.command('heavy_task') do |ctx|
616
+ ctx.reply("Processing in background...")
617
+
618
+ Async do
619
+ result = perform_heavy_computation(ctx.text)
620
+ ctx.reply("Result: #{result}")
621
+ end
622
+ end
623
+ ```
624
+
625
+ ## Backup and Recovery
626
+
627
+ ### Database Backups
628
+
629
+ ```bash
630
+ # Redis backup script
631
+ #!/bin/bash
632
+ DATE=$(date +%Y%m%d_%H%M%S)
633
+ redis-cli --rdb /backup/redis_$DATE.rdb
634
+
635
+ # Clean old backups
636
+ find /backup -name "redis_*.rdb" -mtime +7 -delete
637
+ ```
638
+
639
+ ### Configuration Backup
640
+
641
+ ```ruby
642
+ # Backup bot configuration
643
+ task :backup do
644
+ config = {
645
+ token: ENV['TELEGRAM_BOT_TOKEN'],
646
+ webhook_url: ENV['WEBHOOK_URL'],
647
+ session_store: bot.session_store.class.name,
648
+ timestamp: Time.now.to_i
649
+ }
650
+
651
+ File.write("/backup/config_#{Time.now.to_i}.json", config.to_json)
652
+ end
653
+ ```
654
+
655
+ ## Troubleshooting
656
+
657
+ ### Common Issues
658
+
659
+ **Webhook not receiving updates:**
660
+ - Check SSL certificate validity
661
+ - Verify webhook URL is accessible
662
+ - Check firewall settings
663
+
664
+ **High memory usage:**
665
+ - Monitor for memory leaks
666
+ - Use connection pooling
667
+ - Implement proper garbage collection
668
+
669
+ **Rate limiting:**
670
+ - Implement exponential backoff
671
+ - Cache frequent requests
672
+ - Use webhooks instead of polling
673
+
674
+ **Database connection issues:**
675
+ - Check connection pool size
676
+ - Implement connection retry logic
677
+ - Monitor database performance
678
+
679
+ ### Debug Mode
680
+
681
+ ```ruby
682
+ if ENV['DEBUG'] == 'true'
683
+ bot.logger.level = :debug
684
+ bot.api.debug = true
685
+ end
686
+ ```
687
+
688
+ ### Log Analysis
689
+
690
+ ```bash
691
+ # Search for errors
692
+ grep "ERROR" /var/log/telegem-bot.log
693
+
694
+ # Count requests per hour
695
+ grep "INFO.*request" /var/log/telegem-bot.log | cut -d' ' -f1 | uniq -c
696
+
697
+ # Monitor response times
698
+ grep "response_time" /var/log/telegem-bot.log | awk '{sum+=$2} END {print sum/NR}'
699
+ ```
700
+
701
+ Production deployment requires careful consideration of security, performance, monitoring, and scalability to ensure reliable bot operation.</content>
702
+ <parameter name="filePath">/home/slick/telegem/docs/deployment.md