Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Mailgun Agent #2225

Open
wants to merge 2 commits into
base: nightly
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion data/interfaces/default/newsletter_config.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from plexpy.helpers import anon_url, checked

all_notifiers = sorted(notifiers.get_notifiers(), key=lambda k: (k['agent_label'].lower(), k['friendly_name'], k['id']))
email_notifiers = [n for n in all_notifiers if n['agent_name'] == 'email']
email_notifiers = [n for n in all_notifiers if n['agent_name'] == 'email' or n['agent_name'] == 'mailgun']
email_notifiers = [{'id': 0, 'agent_label': 'New Email Configuration', 'friendly_name': ''}] + email_notifiers
other_notifiers = [{'id': 0, 'agent_label': 'Select a Notification Agent', 'friendly_name': ''}] + all_notifiers
%>
Expand Down
168 changes: 167 additions & 1 deletion plexpy/notifiers.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@
'plexmobileapp': 26,
'lunasea': 27,
'microsoftteams': 28,
'gotify': 29
'gotify': 29,
'mailgun': 30
}

DEFAULT_CUSTOM_CONDITIONS = [{'parameter': '', 'operator': '', 'value': [], 'type': None}]
Expand Down Expand Up @@ -199,6 +200,12 @@ def available_notification_agents():
'class': LUNASEA,
'action_types': ('all',)
},
{'label': 'Mailgun',
'name': 'mailgun',
'id': AGENT_IDS['mailgun'],
'class': MAILGUN,
'action_types': ('all',)
},
{'label': 'Microsoft Teams',
'name': 'microsoftteams',
'id': AGENT_IDS['microsoftteams'],
Expand Down Expand Up @@ -2187,6 +2194,165 @@ def _return_config_options(self):
return config_option


class MAILGUN(Notifier):
"""
Mailgun email notifications
"""
NAME = 'Email'
_DEFAULT_CONFIG = {'from_name': 'Tautulli',
'from': '',
'domain': '',
'mailing_list_address': '',
'bcc_recipients': 1,
'api_key': '',
'tags': '',
'tracking': 0,
'tracking_clicks': 0,
'tracking_opens': 0,
}

def agent_notify(self, subject='', body='', action='', **kwargs):
if not self.config['api_key']:
logger.error("Tautulli Notifiers :: %s notification failed: %s",
self.NAME, "Missing API key")
return False

if not self.config['from']:
logger.error("Tautulli Notifiers :: %s notification failed: %s",
self.NAME, "Missing sender email address")
return False

if not self.config['domain']:
logger.error("Tautulli Notifiers :: %s notification failed: %s",
self.NAME, "Missing domain")
return False

if not self.config['mailing_list_address']:
logger.error("Tautulli Notifiers :: %s notification failed: %s",
self.NAME, "Missing recipient email address")
return False

# Get emails addresses from Mailgun API
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Factor out getting address into a separate method. agent_notify should only handle sending the email.

try:
r = requests.get('https://api.mailgun.net/v3/lists/{}/members'.format(self.config['mailing_list_address']),
auth=('api', self.config['api_key']),
params={'limit': 100})

if r.status_code == 200:
response_data = r.json()
if response_data.get('items'):
email_addresses = [item['address'] for item in response_data['items']]

data = {'from': '{} <{}>'.format(self.config['from_name'], self.config['from']),
'subject': subject,
'html': body}

if self.config['bcc_recipients']:
data['bcc'] = email_addresses
data['to'] = self.config['from']
else:
data['to'] = email_addresses

if self.config['tags'] and len(self.config['tags']) > 0:
data['o:tag'] = self.config['tags']

if self.config['tracking']:
data['o:tracking'] = 'yes'

if self.config['tracking_clicks']:
data['o:tracking-clicks'] = 'yes'

if self.config['tracking_opens']:
data['o:tracking-opens'] = 'yes'

r = requests.post('https://api.mailgun.net/v3/{}/messages'.format(self.config['domain']),
auth=('api', self.config['api_key']),
data=data)

if r.status_code == 200:
logger.info("Tautulli Notifiers :: {name} notification sent.".format(name=self.NAME))
return True
else:
logger.error("Tautulli Notifiers :: {name} notification failed: [{r.status_code}] {r.reason}".format(name=self.NAME, r=r))
logger.debug("Tautulli Notifiers :: Request response: {}".format(request.server_message(r, True)))
return False
else:
logger.error("Tautulli Notifiers :: Unable to retrieve {name} email addresses: {msg}".format(name=self.NAME, msg=response_data.get('message', '')))
return False
else:
logger.error("Tautulli Notifiers :: Unable to retrieve {name} email addresses: [{r.status_code}] {r.reason}".format(name=self.NAME, r=r))
logger.debug("Tautulli Notifiers :: Request response: {}".format(request.server_message(r, True)))
return False
except requests.exceptions.RequestException:
logger.error("Tautulli Notifiers :: Unable to retrieve {name} email addresses: {msg}".format(name=self.NAME, msg=e))
return False

def _return_config_options(self):
config_option = [{'label': 'From Name',
'value': self.config['from_name'],
'name': 'mailgun_from_name',
'description': 'The name of the sender.',
'input_type': 'text'
},
{'label': 'From',
'value': self.config['from'],
'name': 'mailgun_from',
'description': 'The email address of the sender.',
'input_type': 'text'
},
{'label': 'Domain',
'value': self.config['domain'],
'name': 'mailgun_domain',
'description': 'The domain to send from.',
'input_type': 'text'
},
{'label': 'Mailing List Address',
'value': self.config['mailing_list_address'],
'name': 'mailgun_mailing_list_address',
'description': 'The email address of the mailing list on Mailgun.',
'input_type': 'text'
},
{'label': 'BCC Recipients',
'value': self.config['bcc_recipients'],
'name': 'mailgun_bcc_recipients',
'description': 'Add users to Bcc instead of To.',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
'description': 'Add users to Bcc instead of To.',
'description': 'Add users to BCC instead of To.',

'input_type': 'checkbox'
},
{'label': 'API Key',
'value': self.config['api_key'],
'name': 'mailgun_api_key',
'description': 'API key for Mailgun.',
'input_type': 'password'
},
Comment on lines +2321 to +2326
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move API key up so it is the first setting.

Suggested change
{'label': 'API Key',
'value': self.config['api_key'],
'name': 'mailgun_api_key',
'description': 'API key for Mailgun.',
'input_type': 'password'
},
{'label': 'Mailgun API Key',
'value': self.config['api_key'],
'name': 'mailgun_api_key',
'description': 'Your Mailgun API key.',
'input_type': 'token'
},

{'label': 'Tags',
'value': self.config['tags'],
'name': 'mailgun_tags',
'description': 'Comma separated list of tags.',
'input_type': 'text'
},
{'label': 'Tracking',
'value': self.config['tracking'],
'name': 'mailgun_tracking',
'description': 'Enable tracking.',
'input_type': 'checkbox'
},
{'label': 'Tracking Clicks',
'value': self.config['tracking_clicks'],
'name': 'mailgun_tracking_clicks',
'description': 'Enable click tracking.',
'input_type': 'checkbox'
},
{'label': 'Tracking Opens',
'value': self.config['tracking_opens'],
'name': 'mailgun_tracking_opens',
'description': 'Enable open tracking.',
'input_type': 'checkbox'
}
]

return config_option


class LUNASEA(Notifier):
"""
LunaSea Notifications
Expand Down