• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

yurak / fanta / #635723217

03 Oct 2025 08:36PM UTC coverage: 95.428%. First build
#635723217

Pull #497

travis-ci

Pull Request #497: Update leagues order

128 of 155 new or added lines in 26 files covered. (82.58%)

4258 of 4462 relevant lines covered (95.43%)

93.29 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

73.58
/app/controllers/telegram/webhook_controller.rb
1
module Telegram
1✔
2
  class WebhookController < Telegram::Bot::UpdatesController
1✔
3
    include Telegram::Bot::UpdatesController::MessageContext
1✔
4
    include Rails.application.routes.url_helpers
1✔
5

6
    def start!(*args)
1✔
7
      token = args[0]
1✔
8

1✔
9
      if token.present?
NEW
10
        connect_by_token(token)
×
11
        return
12
      end
13

1✔
14
      save_message
1✔
15
      send_start_message
16
    rescue Telegram::Bot::Forbidden => e
17
      Rails.logger.warn("Telegram error for chat #{payload['chat']['id']}: #{e.message}")
1✔
18
    end
1✔
19

1✔
20
    def help!(*)
21
      respond_with :message, text: t('telegram.webhooks.help.content', locale: locale)
22
    end
1✔
23

1✔
24
    def register!(*)
25
      save_context :check_email
26
      respond_with :message, text: t('telegram.webhooks.register.text', locale: locale)
27
    end
28

29
    def learn_more!(*)
1✔
30
      respond_with :message, text: t('telegram.webhooks.learn_more.text', locale: locale), reply_markup: {
1✔
31
        inline_keyboard: [
1✔
32
          [{ text: t('telegram.webhooks.learn_more.rules', locale: locale), url: rules_url(host: host, locale: locale) }],
33
          [{ text: t('telegram.webhooks.learn_more.podcast', locale: locale), url: 'https://youtu.be/P4yh8PXipa4?si=FMme8cul9JJ2bKrC' }]
34
        ]
1✔
35
      }
×
36
      %w[rules_short_ua.pdf rules_extended_ua.pdf rules_en.pdf].each do |filename|
37
        File.open("public/#{filename}") { |f| reply_with :document, document: f }
×
38
      end
39
    end
40

1✔
41
    def callback_query(data)
×
42
      case data
43
      when 'register'   then register!
×
44
      when 'learn_more' then learn_more!
×
45
      end
46
    end
×
47

×
48
    def check_email(*words)
×
49
      save_message
×
50

51
      return if words[0].blank?
×
52

53
      email = words[0].downcase
54
      user = User.find_by(email: email)
55

1✔
56
      if user
1✔
57
        email_exist_response
58
      elsif profile
59
        respond_with :message, text: t('telegram.webhooks.register.chat_exist', locale: locale)
1✔
60
      else
1✔
61
        email_valid_response(email)
62
      end
1✔
63
    end
64

1✔
65
    def contacts!(*)
66
      respond_with :message, text: t('telegram.webhooks.contacts.text', locale: locale)
67
    end
68

1✔
69
    def action_missing(_action, *_args)
70
      return unless action_type == :command
1✔
71

1✔
72
      save_message
73

74
      respond_with :message,
75
                   text: t('telegram.webhooks.action_missing.command', command: action_options[:command], locale: locale)
76
    end
77

78
    private
79

80
    def send_start_message
81
      respond_with :message, text: t('telegram.webhooks.start.text', locale: locale), reply_markup: {
82
        inline_keyboard: [
83
          [
84
            { text: t('telegram.webhooks.start.register', locale: locale), callback_data: 'register' },
1✔
85
            { text: t('telegram.webhooks.start.learn_more', locale: locale), callback_data: 'learn_more' }
2✔
86
          ]
87
        ],
2✔
88
        resize_keyboard: true,
89
        one_time_keyboard: true,
90
        selective: true
91
      }
92
    end
93

94
    def save_message
95
      return unless update && payload
96

97
      TgMessage.create(
98
        update_id: update['update_id'],
99
        full_data: update,
100
        message_id: payload['message_id'],
1✔
101
        chat_id: payload['chat']['id'],
×
102
        text: payload['text'],
103
        username: payload['from']['username'],
104
        first_name: payload['from']['first_name'],
105
        last_name: payload['from']['last_name'],
106
        date: Time.zone.at(payload['date'] || Time.current.to_i).to_datetime
107
      )
108
    end
1✔
109

×
110
    def email_exist_response
111
      respond_with :message, text: t('telegram.webhooks.register.email_exist', locale: locale), reply_markup: {
112
        inline_keyboard: [
113
          [{ text: t('telegram.webhooks.start.register', locale: locale), callback_data: 'register' }]
114
        ]
115
      }
116
    end
117

1✔
118
    def email_valid_response(email)
×
119
      token = SecureRandom.hex(16)
120
      Rails.cache.write("tg_connect:#{token}", from['id'], expires_in: 1.hour)
121

1✔
122
      respond_with :message, text: t('telegram.webhooks.register.success', locale: locale), reply_markup: {
11✔
123
        inline_keyboard: [
124
          [{ text: t('telegram.webhooks.register.sign_up', locale: locale),
11✔
125
             url: new_user_registration_url(email: email, tg_token: token, host: host, locale: locale) }]
126
        ]
127
      }
1✔
128
    end
1✔
129

130
    def connect_by_token(token)
131
      profile = UserProfile.find_by(tg_connect_token: token)
132
      if linkable?(profile)
133
        profile.update(tg_chat_id: from['id'], bot_enabled: true, tg_connect_token: nil, tg_connect_expires_at: nil)
134
        respond_with :message, text: t('telegram.webhooks.start.connected', locale: locale)
135
      else
136
        respond_with :message, text: t('telegram.webhooks.start.connect_failed', locale: locale)
137
      end
138
    end
139

140
    def linkable?(profile)
141
      profile.present? && profile.tg_connect_expires_at.present? && profile.tg_connect_expires_at >= Time.current
142
    end
143

144
    def profile
145
      UserProfile.find_by(tg_chat_id: from['id'])
146
    end
147

148
    def locale
149
      return :ua if from['language_code'] == 'uk'
150

151
      :en
152
    end
153

154
    def host
155
      Rails.application.config.telegram_updates_controller.host
156
    end
157
  end
158
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc