spinels-redd 0.9.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 +7 -0
- data/.github/dependabot.yml +7 -0
- data/.github/workflows/ci.yml +52 -0
- data/.gitignore +10 -0
- data/.rspec +3 -0
- data/.rubocop.yml +29 -0
- data/CONTRIBUTING.md +63 -0
- data/Gemfile +6 -0
- data/Guardfile +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +119 -0
- data/Rakefile +12 -0
- data/TODO.md +423 -0
- data/bin/console +127 -0
- data/bin/guard +2 -0
- data/bin/setup +8 -0
- data/docs/guides/.keep +0 -0
- data/docs/tutorials/creating-bots-with-redd.md +101 -0
- data/docs/tutorials/creating-webapps-with-redd.md +124 -0
- data/docs/tutorials/make-a-grammar-bot.md +5 -0
- data/docs/tutorials.md +7 -0
- data/lib/redd/api_client.rb +116 -0
- data/lib/redd/assist/delete_badly_scoring.rb +64 -0
- data/lib/redd/auth_strategies/auth_strategy.rb +68 -0
- data/lib/redd/auth_strategies/script.rb +35 -0
- data/lib/redd/auth_strategies/userless.rb +29 -0
- data/lib/redd/auth_strategies/web.rb +36 -0
- data/lib/redd/client.rb +91 -0
- data/lib/redd/errors.rb +65 -0
- data/lib/redd/middleware.rb +125 -0
- data/lib/redd/models/access.rb +54 -0
- data/lib/redd/models/comment.rb +229 -0
- data/lib/redd/models/front_page.rb +55 -0
- data/lib/redd/models/gildable.rb +13 -0
- data/lib/redd/models/inboxable.rb +33 -0
- data/lib/redd/models/listing.rb +52 -0
- data/lib/redd/models/live_thread.rb +133 -0
- data/lib/redd/models/live_update.rb +46 -0
- data/lib/redd/models/messageable.rb +20 -0
- data/lib/redd/models/mod_action.rb +59 -0
- data/lib/redd/models/model.rb +23 -0
- data/lib/redd/models/moderatable.rb +46 -0
- data/lib/redd/models/modmail.rb +61 -0
- data/lib/redd/models/modmail_conversation.rb +154 -0
- data/lib/redd/models/modmail_message.rb +35 -0
- data/lib/redd/models/more_comments.rb +96 -0
- data/lib/redd/models/multireddit.rb +104 -0
- data/lib/redd/models/paginated_listing.rb +124 -0
- data/lib/redd/models/postable.rb +83 -0
- data/lib/redd/models/private_message.rb +105 -0
- data/lib/redd/models/replyable.rb +16 -0
- data/lib/redd/models/reportable.rb +14 -0
- data/lib/redd/models/searchable.rb +35 -0
- data/lib/redd/models/self.rb +17 -0
- data/lib/redd/models/session.rb +198 -0
- data/lib/redd/models/submission.rb +405 -0
- data/lib/redd/models/subreddit.rb +670 -0
- data/lib/redd/models/trophy.rb +34 -0
- data/lib/redd/models/user.rb +239 -0
- data/lib/redd/models/wiki_page.rb +56 -0
- data/lib/redd/utilities/error_handler.rb +73 -0
- data/lib/redd/utilities/rate_limiter.rb +21 -0
- data/lib/redd/utilities/unmarshaller.rb +70 -0
- data/lib/redd/version.rb +5 -0
- data/lib/redd.rb +129 -0
- data/lib/spinels-redd.rb +3 -0
- data/logo.png +0 -0
- data/spinels-redd.gemspec +39 -0
- metadata +298 -0
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'model'
|
4
|
+
|
5
|
+
module Redd
|
6
|
+
module Models
|
7
|
+
# A backward-expading listing of items.
|
8
|
+
# @see Stream
|
9
|
+
class Listing < Model
|
10
|
+
include Enumerable
|
11
|
+
|
12
|
+
# Create an empty listing with a client.
|
13
|
+
# @param client [APIClient] the client to create the listing with
|
14
|
+
# @return [Listing] the empty listing
|
15
|
+
def self.empty(client)
|
16
|
+
Listing.new(client, children: [])
|
17
|
+
end
|
18
|
+
|
19
|
+
# Create a fully initialized listing.
|
20
|
+
# @param client [APIClient] the api client
|
21
|
+
# @param attributes [Hash] the attribute hash
|
22
|
+
def initialize(client, attributes = {})
|
23
|
+
super
|
24
|
+
fully_loaded!
|
25
|
+
end
|
26
|
+
|
27
|
+
# @return [Array<Comment, Submission, PrivateMessage>] an array representation of self
|
28
|
+
def to_a
|
29
|
+
read_attribute(:children)
|
30
|
+
end
|
31
|
+
alias to_ary to_a
|
32
|
+
|
33
|
+
%i[[] each empty? first last].each do |method_name|
|
34
|
+
define_method(method_name) do |*args, &block|
|
35
|
+
read_attribute(:children).public_send(method_name, *args, &block)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# @!attribute [r] before
|
40
|
+
# @return [String] the fullname of the item before this listing
|
41
|
+
property :before, :nil
|
42
|
+
|
43
|
+
# @!attribute [r] after
|
44
|
+
# @return [String] the fullname of the item that the next listing will start from
|
45
|
+
property :after, :nil
|
46
|
+
|
47
|
+
# @!attribute [r] children
|
48
|
+
# @return [Array<Model>] the listing's children
|
49
|
+
property :children, :required, with: ->(a) { a.map { |m| client.unmarshal(m) } }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'model'
|
4
|
+
|
5
|
+
module Redd
|
6
|
+
module Models
|
7
|
+
# Represents a live thread.
|
8
|
+
class LiveThread < Model
|
9
|
+
# Get the updates from the thread.
|
10
|
+
# @param params [Hash] a list of params to send with the request
|
11
|
+
# @option params [String] :after return results after the given fullname
|
12
|
+
# @option params [String] :before return results before the given fullname
|
13
|
+
# @option params [Integer] :count the number of items already seen in the listing
|
14
|
+
# @option params [1..100] :limit the maximum number of things to return
|
15
|
+
# @return [Listing]
|
16
|
+
def updates(**params)
|
17
|
+
client.model(:get, "/live/#{read_attribute(:id)}", params)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Configure the settings of this live thread
|
21
|
+
# @param params [Hash] a list of params to send with the request
|
22
|
+
# @option params [String] :description the new description
|
23
|
+
# @option params [Boolean] :nsfw whether the thread is for users 18 and above
|
24
|
+
# @option params [String] :resources the new resources
|
25
|
+
# @option params [String] :title the thread title
|
26
|
+
def configure(**params)
|
27
|
+
client.post("/api/live/#{read_attribute(:id)}/edit", params)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Add an update to this live event.
|
31
|
+
# @param body [String] the update text
|
32
|
+
def update(body)
|
33
|
+
client.post("/api/live/#{read_attribute(:id)}/update", body: body)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Strike out a live thread update.
|
37
|
+
# @param live_update [LiveUpdate] the update to strike out
|
38
|
+
def strike_update(live_update)
|
39
|
+
client.post("/api/live/#{read_attribute(:id)}/strike_update", id: live_update.name)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Delete a live thread update.
|
43
|
+
# @param live_update [LiveUpdate] the update to strike out
|
44
|
+
def delete_update(live_update)
|
45
|
+
client.post("/api/live/#{read_attribute(:id)}/delete_update", id: live_update.name)
|
46
|
+
end
|
47
|
+
|
48
|
+
# @return [Array<User>] the contributors to this thread
|
49
|
+
def contributors
|
50
|
+
client.get("/live/#{read_attribute(:id)}/contributors").body[0][:data].map do |user|
|
51
|
+
User.new(client, user)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# @return [Array<User>] users invited to contribute to this thread
|
56
|
+
def invited_contributors
|
57
|
+
client.get("/live/#{read_attribute(:id)}/contributors").body[1][:data].map do |user|
|
58
|
+
User.new(client, user)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Returns all discussions that link to this live thread.
|
63
|
+
# @param params [Hash] a list of params to send with the request
|
64
|
+
# @option params [String] :after return results after the given fullname
|
65
|
+
# @option params [String] :before return results before the given fullname
|
66
|
+
# @option params [Integer] :count the number of items already seen in the listing
|
67
|
+
# @option params [1..100] :limit the maximum number of things to return
|
68
|
+
#
|
69
|
+
# @return [Listing<Submission>]
|
70
|
+
def discussions(**params)
|
71
|
+
client.model(:get, "/live/#{read_attribute(:id)}/discussions", params)
|
72
|
+
end
|
73
|
+
|
74
|
+
# @!attribute [r] id
|
75
|
+
# @return [String] the thread id
|
76
|
+
property :id, :required
|
77
|
+
|
78
|
+
# @!attribute [r] name
|
79
|
+
# @return [String] the thread fullname
|
80
|
+
property :name, default: -> { "LiveUpdateEvent_#{read_attribute(:id)}" }
|
81
|
+
|
82
|
+
# @!attribute [r] description
|
83
|
+
# @return [String] the live thread description
|
84
|
+
property :description
|
85
|
+
|
86
|
+
# @!attribute [r] description_html
|
87
|
+
# @return [String] the html-rendered thread description
|
88
|
+
property :description_html
|
89
|
+
|
90
|
+
# @!attribute [r] title
|
91
|
+
# @return [String] the live thread title
|
92
|
+
property :title
|
93
|
+
|
94
|
+
# @!attribute [r] created_at
|
95
|
+
# @return [String] the live thread creation time
|
96
|
+
property :created_at, from: :created_utc, with: ->(t) { Time.at(t) }
|
97
|
+
|
98
|
+
# @!attribute [r] websocket_url
|
99
|
+
# @return [String] the websocket url for listening to updates
|
100
|
+
property :websocket_url
|
101
|
+
|
102
|
+
# @!attribute [r] state
|
103
|
+
# @return [String] the thread state (e.g. "live")
|
104
|
+
property :state
|
105
|
+
|
106
|
+
# @!attribute [r] nsfw?
|
107
|
+
# @return [Boolean] whether the thread is nsfw
|
108
|
+
property :nsfw?, from: :nsfw
|
109
|
+
|
110
|
+
# @!attribute [r] viewer_count
|
111
|
+
# @return [Integer] the thread viewer count
|
112
|
+
property :viewer_count
|
113
|
+
|
114
|
+
# @!attribute [r] viewer_count_fuzzed?
|
115
|
+
# @return [Boolean] whether the viewer count is fuzzed
|
116
|
+
property :viewer_count_fuzzed?, from: :viewer_count_fuzzed
|
117
|
+
|
118
|
+
# @!attribute [r] resources
|
119
|
+
# @return [String] the thread's resources section
|
120
|
+
property :resources
|
121
|
+
|
122
|
+
# @!attribute [r] resources_html
|
123
|
+
# @return [String] the html-rendered thread resources
|
124
|
+
property :resources_html
|
125
|
+
|
126
|
+
private
|
127
|
+
|
128
|
+
def lazer_reload
|
129
|
+
client.get("/live/#{read_attribute(:id)}/about").body[:data]
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'model'
|
4
|
+
|
5
|
+
module Redd
|
6
|
+
module Models
|
7
|
+
# A live thread update.
|
8
|
+
class LiveUpdate < Model
|
9
|
+
# @!attribute [r] id
|
10
|
+
# @return [String] the update id
|
11
|
+
property :id, :required
|
12
|
+
|
13
|
+
# @!attribute [r] name
|
14
|
+
# @return [String] the update fullname
|
15
|
+
property :name, default: -> { "LiveUpdate_#{read_attribute(:id)}" }
|
16
|
+
|
17
|
+
# @!attribute [r] body
|
18
|
+
# @return [String] the update body
|
19
|
+
property :body
|
20
|
+
|
21
|
+
# @!attribute [r] body_html
|
22
|
+
# @return [String] the html-rendered update body
|
23
|
+
property :body_html
|
24
|
+
|
25
|
+
# @!attribute [r] embeds
|
26
|
+
# @return [Array]
|
27
|
+
property :embeds
|
28
|
+
|
29
|
+
# @!attribute [r] mobile_embeds
|
30
|
+
# @return [Array]
|
31
|
+
property :mobile_embeds
|
32
|
+
|
33
|
+
# @!attribute [r] author
|
34
|
+
# @return [User] the poster of the update
|
35
|
+
property :author, with: ->(n) { User.new(client, name: n) }
|
36
|
+
|
37
|
+
# @!attribute [r] created_at
|
38
|
+
# @return [Time] the post time
|
39
|
+
property :created_at, from: :created_utc, with: ->(t) { Time.at(t) }
|
40
|
+
|
41
|
+
# @!attribute [r] stricken?
|
42
|
+
# @return [Boolean] whether the update is stricken
|
43
|
+
property :stricken?, from: :stricken
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Redd
|
4
|
+
module Models
|
5
|
+
# A model that can be messaged (i.e. Users and Subreddits).
|
6
|
+
module Messageable
|
7
|
+
# Compose a message to a person or the moderators of a subreddit.
|
8
|
+
#
|
9
|
+
# @param to [String] the thing to send the message to (overriden by User and Subreddit)
|
10
|
+
# @param subject [String] the subject of the message
|
11
|
+
# @param text [String] the message text
|
12
|
+
# @param from [Subreddit, nil] the subreddit to send the message on behalf of
|
13
|
+
def send_message(to:, subject:, text:, from: nil)
|
14
|
+
params = { to: to, subject: subject, text: text }
|
15
|
+
params[:from_sr] = from.display_name if from
|
16
|
+
client.post('/api/compose', params)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'model'
|
4
|
+
|
5
|
+
module Redd
|
6
|
+
module Models
|
7
|
+
# Represents a moderator action, part of a moderation log.
|
8
|
+
# @see Subreddit#mod_log
|
9
|
+
class ModAction < Model
|
10
|
+
# @!attribute [r] description
|
11
|
+
# @return [String] the action description
|
12
|
+
property :description
|
13
|
+
|
14
|
+
# @!attribute [r] target_title
|
15
|
+
# @return [String] the title of the item that was targeted
|
16
|
+
property :target_title
|
17
|
+
|
18
|
+
# @!attribute [r] target_body
|
19
|
+
# @return [String] the body of the item that was targeted
|
20
|
+
property :target_body
|
21
|
+
|
22
|
+
# @!attribute [r] target_permalink
|
23
|
+
# @return [String] the **relative** permalink to the item
|
24
|
+
property :target_permalink
|
25
|
+
|
26
|
+
# @!attribute [r] target_author
|
27
|
+
# @return [User] the target user
|
28
|
+
property :target_author, with: ->(n) { User.new(client, name: n) }
|
29
|
+
|
30
|
+
# @!attribute [r] mod_id36
|
31
|
+
# @return [String] the id of the moderator that performed this action
|
32
|
+
property :mod_id36
|
33
|
+
|
34
|
+
# @!attribute [r] created_at
|
35
|
+
# @return [Time] the time when the action was done
|
36
|
+
property :created_at, from: :created_utc, with: ->(t) { Time.at(t) }
|
37
|
+
|
38
|
+
# @!attribute [r] subreddit
|
39
|
+
# @return [Subreddit] the subreddit the action was performed on
|
40
|
+
property :subreddit, with: ->(n) { Subreddit.new(client, display_name: n) }
|
41
|
+
|
42
|
+
# @!attribute [r] subreddit_name_prefixed
|
43
|
+
# @return [String] the subreddit name, prefixed with a "r/"
|
44
|
+
property :subreddit_name_prefixed
|
45
|
+
|
46
|
+
# @!attribute [r] subreddit_id36
|
47
|
+
# @return [String] the subreddit's id
|
48
|
+
property :subreddit_id36, from: :sr_id36
|
49
|
+
|
50
|
+
# @!attribute [r] details
|
51
|
+
# @return [String] the action details
|
52
|
+
property :details
|
53
|
+
|
54
|
+
# @!attribute [r] action
|
55
|
+
# @return [String] the action type
|
56
|
+
property :action
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'lazy_lazer'
|
4
|
+
|
5
|
+
module Redd
|
6
|
+
module Models
|
7
|
+
# A base model class.
|
8
|
+
class Model
|
9
|
+
include LazyLazer
|
10
|
+
|
11
|
+
# @return [Client] the model's client
|
12
|
+
attr_reader :client
|
13
|
+
|
14
|
+
# Create a new Model.
|
15
|
+
# @param client [Client] the model's client
|
16
|
+
# @param attributes [Hash] the model's attributes
|
17
|
+
def initialize(client, attributes = {})
|
18
|
+
super(attributes)
|
19
|
+
@client = client
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Redd
|
4
|
+
module Models
|
5
|
+
# A model that can be managed by a moderator (i.e. Submissions and Comments).
|
6
|
+
module Moderatable
|
7
|
+
# Approve a submission.
|
8
|
+
def approve
|
9
|
+
client.post('/api/approve', id: read_attribute(:name))
|
10
|
+
end
|
11
|
+
|
12
|
+
# Remove a submission.
|
13
|
+
# @param spam [Boolean] whether or not this item is removed due to it being spam
|
14
|
+
def remove(spam: false)
|
15
|
+
client.post('/api/remove', id: read_attribute(:name), spam: spam)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Distinguish a link or comment with a sigil to show that it has been created by a moderator.
|
19
|
+
# @param how [:yes, :no, :admin, :special, :sticky] how to distinguish the thing
|
20
|
+
# @note :sticky is for comments. see {Submission#make_sticky} for posts.
|
21
|
+
def distinguish(how = :yes)
|
22
|
+
params = { id: read_attribute(:name), how: how }
|
23
|
+
if how == :sticky
|
24
|
+
params[:how] = :yes
|
25
|
+
params[:sticky] = true
|
26
|
+
end
|
27
|
+
client.post('/api/distinguish', params)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Remove the sigil that shows a thing was created by a moderator.
|
31
|
+
def undistinguish
|
32
|
+
distinguish(:no)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Stop getting any moderator-related reports on the thing.
|
36
|
+
def ignore_reports
|
37
|
+
client.post('/api/ignore_reports', id: read_attribute(:name))
|
38
|
+
end
|
39
|
+
|
40
|
+
# Start getting moderator-related reports on the thing again.
|
41
|
+
def unignore_reports
|
42
|
+
client.post('/api/unignore_reports', id: read_attribute(:name))
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'model'
|
4
|
+
require_relative 'subreddit'
|
5
|
+
|
6
|
+
module Redd
|
7
|
+
module Models
|
8
|
+
# A container for the new modmail.
|
9
|
+
class Modmail < Model
|
10
|
+
# @return [Hash<Symbol, Integer>] the number of unread messages in each category
|
11
|
+
def unread_count
|
12
|
+
client.get('/api/mod/conversations/unread/count').body
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return [Array<Subreddit>] moderated subreddits that are enrolled in the new modmail
|
16
|
+
def enrolled
|
17
|
+
client.get('/api/mod/conversations/subreddits').body[:subreddits].map do |_, s|
|
18
|
+
Subreddit.new(client, s.merge(last_updated: s.delete(:lastUpdated)))
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Get the conversations
|
23
|
+
# @param subreddits [Subreddit, Array<Subreddit>] the subreddits to limit to
|
24
|
+
# @param params [Hash] additional request parameters
|
25
|
+
# @option params [String] :after base36 modmail conversation id
|
26
|
+
# @option params [Integer] :limit an integer (default: 25)
|
27
|
+
# @option params [:recent, :mod, :user, :unread] :sort the sort order
|
28
|
+
# @option params [:new, :inprogress, :mod, :notifications, :archived, :highlighted, :all]
|
29
|
+
# :state the state to limit the conversations by
|
30
|
+
# @return [Array<ModmailConversation>] the conversations
|
31
|
+
def conversations(subreddits: nil, **params)
|
32
|
+
params[:entity] = Array(subreddits).map(&:display_name).join(',') if subreddits
|
33
|
+
client.get('/api/mod/conversations', **params)
|
34
|
+
.body[:conversations]
|
35
|
+
.values
|
36
|
+
.map { |conv| ModmailConversation.new(client, conv) }
|
37
|
+
end
|
38
|
+
|
39
|
+
# Create a new conversation.
|
40
|
+
# @param from [Subreddit] the subreddit to send the conversation from
|
41
|
+
# @param to [User] the person to send the message to
|
42
|
+
# @param subject [String] the message subject
|
43
|
+
# @param body [String] the message body
|
44
|
+
# @return [ModmailConversation] the created conversation
|
45
|
+
def create(from:, to:, subject:, body:, hidden: false)
|
46
|
+
ModmailConversation.new(client, client.post(
|
47
|
+
'/api/mod/conversations',
|
48
|
+
srName: from.display_name, to: to.name,
|
49
|
+
subject: subject, body: body, isAuthorHidden: hidden
|
50
|
+
).body[:conversation])
|
51
|
+
end
|
52
|
+
|
53
|
+
# Get a conversation from its base36 id.
|
54
|
+
# @param id [String] the conversation's id
|
55
|
+
# @return [ModmailConversation]
|
56
|
+
def get(id)
|
57
|
+
ModmailConversation.new(client, id: id)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,154 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'time'
|
4
|
+
require_relative 'model'
|
5
|
+
|
6
|
+
module Redd
|
7
|
+
module Models
|
8
|
+
# Represents a conversation in the new modmail.
|
9
|
+
class ModmailConversation < Model
|
10
|
+
# Add a reply to the ongoing conversation.
|
11
|
+
# @param body [String] the message body (probably markdown)
|
12
|
+
# @param hidden [Boolean] whether the message is hidden
|
13
|
+
# @param internal [Boolean] whether the message is internal
|
14
|
+
def reply(body, hidden: false, internal: false)
|
15
|
+
# TODO: merge response into the conversation
|
16
|
+
client.post(
|
17
|
+
"/api/mod/conversations/#{read_attribute(:id)}",
|
18
|
+
body: body, isAuthorHidden: hidden, isInternal: internal
|
19
|
+
).body
|
20
|
+
end
|
21
|
+
|
22
|
+
# Mark this conversation as read.
|
23
|
+
def mark_as_read
|
24
|
+
client.post('/api/mod/conversations/read', conversationIds: [read_attribute(:id)])
|
25
|
+
end
|
26
|
+
|
27
|
+
# Mark this conversation as unread.
|
28
|
+
def mark_as_unread
|
29
|
+
client.post('/api/mod/conversations/unread', conversationIds: [read_attribute(:id)])
|
30
|
+
end
|
31
|
+
|
32
|
+
# Mark this conversation as archived.
|
33
|
+
def archive
|
34
|
+
perform_action(:post, 'archive')
|
35
|
+
end
|
36
|
+
|
37
|
+
# Removed this conversation from archived.
|
38
|
+
def unarchive
|
39
|
+
perform_action(:post, 'unarchive')
|
40
|
+
end
|
41
|
+
|
42
|
+
# Highlight this conversation.
|
43
|
+
def highlight
|
44
|
+
perform_action(:post, 'highlight')
|
45
|
+
end
|
46
|
+
|
47
|
+
# Remove the highlight on this conversation.
|
48
|
+
def unhighlight
|
49
|
+
perform_action(:delete, 'highlight')
|
50
|
+
end
|
51
|
+
|
52
|
+
# Mute this conversation.
|
53
|
+
def mute
|
54
|
+
perform_action(:post, 'mute')
|
55
|
+
end
|
56
|
+
|
57
|
+
# Unmute this conversation.
|
58
|
+
def unmute
|
59
|
+
perform_action(:post, 'unmute')
|
60
|
+
end
|
61
|
+
|
62
|
+
# @!attribute [r] id
|
63
|
+
# @return [String] the conversation id
|
64
|
+
property :id, :required
|
65
|
+
|
66
|
+
# @!attribute [r] messages
|
67
|
+
# @return [Array<ModmailMessage>] the modmail messages
|
68
|
+
property :messages, with: ->(hsh) { hsh.values.map { |m| ModmailMessage.new(client, m) } }
|
69
|
+
|
70
|
+
# @!attribute [r] user
|
71
|
+
# @return [Object] FIXME: details about the user the conversation deals with
|
72
|
+
property :user
|
73
|
+
|
74
|
+
# @!attribute [r] auto?
|
75
|
+
# @return [Boolean]
|
76
|
+
property :auto?, from: :isAuto
|
77
|
+
|
78
|
+
# @!attribute [r] message_ids
|
79
|
+
# @return [Array<String>] the conversation's message ids
|
80
|
+
property :message_ids, from: :objIds
|
81
|
+
|
82
|
+
# @!attribute [r] replyable?
|
83
|
+
# @return [Boolean] whether you can reply to this conversation
|
84
|
+
property :replyable?, from: :isRepliable
|
85
|
+
|
86
|
+
# @!attribute [r] last_user_update
|
87
|
+
# @return [Time] the time of last user update
|
88
|
+
property :last_user_update, from: :lastUserUpdate, with: ->(t) { Time.parse(t) }
|
89
|
+
|
90
|
+
# @!attribute [r] internal?
|
91
|
+
# @return [Boolean]
|
92
|
+
property :internal?, from: :isInternal
|
93
|
+
|
94
|
+
# @!attribute [r] last_mod_update
|
95
|
+
# @return [Time] the time of last mod update
|
96
|
+
property :last_mod_update, from: :lastModUpdate, with: ->(t) { Time.parse(t) }
|
97
|
+
|
98
|
+
# @!attribute [r] last_updated
|
99
|
+
# @return [Time] the time of last update
|
100
|
+
property :last_updated, from: :lastUpdated, with: ->(t) { Time.parse(t) }
|
101
|
+
|
102
|
+
# @!attribute [r] authors
|
103
|
+
# @return [Array<Hash>] FIXME: apply conversions
|
104
|
+
property :authors
|
105
|
+
|
106
|
+
# @!attribute [r] owner
|
107
|
+
# @return [Hash] FIXME: do shit
|
108
|
+
property :owner
|
109
|
+
|
110
|
+
# @!attribute [r] highlighted?
|
111
|
+
# @return [Boolean] whether the conversation is highlighted
|
112
|
+
property :highlighted?, from: :isHighlighted
|
113
|
+
|
114
|
+
# @!attribute [r] subject
|
115
|
+
# @return [String] the conversation subject
|
116
|
+
property :subject
|
117
|
+
|
118
|
+
# @!attribute [r] participant
|
119
|
+
# @return [Hash] FIXME: do shit
|
120
|
+
property :participant
|
121
|
+
|
122
|
+
# @!attribute [r] state
|
123
|
+
# @return [Integer]
|
124
|
+
property :state
|
125
|
+
|
126
|
+
# @!attribute [r] last_unread
|
127
|
+
# @return [Object]
|
128
|
+
property :last_unread, from: :lastUnread
|
129
|
+
|
130
|
+
# @!attribute [r] message_count
|
131
|
+
# @return [Integer] the message count
|
132
|
+
property :message_count, from: :numMessages
|
133
|
+
|
134
|
+
private
|
135
|
+
|
136
|
+
def lazer_reload
|
137
|
+
fully_loaded!
|
138
|
+
response = client.get("/api/mod/conversations/#{read_attribute(:id)}").body
|
139
|
+
response[:conversation].merge(
|
140
|
+
messages: response[:messages],
|
141
|
+
user: response[:user],
|
142
|
+
modActions: response[:modActions]
|
143
|
+
)
|
144
|
+
end
|
145
|
+
|
146
|
+
# Perform an action on a conversation.
|
147
|
+
# @param method [:post, :delete] the method to use
|
148
|
+
# @param action [String] the name of the action
|
149
|
+
def perform_action(method, action)
|
150
|
+
client.send(method, "/api/mod/conversations/#{read_attribute(:id)}/#{action}")
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'time'
|
4
|
+
require_relative 'model'
|
5
|
+
|
6
|
+
module Redd
|
7
|
+
module Models
|
8
|
+
# Represents a message in the new modmail.
|
9
|
+
class ModmailMessage < Model
|
10
|
+
# @!attribute [r] id
|
11
|
+
# @return [String] the message id
|
12
|
+
property :id
|
13
|
+
|
14
|
+
# @!attribute [r] body
|
15
|
+
# @return [String] the html conversation body
|
16
|
+
property :body
|
17
|
+
|
18
|
+
# @!attribute [r] markdown_body
|
19
|
+
# @return [String] the body in markdown form
|
20
|
+
property :markdown_body, from: :bodyMarkdown
|
21
|
+
|
22
|
+
# @!attribute [r] author
|
23
|
+
# @return [Object] FIXME: do shit
|
24
|
+
property :author
|
25
|
+
|
26
|
+
# @!attribute [r] internal?
|
27
|
+
# @return [Boolean] whether the message is internal
|
28
|
+
property :internal?, from: :isInternal
|
29
|
+
|
30
|
+
# @!attribute [r] date
|
31
|
+
# @return [Time] the message date
|
32
|
+
property :date, with: ->(t) { Time.parse(t) }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|