+22
-3
app/mastodon_account.rb
+22
-3
app/mastodon_account.rb
···
4
4
class MastodonAccount
5
5
APP_NAME = "Tootify"
6
6
CONFIG_FILE = File.expand_path(File.join(__dir__, '..', 'config', 'mastodon.yml'))
7
-
OAUTH_SCOPES = 'read:accounts read:statuses write:media write:statuses'
7
+
8
+
OAUTH_SCOPES = [
9
+
'read:accounts',
10
+
'read:statuses',
11
+
'read:search',
12
+
'write:media',
13
+
'write:statuses'
14
+
].join(' ')
8
15
9
16
def initialize
10
17
@config = File.exist?(CONFIG_FILE) ? YAML.load(File.read(CONFIG_FILE)) : {}
···
52
59
api.register_oauth_app(APP_NAME, OAUTH_SCOPES)
53
60
end
54
61
55
-
def post_status(text, media_ids = nil, parent_id = nil)
62
+
def instance_info
56
63
instance = @config['handle'].split('@').last
57
64
api = MastodonAPI.new(instance, @config['access_token'])
58
-
api.post_status(text, media_ids, parent_id)
65
+
api.instance_info
66
+
end
67
+
68
+
def post_status(text, media_ids: nil, parent_id: nil, quoted_status_id: nil)
69
+
instance = @config['handle'].split('@').last
70
+
api = MastodonAPI.new(instance, @config['access_token'])
71
+
api.post_status(text, media_ids: media_ids, parent_id: parent_id, quoted_status_id: quoted_status_id)
59
72
end
60
73
61
74
def upload_media(data, filename, content_type, alt = nil)
···
63
76
api = MastodonAPI.new(instance, @config['access_token'])
64
77
api.upload_media(data, filename, content_type, alt)
65
78
end
79
+
80
+
def search_post_by_url(url)
81
+
instance = @config['handle'].split('@').last
82
+
api = MastodonAPI.new(instance, @config['access_token'])
83
+
api.search_post_by_url(url)
84
+
end
66
85
end
+16
-1
app/mastodon_api.rb
+16
-1
app/mastodon_api.rb
···
74
74
get_json("/accounts/verify_credentials")
75
75
end
76
76
77
+
def instance_info
78
+
get_json("https://#{@host}/api/v2/instance")
79
+
end
80
+
77
81
def lookup_account(username)
78
82
json = get_json("/accounts/lookup", { acct: username })
79
83
raise UnexpectedResponseError.new unless json.is_a?(Hash) && json['id'].is_a?(String)
···
84
88
get_json("/accounts/#{user_id}/statuses", params)
85
89
end
86
90
87
-
def post_status(text, media_ids = nil, parent_id = nil)
91
+
def post_status(text, media_ids: nil, parent_id: nil, quoted_status_id: nil)
88
92
params = { status: text }
89
93
params['media_ids[]'] = media_ids if media_ids
90
94
params['in_reply_to_id'] = parent_id if parent_id
95
+
params['quoted_status_id'] = quoted_status_id if quoted_status_id
91
96
92
97
post_json("/statuses", params)
93
98
end
···
127
132
128
133
def get_media(media_id)
129
134
get_json("/media/#{media_id}")
135
+
end
136
+
137
+
def search_post_by_url(url)
138
+
json = get_json("https://#{@host}/api/v2/search", {
139
+
q: url,
140
+
type: 'statuses',
141
+
resolve: true
142
+
})
143
+
144
+
json['statuses'] && json['statuses'][0]
130
145
end
131
146
132
147
def get_json(path, params = {})
+18
-3
app/tootify.rb
+18
-3
app/tootify.rb
···
135
135
136
136
if collection == 'app.bsky.feed.post'
137
137
link_to_append = bsky_post_link(repo, rkey)
138
+
instance_info = @mastodon.instance_info
138
139
139
-
if @config['extract_link_from_quotes']
140
+
if instance_info.dig('api_versions', 'mastodon').to_i >= 7
140
141
quoted_record = fetch_record_by_at_uri(quote_uri)
141
142
143
+
# TODO: we need to wait for Bridgy to add support for quote_authorizations
144
+
quoted_post_url = quoted_record['bridgyOriginalUrl'] #|| "https://bsky.brid.gy/convert/ap/#{quote_uri}"
145
+
146
+
if quoted_post_url && (local_post = @mastodon.search_post_by_url(quoted_post_url))
147
+
quote_policy = local_post.dig('quote_approval', 'current_user')
148
+
149
+
if quote_policy == 'automatic' || quote_policy == 'manual'
150
+
quote_id = local_post['id']
151
+
end
152
+
end
153
+
end
154
+
155
+
if !quote_id && @config['extract_link_from_quotes']
156
+
quoted_record ||= fetch_record_by_at_uri(quote_uri)
142
157
quote_link = link_embed(quoted_record)
143
158
144
159
if quote_link.nil?
···
151
166
end
152
167
end
153
168
154
-
append_link(text, link_to_append) unless text.include?(link_to_append)
169
+
append_link(text, link_to_append) unless quote_id || text.include?(link_to_append)
155
170
end
156
171
end
157
172
···
191
206
text += "\n\n" + tags.map { |t| '#' + t.gsub(' ', '') }.join(' ')
192
207
end
193
208
194
-
@mastodon.post_status(text, media_ids, mastodon_parent_id)
209
+
@mastodon.post_status(text, media_ids: media_ids, parent_id: mastodon_parent_id, quoted_status_id: quote_id)
195
210
end
196
211
197
212
def fetch_record_by_at_uri(quote_uri)