diff --git a/.gitignore b/.gitignore index 861a675c9..fbc08f884 100644 --- a/.gitignore +++ b/.gitignore @@ -227,3 +227,4 @@ bootstrap-custom.min.css /WebfrontCore/wwwroot/**/dds /DiscordWebhook/env +/DiscordWebhook/config.dev.json diff --git a/DiscordWebhook/DiscordWebhook.py b/DiscordWebhook/DiscordWebhook.py index ed59e5fcb..77c5554e8 100644 --- a/DiscordWebhook/DiscordWebhook.py +++ b/DiscordWebhook/DiscordWebhook.py @@ -3,6 +3,7 @@ import time import json import collections +# the following classes model the discord webhook api parameters class WebhookAuthor(): def __init__(self, name=None, url=None, icon_url=None): if name: @@ -38,12 +39,18 @@ class WebhookParams(): self.content = '' self.embeds = [] + # quick way to convert all the objects to a nice json object def to_json(self): return json.dumps(self, default=lambda o: o.__dict__, sort_keys=True) +# gets the relative link to a user's profile def get_client_profile(profile_id): return '{}/Client/ProfileAsync/{}'.format(base_url, str(profile_id)) +def get_client_profile_markdown(client_name, profile_id): + return '[{}]({})'.format(client_name, get_client_profile(profile_id)) + +#todo: exception handling for opening the file with open('config.json') as json_config_file: json_config = json.load(json_config_file) @@ -54,7 +61,8 @@ end_point = '/api/event' request_url = base_url + end_point # this should be the full discord webhook url # ie https://discordapp.com/api/webhooks// -discord_webhook_url = json_config['DiscordWebhookUrl'] +discord_webhook_notification_url = json_config['DiscordWebhookNotificationUrl'] +discord_webhook_information_url = json_config['DiscordWebhookInformationUrl'] # this should be the numerical id of the discord group # 12345678912345678 notify_role_ids = json_config['NotifyRoleIds'] @@ -63,15 +71,25 @@ def get_new_events(): events = [] response = requests.get(request_url) data = response.json() + should_notify = False for event in data: # commonly used event info items event_type = event['eventType']['name'] server_name = event['ownerEntity']['name'] + if event['originEntity']: + origin_client_name = str(event['originEntity']['name']) + origin_client_id = int(event['originEntity']['id']) + + if event['targetEntity']: + target_client_name = str(event['targetEntity']['name']) or '' + target_client_id = int(event['targetEntity']['id']) or 0 + webhook_item = WebhookParams() webhook_item_embed = WebhookEmbed() + #todo: the following don't need to be generated every time, as it says the same webhook_item.username = 'IW4MAdmin' webhook_item.avatar_url = 'https://raidmax.org/IW4MAdmin/img/iw4adminicon-3.png' webhook_item_embed.color = 31436 @@ -79,56 +97,110 @@ def get_new_events(): webhook_item_embed.thumbnail = { 'url' : 'https://raidmax.org/IW4MAdmin/img/iw4adminicon-3.png' } webhook_item.embeds.append(webhook_item_embed) + # the server should be visible on all event types + server_field = WebhookField('Server', server_name) + webhook_item_embed.fields.append(server_field) + role_ids_string = '' for id in notify_role_ids: role_ids_string += '\r\n<@&{}>\r\n'.format(id) - - webhook_notifyrole = WebhookField('Notifies',role_ids_string) if event_type == 'Report': - origin_client_name = event['originEntity']['name'] - origin_client_id = int(event['originEntity']['id']) - - target_client_name = event['targetEntity']['name'] - target_client_id = int(event['targetEntity']['id']) - report_reason = event['extraInfo'] - server_field = WebhookField('Server', server_name) report_reason_field = WebhookField('Reason', report_reason) - reported_by_field = WebhookField('By', '[{}]({})'.format(origin_client_name, get_client_profile(origin_client_id))) - reported_field = WebhookField('Reported Player', '[{}]({})'.format(target_client_name, get_client_profile(target_client_id))) + reported_by_field = WebhookField('By', get_client_profile_markdown(origin_client_name, origin_client_id)) + reported_field = WebhookField('Reported Player',get_client_profile_markdown(target_client_name, target_client_id)) + # add each fields to the embed webhook_item_embed.title = 'Player Reported' - webhook_item_embed.fields.append(server_field) webhook_item_embed.fields.append(reported_field) webhook_item_embed.fields.append(reported_by_field) webhook_item_embed.fields.append(report_reason_field) - - #make sure there's at least one group to notify - if len(notify_role_ids) > 0: - webhook_item.content = role_ids_string + should_notify = True + + elif event_type == 'Ban': + ban_reason = event['extraInfo'] + ban_reason_field = WebhookField('Reason', ban_reason) + banned_by_field = WebhookField('By', get_client_profile_markdown(origin_client_name, origin_client_id)) + banned_field = WebhookField('Banned Player', get_client_profile_markdown(target_client_name, target_client_id)) + + # add each fields to the embed + webhook_item_embed.title = 'Player Banned' + webhook_item_embed.fields.append(banned_field) + webhook_item_embed.fields.append(banned_by_field) + webhook_item_embed.fields.append(ban_reason_field) + + should_notify = True + + elif event_type == 'Connect': + connected_field = WebhookField('Connected Player', get_client_profile_markdown(origin_client_name, origin_client_id)) + webhook_item_embed.title = 'Player Connected' + webhook_item_embed.fields.append(connected_field) + + elif event_type == 'Disconnect': + disconnected_field = WebhookField('Disconnected Player', get_client_profile_markdown(origin_client_name, origin_client_id)) + webhook_item_embed.title = 'Player Disconnected' + webhook_item_embed.fields.append(disconnected_field) + + elif event_type == 'Say': + say_client_field = WebhookField('Player', get_client_profile_markdown(origin_client_name, origin_client_id)) + message_field = WebhookField('Message', str(event['extraInfo'])) + + webhook_item_embed.title = 'Message From Player' + webhook_item_embed.fields.append(say_client_field) + webhook_item_embed.fields.append(message_field) + + #if event_type == 'ScriptKill' or event_type == 'Kill': + # kill_str = '{} killed {}'.format(get_client_profile_markdown(origin_client_name, origin_client_id), + # get_client_profile_markdown(target_client_name, target_client_id)) + # killed_field = WebhookField('Kill Information', kill_str) + # webhook_item_embed.title = 'Player Killed' + # webhook_item_embed.fields.append(killed_field) + + #todo: handle other events else: continue - events.append(webhook_item) + #make sure there's at least one group to notify + if len(notify_role_ids) > 0: + # unfortunately only the content can be used to to notify members in groups + #embed content shows the role but doesn't notify + webhook_item.content = role_ids_string + + events.append({'item' : webhook_item, 'notify' : should_notify}) return events +# sends the data to the webhook location def execute_webhook(data): for event in data: - event_json = event.to_json() - response = requests.post(discord_webhook_url, data=event_json, headers={'Content-type' : 'application/json'}) + event_json = event['item'].to_json() + url = None + if event['notify']: + url = discord_webhook_notification_url + elif len(discord_webhook_information_url) > 0: + url = discord_webhook_information_url + + if url : + response = requests.post(url, + data=event_json, + headers={'Content-type' : 'application/json'}) + +# grabs new events and executes the webhook fo each valid event def run(): + failed_count = 1 + print('starting polling for events') while True: try: new_events = get_new_events() execute_webhook(new_events) except: - print('failed to get new events') - time.sleep(2.5) + print('failed to get new events ({})'.format(failed_count)) + failed_count += 1 + time.sleep(5) if __name__ == "__main__": run() \ No newline at end of file diff --git a/DiscordWebhook/DiscordWebhook.pyproj b/DiscordWebhook/DiscordWebhook.pyproj index 0dfa2fb79..e0113872e 100644 --- a/DiscordWebhook/DiscordWebhook.pyproj +++ b/DiscordWebhook/DiscordWebhook.pyproj @@ -36,7 +36,9 @@ + +