telegrams 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ae7b173896a5f9c90fe0ddb584cdee97044f914ca5d9fa958fb99d4087352bec
4
- data.tar.gz: 4991d2ef06af4fea3cdbc390acfa1727ac39df0532117374245c4d5db0b05fa1
3
+ metadata.gz: 07f64a28ab74c341a147501d87ca332f32d7f7b17ae43525248a8b0761013ff5
4
+ data.tar.gz: 46362b2dab6ae4609988360dd7afbd2a98ce910cf360db1205f5318b3fe4316e
5
5
  SHA512:
6
- metadata.gz: baea9f341a7d4ab9dee90cfdb99e215fbc420f2b6a4de584f13e74bf17cfec37825ef34c65b0c6815f0e90bd77431ff6c032c15adc302521fe20a4ff88dec542
7
- data.tar.gz: 373788d9afe6f9eb005733c89bef79c8d4ace52396da1594dda3fc7bae450c115c9f6444d95e095e736ffd7b90cc388c778f0e92d963fb3a53c6ebbd2e37a93d
6
+ metadata.gz: 235e0542ccb49d34b4751118b2f809a4c4dabf641e68b11a5f9f20641cd51122aa9446811f11de6b6d943edcae4bc426e3e6b4532fdd8a0857112514f14dc69c
7
+ data.tar.gz: 29f8aa12a72cd6d64fc8b2620b228ffdcefd688867bb389015a9781e30a68ca280c79b111cf48c7b75b6ccde3e726df8a9184b3cce35bca5b19fd9d1ea44f523
data/CHANGELOG.md CHANGED
@@ -1,4 +1,6 @@
1
- ## [Unreleased]
1
+ ## [0.1.1] - 2025-02-18
2
+
3
+ - Rebranded and moved permanently to the `telegrama` gem
2
4
 
3
5
  ## [0.1.0] - 2025-02-18
4
6
 
data/README.md CHANGED
@@ -1,124 +1,3 @@
1
- # 💬 `telegrams` a tiny wrapper to send admin Telegram messages
1
+ # You're probably looking for the `telegrama` gem
2
2
 
3
- [![Gem Version](https://badge.fury.io/rb/telegrams.svg)](https://badge.fury.io/rb/telegrams)
4
-
5
- Send quick, simple admin / logging Telegram messages via a Telegram bot.
6
-
7
- I'm making this gem because I'm tired of copy-pasting the same Telegram wrapper from Rails project to Rails project just to send myself admin messages and notifications. The goal with this gem is to provide a straightforward, minimal API to send Telegram messages reliably. All I want to do is this:
8
-
9
- ```ruby
10
- Telegrams.send_message("Important admin notification!")
11
- ```
12
-
13
- This is useful for Rails developers using Telegram messages for notifications, admin alerts, errors, logs, daily summaries, and status updates.
14
-
15
- ## Quick start
16
-
17
- Add telegrams to your Gemfile:
18
-
19
- ```ruby
20
- gem 'telegrams'
21
- ```
22
-
23
- Then run:
24
-
25
- ```bash
26
- bundle install
27
- ```
28
-
29
- Then, create an initializer file under `config/initializers/telegrams.rb` and set your credentials:
30
-
31
- ```ruby
32
- Telegrams.configure do |config|
33
- config.bot_token = Rails.application.credentials.dig(Rails.env.to_sym, :telegram, :bot_token)
34
- config.chat_id = Rails.application.credentials.dig(Rails.env.to_sym, :telegram, :chat_id)
35
- config.default_parse_mode = 'MarkdownV2'
36
-
37
- # Default formatting options
38
- config.formatting_options = {
39
- escape_markdown: true, # Escape markdown special characters
40
- obfuscate_emails: false, # Off by default, enable if needed (it anonymizes email addresses in the message to things like abc...d@gmail.com)
41
- escape_html: false, # Optionally escape HTML characters
42
- truncate: 4096 # Truncate if message exceeds Telegram's limit (or a custom limit)
43
- }
44
-
45
- config.deliver_message_async = false # Enable async message delivery with ActiveJob (enqueue the send_message call to offload message sending from the request cycle)
46
- config.deliver_message_queue = 'default' # Use a custom ActiveJob queue
47
- end
48
- ```
49
-
50
- Done!
51
-
52
- You can now send Telegram messages using your bot:
53
-
54
- ```ruby
55
- Telegrams.send_message("Hey, this is your Rails app speaking via Telegram!")
56
- ```
57
-
58
- ## Advanced options
59
-
60
- ### Obfuscate emails in the message
61
-
62
- Sometimes you want to report user actions including a sufficiently identifiable but otherwise anonymous user email. For example, when someone makes gets a refund, you may want to send a message like `john.doe21@email.com got refunded $XX.XX` – but there may be other people / employees in the group chat, so instead of leaking personal, private information, just turn on the `obfuscate_emails` option and the message will automatically get formatted as: `joh...1@email.com got refunded $XX.XX`
63
-
64
- ### Overriding defaults with options
65
-
66
- You can pass an options hash to `Telegrams.send_message` to override default behavior on a per‑message basis:
67
-
68
- - **`chat_id`**
69
- *Override the default chat ID set in your configuration.*
70
- **Usage Example:**
71
- ```ruby
72
- Telegrams.send_message("Hello, alternate group!", chat_id: alternate_chat_id)
73
- ```
74
-
75
- - **`parse_mode`**
76
- *Override the default parse mode (default is `"MarkdownV2"`).*
77
- **Usage Example:**
78
- ```ruby
79
- Telegrams.send_message("Hello, world!", parse_mode: "HTML")
80
- ```
81
-
82
- - **`disable_web_page_preview`**
83
- *Enable or disable web page previews (default is `true`).*
84
- **Usage Example:**
85
- ```ruby
86
- Telegrams.send_message("Check out this link: https://example.com", disable_web_page_preview: false)
87
- ```
88
-
89
- - **`formatting`**
90
- *A hash that overrides the default formatting options provided in the configuration. Available keys include:*
91
- - `escape_markdown` (Boolean): Automatically escape Telegram Markdown special characters.
92
- - `obfuscate_emails` (Boolean): Obfuscate email addresses found in the message.
93
- - `escape_html` (Boolean): Escape HTML entities.
94
- - `truncate` (Integer): Maximum allowed message length (default is `4096`).
95
-
96
- **Usage Example:**
97
- ```ruby
98
- Telegrams.send_message("Contact: john.doe@example.com", formatting: { obfuscate_emails: true })
99
- ```
100
-
101
- ### Asynchronous message delivery
102
-
103
- For production environments or high-traffic applications, you might want to offload message delivery to a background job. Our gem supports asynchronous delivery via ActiveJob.
104
-
105
- With `deliver_message_async` setting enabled, calling:
106
- ```ruby
107
- Telegrams.send_message("Hello asynchronously!")
108
- ```
109
-
110
- will enqueue a job on the specified queue (`deliver_message_queue`) rather than sending the message immediately.
111
-
112
- ## Development
113
-
114
- 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 that will allow you to experiment.
115
-
116
- To install this gem onto your local machine, run `bundle exec rake install`.
117
-
118
- ## Contributing
119
-
120
- Bug reports and pull requests are welcome on GitHub at https://github.com/rameerez/telegrams. Our code of conduct is: just be nice and make your mom proud of what you do and post online.
121
-
122
- ## License
123
-
124
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
3
+ Head to [`telegrama`](https://github.com/rameerez/telegrama)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Telegrams
4
- VERSION = "0.1.0"
4
+ VERSION = "0.1.1"
5
5
  end
data/lib/telegrams.rb CHANGED
@@ -1,42 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Require standard libraries that our gem depends on
4
- require "net/http"
5
- require "uri"
6
- require "json"
7
- require "cgi"
8
-
9
- # Require our gem files
10
- require_relative "telegrams/error"
11
3
  require_relative "telegrams/version"
12
- require_relative "telegrams/configuration"
13
- require_relative "telegrams/formatter"
14
- require_relative "telegrams/client"
15
- require_relative "telegrams/send_message_job"
16
4
 
17
5
  module Telegrams
18
- class << self
19
- # Returns the configuration object.
20
- def configuration
21
- @configuration ||= Configuration.new
22
- end
23
-
24
- def configure
25
- yield(configuration)
26
- configuration.validate!
27
- end
28
-
29
- # Sends a message using the configured settings.
30
- # Before sending, we validate the configuration.
31
- # This way, if nothing’s been set up, we get a descriptive error instead of a low-level one.
32
- def send_message(message, options = {})
33
- configuration.validate!
34
- if configuration.deliver_message_async
35
- SendMessageJob.set(queue: configuration.deliver_message_queue).perform_later(message, options)
36
- else
37
- Client.new.send_message(message, options)
38
- end
39
- end
40
-
41
- end
6
+ class Error < StandardError; end
7
+ # Your code goes here...
42
8
  end
metadata CHANGED
@@ -1,17 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: telegrams
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Javi R
8
8
  bindir: exe
9
9
  cert_chain: []
10
10
  date: 2025-02-18 00:00:00.000000000 Z
11
- dependencies: []
12
- description: Send quick, simple admin / logging Telegram messages via a Telegram bot.
13
- Useful for Rails developers using Telegram messages for notifications, admin alerts,
14
- daily summaries, and status updates. Integrates with the Telegram Bot API.
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: telegrama
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: 0.1.1
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: 0.1.1
26
+ description: You're probably looking for the telegrama gem instead
15
27
  email:
16
28
  - rubygems@rameerez.com
17
29
  executables: []
@@ -23,11 +35,6 @@ files:
23
35
  - README.md
24
36
  - Rakefile
25
37
  - lib/telegrams.rb
26
- - lib/telegrams/client.rb
27
- - lib/telegrams/configuration.rb
28
- - lib/telegrams/error.rb
29
- - lib/telegrams/formatter.rb
30
- - lib/telegrams/send_message_job.rb
31
38
  - lib/telegrams/version.rb
32
39
  - sig/telegrams.rbs
33
40
  homepage: https://github.com/rameerez/telegrams
@@ -55,5 +62,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
55
62
  requirements: []
56
63
  rubygems_version: 3.6.2
57
64
  specification_version: 4
58
- summary: A tiny wrapper to send Telegram admin messages via the Telegram Bot API.
65
+ summary: You're probably looking for the telegrama gem instead
59
66
  test_files: []
@@ -1,49 +0,0 @@
1
- module Telegrams
2
- class Client
3
- def send_message(message, options = {})
4
- # Allow chat ID override; fallback to config default
5
- chat_id = options.delete(:chat_id) || Telegrams.configuration.chat_id
6
-
7
- # Allow runtime formatting options, merging with configured defaults
8
- formatting_opts = options.delete(:formatting) || {}
9
- formatted_message = Formatter.format(message, formatting_opts)
10
-
11
- payload = {
12
- chat_id: chat_id,
13
- text: formatted_message,
14
- parse_mode: options[:parse_mode] || Telegrams.configuration.default_parse_mode,
15
- disable_web_page_preview: options.fetch(:disable_web_page_preview, true)
16
- }
17
-
18
- perform_request(payload)
19
- end
20
-
21
- private
22
-
23
- def perform_request(payload)
24
- uri = URI("https://api.telegram.org/bot#{Telegrams.configuration.bot_token}/sendMessage")
25
- request = Net::HTTP::Post.new(uri, 'Content-Type' => 'application/json')
26
- request.body = payload.to_json
27
-
28
- response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
29
- http.request(request)
30
- end
31
-
32
- unless response.is_a?(Net::HTTPSuccess)
33
- error_info = JSON.parse(response.body) rescue {}
34
- error_description = error_info["description"] || response.body
35
- logger.error("Telegrams API error for chat_id #{payload[:chat_id]}: #{error_description}")
36
- raise Error, "Telegram API error for chat_id #{payload[:chat_id]}: #{error_description}"
37
- end
38
-
39
- response
40
- rescue StandardError => e
41
- logger.error("Failed to send Telegram message: #{e.message}")
42
- raise Error, "Failed to send Telegram message: #{e.message}"
43
- end
44
-
45
- def logger
46
- defined?(Rails) && Rails.respond_to?(:logger) ? Rails.logger : Logger.new($stdout)
47
- end
48
- end
49
- end
@@ -1,103 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Telegrams
4
- class Configuration
5
-
6
- # Your Telegram Bot API token
7
- attr_accessor :bot_token
8
-
9
- # Default chat ID for sending messages.
10
- # You can override this on the fly when sending messages.
11
- attr_accessor :chat_id
12
-
13
- # Default parse mode for messages (e.g. "MarkdownV2" or "HTML").
14
- attr_accessor :default_parse_mode
15
-
16
- # Whether to disable web page previews by default.
17
- attr_accessor :disable_web_page_preview
18
-
19
- # =========================================
20
- # Formatting Options
21
- # =========================================
22
-
23
- # Formatting options used by the Formatter module.
24
- # Available keys:
25
- # :escape_markdown (Boolean) - Escape Telegram markdown special characters.
26
- # :obfuscate_emails (Boolean) - Obfuscate email addresses found in messages.
27
- # :escape_html (Boolean) - Escape HTML entities (<, >, &).
28
- # :truncate (Integer) - Maximum allowed message length.
29
- attr_accessor :formatting_options
30
-
31
- # Whether to deliver messages asynchronously via ActiveJob.
32
- # Defaults to false
33
- attr_accessor :deliver_message_async
34
-
35
- # The ActiveJob queue name to use when enqueuing messages.
36
- # Defaults to 'default'
37
- attr_accessor :deliver_message_queue
38
-
39
- def initialize
40
- # Credentials (must be set via initializer)
41
- @bot_token = nil
42
- @chat_id = nil
43
-
44
- # Defaults for message formatting
45
- @default_parse_mode = 'MarkdownV2'
46
- @disable_web_page_preview = true
47
-
48
- # Sensible defaults for formatting options.
49
- @formatting_options = {
50
- escape_markdown: true,
51
- obfuscate_emails: false,
52
- escape_html: false,
53
- truncate: 4096
54
- }
55
-
56
- @deliver_message_async = false
57
- @deliver_message_queue = 'default'
58
- end
59
-
60
- # Validate the configuration.
61
- # Raise descriptive errors if required settings are missing or invalid.
62
- def validate!
63
- validate_bot_token!
64
- validate_default_parse_mode!
65
- validate_formatting_options!
66
- true
67
- end
68
-
69
- private
70
-
71
- def validate_bot_token!
72
- if bot_token.nil? || bot_token.strip.empty?
73
- raise ArgumentError, "Telegrams configuration error: bot_token cannot be blank."
74
- end
75
- end
76
-
77
- def validate_default_parse_mode!
78
- allowed_modes = ['MarkdownV2', 'HTML', nil]
79
- unless allowed_modes.include?(default_parse_mode)
80
- raise ArgumentError, "Telegrams configuration error: default_parse_mode must be one of #{allowed_modes.inspect}."
81
- end
82
- end
83
-
84
- def validate_formatting_options!
85
- unless formatting_options.is_a?(Hash)
86
- raise ArgumentError, "Telegrams configuration error: formatting_options must be a hash."
87
- end
88
-
89
- %i[escape_markdown obfuscate_emails escape_html].each do |key|
90
- if formatting_options.key?(key) && ![true, false].include?(formatting_options[key])
91
- raise ArgumentError, "Telegrams configuration error: formatting_options[:#{key}] must be true or false."
92
- end
93
- end
94
-
95
- if formatting_options.key?(:truncate)
96
- truncate_val = formatting_options[:truncate]
97
- unless truncate_val.is_a?(Integer) && truncate_val.positive?
98
- raise ArgumentError, "Telegrams configuration error: formatting_options[:truncate] must be a positive integer."
99
- end
100
- end
101
- end
102
- end
103
- end
@@ -1,3 +0,0 @@
1
- module Telegrams
2
- class Error < StandardError; end
3
- end
@@ -1,70 +0,0 @@
1
- module Telegrams
2
- module Formatter
3
- MARKDOWN_SPECIAL_CHARS = %w[_ * [ ] ( ) ~ ` > # + - = | { } . !].freeze
4
- # Characters that should always be escaped in Telegram messages, even when Markdown is enabled
5
- ALWAYS_ESCAPE_CHARS = %w[. !].freeze
6
- # Characters used for Markdown formatting that need special handling
7
- MARKDOWN_FORMAT_CHARS = %w[* _].freeze
8
-
9
- def self.format(text, options = {})
10
- # Merge defaults with any runtime overrides
11
- defaults = Telegrams.configuration.formatting_options || {}
12
- opts = defaults.merge(options)
13
-
14
- text = text.to_s
15
- text = obfuscate_emails(text) if opts[:obfuscate_emails]
16
- text = escape_html(text) if opts[:escape_html]
17
- if opts[:escape_markdown]
18
- text = escape_markdown(text)
19
- else
20
- # When Markdown is enabled (escape_markdown: false), we still need to escape some special characters
21
- text = escape_special_chars(text)
22
- end
23
- text = truncate(text, opts[:truncate]) if opts[:truncate]
24
- text
25
- end
26
-
27
- def self.escape_markdown(text)
28
- MARKDOWN_SPECIAL_CHARS.each do |char|
29
- text = text.gsub(/(?<!\\)#{Regexp.escape(char)}/, "\\#{char}")
30
- end
31
- text
32
- end
33
-
34
- def self.escape_special_chars(text)
35
- # First escape non-formatting special characters
36
- ALWAYS_ESCAPE_CHARS.each do |char|
37
- text = text.gsub(/(?<!\\)#{Regexp.escape(char)}/, "\\#{char}")
38
- end
39
-
40
- # Then handle formatting characters (* and _) by only escaping them when they're not paired
41
- MARKDOWN_FORMAT_CHARS.each do |char|
42
- # Count unescaped occurrences
43
- count = text.scan(/(?<!\\)#{Regexp.escape(char)}/).count
44
-
45
- if count.odd?
46
- # If we have an odd count, escape all occurrences that aren't already escaped
47
- text = text.gsub(/(?<!\\)#{Regexp.escape(char)}/, "\\#{char}")
48
- end
49
- end
50
-
51
- text
52
- end
53
-
54
- def self.obfuscate_emails(text)
55
- text.gsub(/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/) do |email|
56
- local, domain = email.split('@')
57
- obfuscated_local = local.length > 4 ? "#{local[0..2]}...#{local[-1]}" : "#{local[0]}..."
58
- "#{obfuscated_local}@#{domain}"
59
- end
60
- end
61
-
62
- def self.escape_html(text)
63
- text.gsub(/[<>&]/, '<' => '&lt;', '>' => '&gt;', '&' => '&amp;')
64
- end
65
-
66
- def self.truncate(text, max_length)
67
- text.length > max_length ? text[0, max_length] : text
68
- end
69
- end
70
- end
@@ -1,9 +0,0 @@
1
- module Telegrams
2
- class SendMessageJob < ActiveJob::Base
3
- # No default queue provided here -- it's passed from the job call instead
4
-
5
- def perform(message, options = {})
6
- Client.new.send_message(message, options)
7
- end
8
- end
9
- end