+2
-2
app/mastodon_account.rb
+2
-2
app/mastodon_account.rb
···
46
46
client.create_app(APP_NAME, 'urn:ietf:wg:oauth:2.0:oob', scopes)
47
47
end
48
48
49
-
def post_status(text, media_ids = nil)
49
+
def post_status(text, media_ids = nil, parent_id = nil)
50
50
instance = @config['handle'].split('@').last
51
51
api = MastodonAPI.new(instance, @config['access_token'])
52
-
api.post_status(text, media_ids)
52
+
api.post_status(text, media_ids, parent_id)
53
53
end
54
54
55
55
def upload_media(data, filename, content_type, alt = nil)
+2
-1
app/mastodon_api.rb
+2
-1
app/mastodon_api.rb
···
58
58
get_json("/accounts/#{user_id}/statuses", params)
59
59
end
60
60
61
-
def post_status(text, media_ids = nil)
61
+
def post_status(text, media_ids = nil, parent_id = nil)
62
62
params = { status: text }
63
63
params['media_ids[]'] = media_ids if media_ids
64
+
params['in_reply_to_id'] = parent_id if parent_id
64
65
65
66
post_json("/statuses", params)
66
67
end
+23
app/post_history.rb
+23
app/post_history.rb
···
1
+
class PostHistory
2
+
HISTORY_FILE = File.expand_path(File.join(__dir__, '..', 'config', 'history.csv'))
3
+
4
+
def initialize
5
+
if File.exist?(HISTORY_FILE)
6
+
@id_map = File.read(HISTORY_FILE).lines.map { |l| l.strip.split(',') }.then { |pairs| Hash[pairs] }
7
+
else
8
+
@id_map = {}
9
+
end
10
+
end
11
+
12
+
def [](bluesky_rkey)
13
+
@id_map[bluesky_rkey]
14
+
end
15
+
16
+
def add(bluesky_rkey, mastodon_id)
17
+
@id_map[bluesky_rkey] = mastodon_id
18
+
19
+
File.open(HISTORY_FILE, 'a') do |f|
20
+
f.puts("#{bluesky_rkey},#{mastodon_id}")
21
+
end
22
+
end
23
+
end
+36
-9
app/tootify.rb
+36
-9
app/tootify.rb
···
2
2
3
3
require_relative 'bluesky_account'
4
4
require_relative 'mastodon_account'
5
+
require_relative 'post_history'
5
6
6
7
class Tootify
7
8
attr_accessor :check_interval
···
9
10
def initialize
10
11
@bluesky = BlueskyAccount.new
11
12
@mastodon = MastodonAccount.new
13
+
@history = PostHistory.new
12
14
@check_interval = 60
13
15
end
14
16
···
58
60
next
59
61
end
60
62
61
-
if record['value']['reply']
62
-
puts "Skipping reply"
63
-
@bluesky.delete_record_at(like_uri)
64
-
next
63
+
if reply = record['value']['reply']
64
+
parent_uri = reply['parent']['uri']
65
+
prepo = parent_uri.split('/')[2]
66
+
67
+
if prepo != @bluesky.did
68
+
puts "Skipping reply to someone else"
69
+
@bluesky.delete_record_at(like_uri)
70
+
next
71
+
else
72
+
# self-reply, we'll try to cross-post it
73
+
end
65
74
end
66
75
67
-
records << [record['value'], like_uri]
76
+
records << [record['value'], rkey, like_uri]
68
77
end
69
78
70
-
records.sort_by { |x| x[0]['createdAt'] }.each do |record, like_uri|
71
-
post_to_mastodon(record)
79
+
records.sort_by { |x| x[0]['createdAt'] }.each do |record, rkey, like_uri|
80
+
mastodon_parent_id = nil
81
+
82
+
if reply = record['reply']
83
+
parent_uri = reply['parent']['uri']
84
+
prkey = parent_uri.split('/')[4]
85
+
86
+
if parent_id = @history[prkey]
87
+
mastodon_parent_id = parent_id
88
+
else
89
+
puts "Skipping reply to a post that wasn't cross-posted"
90
+
@bluesky.delete_record_at(like_uri)
91
+
next
92
+
end
93
+
end
94
+
95
+
response = post_to_mastodon(record, mastodon_parent_id)
96
+
p response
97
+
98
+
@history.add(rkey, response['id'])
72
99
@bluesky.delete_record_at(like_uri)
73
100
end
74
101
end
···
80
107
end
81
108
end
82
109
83
-
def post_to_mastodon(record)
110
+
def post_to_mastodon(record, mastodon_parent_id = nil)
84
111
p record
85
112
86
113
text = expand_facets(record)
···
121
148
text += "\n\n" + tags.map { |t| '#' + t.gsub(' ', '') }.join(' ')
122
149
end
123
150
124
-
p @mastodon.post_status(text, media_ids)
151
+
@mastodon.post_status(text, media_ids, mastodon_parent_id)
125
152
end
126
153
127
154
def expand_facets(record)