reddit-to-telegram 0.3.1 → 0.5.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +6 -0
- data/Gemfile.lock +1 -1
- data/README.md +12 -9
- data/lib/reddit-to-telegram.rb +7 -24
- data/lib/reddit_to_telegram/errors.rb +1 -0
- data/lib/reddit_to_telegram/post.rb +50 -0
- data/lib/reddit_to_telegram/reddit/fetch.rb +34 -8
- data/lib/reddit_to_telegram/reddit/output/imgur.rb +59 -0
- data/lib/reddit_to_telegram/reddit/output.rb +20 -4
- data/lib/reddit_to_telegram/store/aws_simple_db.rb +11 -0
- data/lib/reddit_to_telegram/telegram/post.rb +2 -1
- data/lib/reddit_to_telegram/telegram/prepare_request.rb +7 -1
- data/lib/reddit_to_telegram/variables.rb +6 -1
- data/lib/reddit_to_telegram/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 81b0c79fce533367384f2a5bce697b0fafa0e914f772ce23e7ac903aeeec1577
|
4
|
+
data.tar.gz: aac0c0448ab4964df36acf62819e2c73e1d7f90d750091fa88b43a1605612580
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1b0f0c32452b4784a50ed4f0557bf1347d84e0fb3f0bc6ba6af1baa0c2426f066283ad9c0a30f22e1232462c2aa2e45f44e637e942208548130152bf5611d081
|
7
|
+
data.tar.gz: 54807fe38f1a4f03e6baff998dc517b1fd3835f435837e75e1ca23809df7b5edef768106a4477f43f9490af63d3df280273e420c153004760e7f19680856aa8b
|
data/.rubocop.yml
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
Metrics/MethodLength:
|
2
2
|
Max: 20
|
3
3
|
|
4
|
+
Naming/VariableNumber:
|
5
|
+
Enabled: false
|
6
|
+
|
4
7
|
Style/Documentation:
|
5
8
|
Enabled: false
|
6
9
|
|
@@ -15,3 +18,6 @@ Style/StringLiterals:
|
|
15
18
|
|
16
19
|
Style/RaiseArgs:
|
17
20
|
Enabled: false
|
21
|
+
|
22
|
+
Style/RedundantRegexpEscape:
|
23
|
+
Enabled: false
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
#### Fetches hot posts from chosen subreddits and pushes them to Telegram channels.
|
6
6
|
|
7
|
-
Beware, this is remotely not production-ready, you'll see lots of bugs and it may break at any time.
|
7
|
+
Beware, this is remotely not production-ready, API will change, you'll see lots of bugs and it may break at any time.
|
8
8
|
Be sure to check for gem updates.
|
9
9
|
|
10
10
|
## Installation
|
@@ -23,21 +23,21 @@ Or `gem install reddit-to-telegram`. Don't forget to `require` it.
|
|
23
23
|
|
24
24
|
To run it, you'll need some env variables set.
|
25
25
|
```
|
26
|
-
RTT_AWS_ACCESS_KEY_ID= # Your AWS access key ID. Needed for AWS SimpleDB storage.
|
26
|
+
RTT_AWS_ACCESS_KEY_ID= # (Optional) Your AWS access key ID. Needed for AWS SimpleDB storage.
|
27
27
|
RTT_AWS_DOMAIN_NAME= # (Optional) Domain name to use for SimpleDB
|
28
|
-
RTT_AWS_REGION= # AWS region your SimpleDB will be hosted on. Beware, it's not available in all regions.
|
29
|
-
RTT_AWS_SECRET_ACCESS_KEY= # Your AWS access key ID. Needed for AWS SimpleDB storage.
|
28
|
+
RTT_AWS_REGION= # (Optional) AWS region your SimpleDB will be hosted on. Beware, it's not available in all regions.
|
29
|
+
RTT_AWS_SECRET_ACCESS_KEY= # (Optional) Your AWS access key ID. Needed for AWS SimpleDB storage.
|
30
30
|
RTT_MAX_STORED_POSTS= # (Optional) Number of posts to store in the database to avoid duplicates, default is 25.
|
31
31
|
RTT_REDDIT_CLIENT_ID= # Reddit app credentials to access API. Might not be needed depending on setup, reddit allows some requests without authentication.
|
32
32
|
RTT_REDDIT_CLIENT_SECRET= # Reddit app credentials to access API. Might not be needed depending on setup, reddit allows some requests without authentication.
|
33
|
-
RTT_STORE_TYPE= # (Optional) Choose between aws_simple_db, memory or temp_file
|
33
|
+
RTT_STORE_TYPE= # (Optional) Choose between aws_simple_db, memory or temp_file. Default is aws_simple_db, so if you're not specifying your AWS credentials, you have to specify another store type.
|
34
34
|
RTT_TELEGRAM_BOT_TOKEN= # The token you've received when you've created a telegram bot.
|
35
35
|
RTT_TEMP_DIR= (Optional) # Directory to write temp files to without trailing /
|
36
36
|
```
|
37
37
|
|
38
38
|
You can also set them dynamically:
|
39
39
|
```
|
40
|
-
RedditToTelegram::Variables.aws.
|
40
|
+
RedditToTelegram::Variables.aws.access_key_id =
|
41
41
|
RedditToTelegram::Variables.telegram.bot_token =
|
42
42
|
```
|
43
43
|
Check out `lib/variables` for list of all available variables.
|
@@ -45,12 +45,15 @@ Check out `lib/variables` for list of all available variables.
|
|
45
45
|
## Usage
|
46
46
|
|
47
47
|
1. Add the bot as administrator to Telegram channels you'd like to post to.
|
48
|
-
2.
|
48
|
+
2. To fetch latest hot post which hasn't been pushed yet:
|
49
49
|
```
|
50
|
-
RedditToTelegram.
|
50
|
+
RedditToTelegram.hot(
|
51
51
|
subreddit_name_1: :telegram_channel_id_1,
|
52
52
|
subreddit_name_2: :telegram_channel_id_2
|
53
53
|
)
|
54
|
-
|
54
|
+
```
|
55
|
+
Or to push one specific post (the only thing you need to set up for this is your telegram bot token):
|
56
|
+
```
|
57
|
+
RedditToTelegram.single("regular_link_to_post", :telegram_channel_id)
|
55
58
|
```
|
56
59
|
Use `:telegram_channel_id` without the `@`.
|
data/lib/reddit-to-telegram.rb
CHANGED
@@ -1,37 +1,20 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "reddit_to_telegram/
|
4
|
-
require_relative "reddit_to_telegram/store"
|
5
|
-
require_relative "reddit_to_telegram/telegram/post"
|
3
|
+
require_relative "reddit_to_telegram/post"
|
6
4
|
require_relative "reddit_to_telegram/version"
|
7
5
|
|
8
6
|
module RedditToTelegram
|
9
7
|
class << self
|
10
|
-
|
11
|
-
return if sources.empty?
|
8
|
+
extend Forwardable
|
12
9
|
|
13
|
-
|
10
|
+
def_delegators :post, :hot, :single
|
14
11
|
|
15
|
-
|
16
|
-
|
17
|
-
handle_res(res, subreddit, telegram_chat_id)
|
18
|
-
end
|
12
|
+
def post
|
13
|
+
Post
|
19
14
|
end
|
20
15
|
|
21
|
-
|
22
|
-
|
23
|
-
def handle_res(res, subreddit, telegram_chat_id)
|
24
|
-
return if res.nil?
|
25
|
-
|
26
|
-
post = find_new_post(subreddit, res)
|
27
|
-
return if post.nil?
|
28
|
-
|
29
|
-
Telegram::Post.push(post, telegram_chat_id)
|
30
|
-
Store::Posts.add(subreddit, post[:id])
|
31
|
-
end
|
32
|
-
|
33
|
-
def find_new_post(subreddit, posts)
|
34
|
-
posts.find { |post| !Store::Posts.dup?(subreddit, post[:id]) }
|
16
|
+
def version
|
17
|
+
VERSION
|
35
18
|
end
|
36
19
|
end
|
37
20
|
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "reddit/fetch"
|
4
|
+
require_relative "store"
|
5
|
+
require_relative "telegram/post"
|
6
|
+
require_relative "variables"
|
7
|
+
|
8
|
+
module RedditToTelegram
|
9
|
+
class Post
|
10
|
+
class << self
|
11
|
+
def hot(sources)
|
12
|
+
return if sources.empty?
|
13
|
+
|
14
|
+
Store.setup
|
15
|
+
|
16
|
+
sources.each do |subreddit, telegram_chat_id|
|
17
|
+
res = Reddit::Fetch.hot(subreddit)
|
18
|
+
handle_res(res, subreddit, telegram_chat_id)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def single(link, telegram_chat_id)
|
23
|
+
return if link.empty?
|
24
|
+
|
25
|
+
Variables.store.type = :memory
|
26
|
+
Store.setup
|
27
|
+
|
28
|
+
res = Reddit::Fetch.post(link)
|
29
|
+
Telegram::Post.push(res, telegram_chat_id)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def handle_res(res, subreddit, telegram_chat_id)
|
35
|
+
return if res.nil?
|
36
|
+
|
37
|
+
post = find_new_post(subreddit, res)
|
38
|
+
return if post.nil?
|
39
|
+
|
40
|
+
res = Telegram::Post.push(post, telegram_chat_id)
|
41
|
+
Store::Posts.add(subreddit, post[:id])
|
42
|
+
res
|
43
|
+
end
|
44
|
+
|
45
|
+
def find_new_post(subreddit, posts)
|
46
|
+
posts.find { |post| !Store::Posts.dup?(subreddit, post[:id]) }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -12,7 +12,9 @@ module RedditToTelegram
|
|
12
12
|
include HTTParty
|
13
13
|
|
14
14
|
BASE_URI = "https://oauth.reddit.com/r"
|
15
|
-
|
15
|
+
WEBSITE_URI = "https://www.reddit.com/r"
|
16
|
+
QUERY_FOR_POST = { g: "GLOBAL" }.freeze
|
17
|
+
QUERY_FOR_SUBREDDIT = QUERY_FOR_POST.merge(limit: Variables.store.max_stored_posts).freeze
|
16
18
|
BASE_HEADERS = {
|
17
19
|
"Content-Type" => "application/json",
|
18
20
|
"Accept" => "application/json"
|
@@ -23,26 +25,50 @@ module RedditToTelegram
|
|
23
25
|
headers = BASE_HEADERS.merge("Authorization" => "Bearer #{Store::Reddit.token}")
|
24
26
|
res = HTTParty.get(
|
25
27
|
"#{BASE_URI}/#{subreddit}/hot.json",
|
26
|
-
query:
|
28
|
+
query: QUERY_FOR_SUBREDDIT,
|
27
29
|
headers:
|
28
30
|
)
|
29
|
-
handle_response(res, subreddit, retries_left)
|
31
|
+
handle_response(res, hot: [subreddit, retries_left])
|
32
|
+
end
|
33
|
+
|
34
|
+
def post(link, retries_left = 5)
|
35
|
+
headers = BASE_HEADERS.merge("Authorization" => "Bearer #{Store::Reddit.token}")
|
36
|
+
res = HTTParty.get(
|
37
|
+
"#{link.gsub('www', 'oauth')}.json",
|
38
|
+
query: QUERY_FOR_POST,
|
39
|
+
headers:
|
40
|
+
)
|
41
|
+
handle_response(res, post: retries_left)
|
30
42
|
end
|
31
43
|
|
32
44
|
private
|
33
45
|
|
34
|
-
def handle_response(res,
|
46
|
+
def handle_response(res, func)
|
47
|
+
func_name = func.keys.first
|
48
|
+
func_args = Array(func.values.first)
|
49
|
+
|
35
50
|
case res.code
|
36
51
|
when 401
|
37
|
-
|
38
|
-
hot(subreddit, retries_left) if retries_left > 0
|
52
|
+
handle_401(func_name, func_args)
|
39
53
|
when 429
|
40
|
-
|
41
|
-
hot(subreddit, retries_left - 1) if retries_left > 0
|
54
|
+
handle_429(func_name, func_args)
|
42
55
|
when 200
|
43
56
|
Output.format_response(res)
|
44
57
|
end
|
45
58
|
end
|
59
|
+
|
60
|
+
def handle_401(func_name, func_args)
|
61
|
+
Store::Reddit.token = Auth.token
|
62
|
+
send(func_name, *func_args) if func_args.last > 0
|
63
|
+
end
|
64
|
+
|
65
|
+
def handle_429(func_name, func_args)
|
66
|
+
retries_left = func_args.last
|
67
|
+
|
68
|
+
sleep(10 / retries_left) if retries_left > 0
|
69
|
+
func_args[func_args.length - 1] = retries_left - 1
|
70
|
+
send(func_name, *func_args) if retries_left > 0
|
71
|
+
end
|
46
72
|
end
|
47
73
|
end
|
48
74
|
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "cgi"
|
4
|
+
|
5
|
+
module RedditToTelegram
|
6
|
+
module Reddit
|
7
|
+
class Output
|
8
|
+
class Imgur
|
9
|
+
class << self
|
10
|
+
def try_extract(data)
|
11
|
+
full_url = decode_imgur_url(data)
|
12
|
+
video_url = extract_video_url(full_url)
|
13
|
+
width = extract_video_width(full_url)
|
14
|
+
return if video_url.nil? || width.nil?
|
15
|
+
|
16
|
+
format_imgur_post(data, video_url, width)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def decode_imgur_url(data)
|
22
|
+
encoded_url = data
|
23
|
+
.dig("media_embed", "content")
|
24
|
+
&.match(/src=\"\S+schema=imgur\"/)&.to_s
|
25
|
+
&.gsub(/src=\"|\"/, 'src=\"' => "", '\"' => "")
|
26
|
+
CGI.unescape(encoded_url)
|
27
|
+
end
|
28
|
+
|
29
|
+
def extract_video_url(full_url)
|
30
|
+
video_url_arr = full_url&.match(/image=(\S+\?|&)/)&.to_s&.send(:[], 6..-2)&.split(".")
|
31
|
+
return if Array(video_url_arr).empty?
|
32
|
+
|
33
|
+
video_url_arr[video_url_arr.length - 1] = "mp4"
|
34
|
+
video_url_arr.join(".")
|
35
|
+
end
|
36
|
+
|
37
|
+
def extract_video_width(full_url)
|
38
|
+
full_url&.match(/w=(\w+)/)&.to_s&.send(:[], 2..)
|
39
|
+
end
|
40
|
+
|
41
|
+
def format_imgur_post(data, video_url, width)
|
42
|
+
RedditToTelegram::Reddit::Output.send(
|
43
|
+
:base_post_format_attrs, data
|
44
|
+
).merge(
|
45
|
+
{
|
46
|
+
type: :video,
|
47
|
+
media: video_url,
|
48
|
+
misc: {
|
49
|
+
binary: false,
|
50
|
+
video_width: width
|
51
|
+
}
|
52
|
+
}
|
53
|
+
)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -1,10 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "cgi"
|
4
|
+
require_relative "output/imgur"
|
5
|
+
|
3
6
|
module RedditToTelegram
|
4
7
|
module Reddit
|
5
8
|
class Output
|
6
9
|
class << self
|
7
10
|
def format_response(res)
|
11
|
+
return format_post(res[0]["data"]["children"][0]) if single_post?(res)
|
12
|
+
|
8
13
|
posts = res["data"]["children"]
|
9
14
|
posts.reject! { |post| post["data"]["stickied"] == true }
|
10
15
|
posts.map { |post| format_post(post) }.compact
|
@@ -12,6 +17,10 @@ module RedditToTelegram
|
|
12
17
|
|
13
18
|
private
|
14
19
|
|
20
|
+
def single_post?(res)
|
21
|
+
res.parsed_response.is_a?(Array) && res[0]["data"]["dist"] == 1
|
22
|
+
end
|
23
|
+
|
15
24
|
def format_post(post)
|
16
25
|
data = post["data"]
|
17
26
|
if data["post_hint"] == "image"
|
@@ -33,6 +42,9 @@ module RedditToTelegram
|
|
33
42
|
end
|
34
43
|
|
35
44
|
def format_link_post(data)
|
45
|
+
res = Imgur.try_extract(data) if data["domain"] == "imgur.com"
|
46
|
+
return res unless res.nil?
|
47
|
+
|
36
48
|
base_post_format_attrs(data).merge(
|
37
49
|
{ type: :text,
|
38
50
|
text: "#{data['title']}\n\n#{data['url']}" }
|
@@ -61,7 +73,9 @@ module RedditToTelegram
|
|
61
73
|
type: :video,
|
62
74
|
media: video_url,
|
63
75
|
misc: {
|
64
|
-
binary: video_data["has_audio"] || false
|
76
|
+
binary: video_data["has_audio"] || false,
|
77
|
+
video_height: video_data["height"],
|
78
|
+
video_width: video_data["width"]
|
65
79
|
}
|
66
80
|
}
|
67
81
|
)
|
@@ -69,12 +83,14 @@ module RedditToTelegram
|
|
69
83
|
|
70
84
|
def base_post_format_attrs(data)
|
71
85
|
{ id: data["name"],
|
72
|
-
text: data["title"] }
|
86
|
+
text: CGI.unescapeHTML(data["title"]) }
|
73
87
|
end
|
74
88
|
|
75
89
|
def prepare_gallery_links(data)
|
76
|
-
data["
|
77
|
-
|
90
|
+
data["gallery_data"]["items"].map do |image|
|
91
|
+
data["media_metadata"].find do |key, _|
|
92
|
+
key == image["media_id"]
|
93
|
+
end[1]["s"]["u"].split("?").first.gsub("preview", "i")
|
78
94
|
end
|
79
95
|
end
|
80
96
|
end
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require "aws-sdk-simpledb"
|
4
4
|
require "json"
|
5
|
+
require_relative "../errors"
|
5
6
|
require_relative "../variables"
|
6
7
|
|
7
8
|
module RedditToTelegram
|
@@ -23,10 +24,20 @@ module RedditToTelegram
|
|
23
24
|
attr_reader :reddit_token
|
24
25
|
|
25
26
|
def setup
|
27
|
+
check_credentials
|
26
28
|
create_domain unless client.list_domains.domain_names.include?(Variables.aws.domain_name)
|
27
29
|
read_db
|
28
30
|
end
|
29
31
|
|
32
|
+
def check_credentials
|
33
|
+
return unless Variables.store.type == :aws_simple_db
|
34
|
+
|
35
|
+
return if Variables.aws.all_present?
|
36
|
+
|
37
|
+
raise(MissingVariables.new("Missing AWS credentials. "\
|
38
|
+
"Set them up or change store type to anything other than aws_simple_db"))
|
39
|
+
end
|
40
|
+
|
30
41
|
def reddit_token=(val)
|
31
42
|
@reddit_token = val
|
32
43
|
write_db
|
@@ -22,13 +22,14 @@ module RedditToTelegram
|
|
22
22
|
|
23
23
|
class << self
|
24
24
|
def push(post, channel)
|
25
|
-
HTTParty.post(
|
25
|
+
res = HTTParty.post(
|
26
26
|
"#{BASE_URI}#{Variables.telegram.bot_token}/send#{METHOD_MAP[post[:type]]}",
|
27
27
|
**params(post, channel)
|
28
28
|
)
|
29
29
|
|
30
30
|
push({ type: :text, id: post[:id], text: post[:text] }, channel) if post[:type] == :gallery
|
31
31
|
Video.delete_file if post[:type] == :video && post.dig(:misc)&.dig(:binary)
|
32
|
+
res
|
32
33
|
end
|
33
34
|
|
34
35
|
private
|
@@ -15,7 +15,13 @@ module RedditToTelegram
|
|
15
15
|
when :text
|
16
16
|
{ chat_id: "@#{chat_id}", text: prepare_text(post, chat_id) }
|
17
17
|
when :video
|
18
|
-
{
|
18
|
+
{
|
19
|
+
chat_id: "@#{chat_id}",
|
20
|
+
video: prepare_video(post),
|
21
|
+
height: post[:misc][:video_height],
|
22
|
+
width: post[:misc][:video_width],
|
23
|
+
caption: prepare_text(post, chat_id)
|
24
|
+
}
|
19
25
|
end
|
20
26
|
end
|
21
27
|
|
@@ -42,10 +42,11 @@ module RedditToTelegram
|
|
42
42
|
end
|
43
43
|
|
44
44
|
class AWS
|
45
|
+
ATTRS = %i[access_key_id secret_access_key region domain_name].freeze
|
45
46
|
DEFAULT_DOMAIN_NAME = "reddit_to_telegram"
|
46
47
|
|
47
48
|
class << self
|
48
|
-
attr_writer
|
49
|
+
attr_writer(*ATTRS)
|
49
50
|
|
50
51
|
def access_key_id
|
51
52
|
@access_key_id ||= ENV["RTT_AWS_ACCESS_KEY_ID"]
|
@@ -62,6 +63,10 @@ module RedditToTelegram
|
|
62
63
|
def domain_name
|
63
64
|
@domain_name ||= ENV["RTT_AWS_DOMAIN_NAME"] || DEFAULT_DOMAIN_NAME
|
64
65
|
end
|
66
|
+
|
67
|
+
def set_up?
|
68
|
+
ATTRS.all? { |a| !a.empty? }
|
69
|
+
end
|
65
70
|
end
|
66
71
|
end
|
67
72
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: reddit-to-telegram
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mark Tityuk
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-03-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk-simpledb
|
@@ -66,9 +66,11 @@ files:
|
|
66
66
|
- README.md
|
67
67
|
- lib/reddit-to-telegram.rb
|
68
68
|
- lib/reddit_to_telegram/errors.rb
|
69
|
+
- lib/reddit_to_telegram/post.rb
|
69
70
|
- lib/reddit_to_telegram/reddit/auth.rb
|
70
71
|
- lib/reddit_to_telegram/reddit/fetch.rb
|
71
72
|
- lib/reddit_to_telegram/reddit/output.rb
|
73
|
+
- lib/reddit_to_telegram/reddit/output/imgur.rb
|
72
74
|
- lib/reddit_to_telegram/store.rb
|
73
75
|
- lib/reddit_to_telegram/store/aws_simple_db.rb
|
74
76
|
- lib/reddit_to_telegram/store/memory.rb
|