diff --git a/bienvenibot.py b/bienvenibot.py index 2a14af1..a0dab28 100644 --- a/bienvenibot.py +++ b/bienvenibot.py @@ -1,5 +1,6 @@ from common import get_api from common import list_read +from common import list_append from common import list_write # Messages @@ -9,28 +10,25 @@ message = "¡Hola! Soy Roberto, el administrador de este servidor de Mastodon :m # Initialization bot_name = 'bienvenibot' api = get_api('masto.es', 'rober') -last_ids = list_read(bot_name) -new_last_ids=[] -max_notifications=5 -notifications = api.notifications(limit=max_notifications) -#notifications = mastodon.notifications(types=["admin.sign_up"], limit=5) +users = list_read(bot_name) +users_limited = list_read(bot_name + "_limited") +users_limited_new = [] +notifications = api.notifications(types=["admin.sign_up"]) + +def try_dm(user): + try: + api.status_post("@" + user + " " + message, visibility="direct") + except: + users_limited_new.append(user) + +for user in users_limited: + try_dm(user) + for n in notifications: - new_last_ids.append(n['id']) + # Message new users + user = n['account']['acct'] + if n['type'] == "admin.sign_up" and user not in users: + list_append(bot_name, user) + try_dm(user) -# Some notifications may have been deleted since last fetch -# Therefore, it is better to check less than the maximum number of notifications -for i in range(0, max_notifications - 1): - n = notifications[i] - if str(n['id']) not in last_ids: - # Message new users - username = n['account']['acct'] - if n['type'] == "admin.sign_up": - api.status_post("@" + username + " " + message, visibility="direct") - # Follow any user who interacted with our account - #elif not "@" in username: - elif n['type'] == "follow": - api.account_follow(n['account']['id']) - elif n['type'] == "admin.report": - api.status_post("@Roboron@im-in.space Informe recibido de " + username, visibility="direct") - -list_write(bot_name, new_last_ids) +list_write(bot_name + "_limited", users_limited_new) diff --git a/common.py b/common.py index f99297f..6ac5ef2 100644 --- a/common.py +++ b/common.py @@ -14,7 +14,7 @@ def get_api(url, token_name = ""): else: token = "" - return Mastodon(access_token = token, api_base_url = url) + return Mastodon(access_token = token, api_base_url = url, ratelimit_method='throw') def list_read(name): try: @@ -22,11 +22,12 @@ def list_read(name): except FileNotFoundError: file = open('list/' + name, 'x') file.close() - return [""] + return [] else: list = file.read().splitlines() file.close() return list + def list_write(name, values): file = open('list/' + name, 'w') for value in values: diff --git a/federabot.py b/federabot.py index 6b9bff9..f4ce8ae 100644 --- a/federabot.py +++ b/federabot.py @@ -21,47 +21,73 @@ excluded_domains = [ 'mastorol.es', 'shrimply.social', 'mstdn.jmiguel.eu', - # Relay chocoflan - 'mk.mistli.net', - 'izta.mistli.net', - 'novoa.nagoya', - 'quey.la', - 'social.hispabot.freemyip.com', - 'mastodon.uy', - 'mstdn.mx', - 'el-spot.xyz', - 'mastodonperu.xyz', + 'mastorock.com', + 'frikiverse.zone', '41020.social', - #'mast.lat', - 'acc4e.com', - #'mastodon.com.py', - #'shrimply.social', - 'nonomastodon.redirectme.net', - 'arguos.com', - 'social.wikimedia.es', - 'tarugo.ddns.net', - 'pleroma.lyricaltokarev.fun', + 'tuiter.rocks', + 'mastorock.com', + 'meetiko.org', + 'mastodon.cr', # Relay nobigtech.es 'sindicato.social', - #'mastodon.uy', + 'mastodon.uy', 'red.niboe.info', 'nobigtech.es', 'loa.masto.host', 'bizkaia.social', - #'mstdn.mx', + 'mstdn.mx', 'federa.social', # Non-spanish accounts >:( - 'sportsbots.xyz' + 'sportsbots.xyz', + 'press.coop' ] bot_name = 'federabot' api_mastoes = get_api('masto.es', 'rober') + following = list_read(bot_name) -date_recent = datetime.today() - timedelta(days=7) +date_recent = datetime.today() - timedelta(days=30) + +follows_limited = list_read(bot_name + '_follows_limited') +dms_limited = list_read(bot_name + '_messages_limited') + +list_write(bot_name + "_follows_limited", []) +list_write(bot_name + "_messages_limited", []) + +def try_follow(user_id): + try: + api_mastoes.account_follow(user_id) + except: + list_append(bot_name + '_follows_limited', str(user_id)) + print("Fail to follow. Will retry next time") + +def try_dm(username, user_domain): + try: + api_mastoes.status_post("@" + username + " " + get_message(user_domain), visibility="direct") + print("Welcome new user: " + username) + except: + list_append(bot_name + '_messages_limited', username) + print("Fail to welcome new user: " + username + ". Will retry next time") + +def check_follows(): + notifications = api_mastoes.notifications(types=["follow"]) + for n in notifications: + username = n['account']['acct'] + user_domain = username.split("@")[1] if "@" in username else "masto.es" + date_created = n['account']['created_at'].replace(tzinfo=None) + if username not in following: + print("Following: " + username) + try_follow(n['account']['id']) + following.append(username) + list_append(bot_name, username) + if date_created > date_recent and user_domain == 'mastodon.social': + try_dm(username, user_domain) def check_timeline(domain, timeline_name = 'public', api_external=None): + if api_external is None: api_external = get_api(domain) + last_id = list_read(bot_name + "_last_id_" + domain)[0] timeline = api_external.timeline( timeline=timeline_name, @@ -84,24 +110,38 @@ def check_timeline(domain, timeline_name = 'public', api_external=None): ): date_created = post['account']['created_at'].replace(tzinfo=None) if date_created > date_recent and timeline_name == 'local' and user_domain == 'mastodon.social': - print("New user: " + username) - api_mastoes.status_post("@" + username + " " + get_message(user_domain), visibility="direct") + try_dm(username, user_domain) print("Following: " + username) user = api_mastoes.search_v2("@" + username + " ", result_type="accounts")["accounts"][0] # Retrieve the post, it could be the first api_mastoes.search_v2(post['url'], result_type="posts") - api_mastoes.account_follow(user['id']) following.append(username) list_append(bot_name, username) + try_follow(user['id']) if len(timeline) > 0: list_write(bot_name + "_last_id_" + domain, [timeline[0]['id']]) -api=get_api('masto.es', bot_name) -check_timeline('masto.es', api_external=api) + +print('\nChecking previous attempts...') +for user_id in follows_limited: + try_follow(user_id) + +for username in dms_limited: + user_domain = username.split("@")[1] + try_dm(username, user_domain) + +print('\nChecking follows...') +check_follows() + api=get_api('mastodon.social', bot_name + "_mastodon_social") +print('\nChecking mastodon.social local TL') check_timeline('mastodon.social', 'local', api_external=api) +print('\nChecking mastodon.social federated TL') check_timeline('mastodon.social', 'public', api_external=api) +print('\nChecking masto.es federated TL') +api=get_api('masto.es', bot_name) +check_timeline('masto.es', api_external=api)