masto-tools/masto_tools/scripts/mass_dm.py

90 lines
2.8 KiB
Python

"""
DM All
"""
# from masto_tools.script import Script
# class MassDM(Script):
# """
# Send a message to everyone on the instance :)
#
# fuck it getting tired come back to making formal script mode later
# just do functional mode for now
# """
from typing import List, Optional
from argparse import ArgumentParser, Namespace
from masto_tools.init import log_in
from warnings import warn
from mastodon import Mastodon
def get_accounts(client) -> List[dict]:
# get first page of accounts
first_accounts = client.admin_accounts()
# then paginate
accounts = client.fetch_remaining(first_accounts)
return accounts
def filter_accounts(accounts:List[dict]) -> List[dict]:
# filter by approval and suspensions status
accounts = [a for a in accounts if \
a['approved'] is True and \
a['disabled'] is False and \
a['suspended'] is False and \
a['silenced'] is False]
return accounts
def send_dm(client:Mastodon, message:str, account:dict) -> dict:
# prepend @ to message
message = f"@{account['username']}\n" + message
response = client.status_post(message, visibility='direct')
return response
def send_to_all(client:Mastodon, message:str, accounts:List[dict], message_id:str, message_tag:str="DMAnnouncement") -> List[dict]:
"""
Send message to all, returning dictionary of account IDs and
:param message: The message to send
:param accounts: List of accounts to send to
:param message_id: Unique ID to label messages with (to be able to find this specific message later
:param message_tag: General tag to label all mass DMs with
:return:
"""
# Postpend the tags to the message
message += "\n\n" + f"#{message_tag.replace(' ', '_')} " + f"#{message_id.replace(' ', '_')}"
responses = []
for account in accounts:
try:
response = send_dm(client, message, account)
responses.append(response)
except Exception as e:
# TODO: Logging and error handling lmao
warn(f"Could not send dm to username: {account['username']}: {str(e)}")
return responses
def argparser() -> ArgumentParser:
parser = ArgumentParser()
parser.add_argument('-m', '--message', help="The Message to send", type=str)
parser.add_argument('-i', '--id', help="Unique message ID")
parser.add_argument('-t', '--tag', help="Tag for all mass DMs", type=str, default="DMAnnouncement")
return parser
def main() -> List[dict]:
args = argparser().parse_args()
client = log_in()
accounts = get_accounts(client)
accounts = filter_accounts(accounts)
responses = send_to_all(client, args.message, accounts, message_id=args.id, message_tag=args.tag)
return responses
if __name__ == "__main__":
responses = main()