Toot toooooooot (Bluesky-Mastodon cross-poster)
1require 'mastodon'
2require 'yaml'
3
4require_relative 'mastodon_api'
5
6class MastodonAccount
7 APP_NAME = "tootify"
8 CONFIG_FILE = File.expand_path(File.join(__dir__, '..', 'config', 'mastodon.yml'))
9 OAUTH_SCOPES = 'read:accounts read:statuses write:media write:statuses'
10
11 def initialize
12 @config = File.exist?(CONFIG_FILE) ? YAML.load(File.read(CONFIG_FILE)) : {}
13 end
14
15 def max_alt_length
16 1500
17 end
18
19 def save_config
20 File.write(CONFIG_FILE, YAML.dump(@config))
21 end
22
23 def oauth_login(handle, email, password)
24 instance = handle.split('@').last
25 app_response = register_oauth_app(instance, OAUTH_SCOPES)
26
27 api = MastodonAPI.new(instance)
28
29 json = api.oauth_login_with_password(
30 app_response.client_id,
31 app_response.client_secret,
32 email, password, OAUTH_SCOPES
33 )
34
35 api.access_token = json['access_token']
36 info = api.account_info
37
38 @config['handle'] = handle
39 @config['access_token'] = api.access_token
40 @config['user_id'] = info['id']
41 save_config
42 end
43
44 def register_oauth_app(instance, scopes)
45 client = Mastodon::REST::Client.new(base_url: "https://#{instance}")
46 client.create_app(APP_NAME, 'urn:ietf:wg:oauth:2.0:oob', scopes)
47 end
48
49 def post_status(text, media_ids = nil)
50 instance = @config['handle'].split('@').last
51 api = MastodonAPI.new(instance, @config['access_token'])
52 api.post_status(text, media_ids)
53 end
54
55 def upload_media(data, filename, content_type, alt = nil)
56 instance = @config['handle'].split('@').last
57 api = MastodonAPI.new(instance, @config['access_token'])
58 api.upload_media(data, filename, content_type, alt)
59 end
60end