diff --git a/data/interfaces/default/notifier_config.html b/data/interfaces/default/notifier_config.html
index fedf5337..e96c3220 100644
--- a/data/interfaces/default/notifier_config.html
+++ b/data/interfaces/default/notifier_config.html
@@ -580,6 +580,18 @@
});
var join_device_names = $join_device_names[0].selectize;
join_device_names.setValue(${json.dumps(next((c['value'] for c in notifier['config_options'] if c['name'] == 'join_device_names'), [])) | n});
+
+ % elif notifier['agent_name'] == 'zapier':
+ $('#zapier_test_hook').click(function () {
+ $.get('zapier_test_hook', { 'zapier_hook': $('#zapier_hook').val() }, function (data) {
+ if (data.result === 'success') {
+ showMsg(' ' + data.msg, false, true, 5000);
+ } else {
+ showMsg(' ' + data.msg, false, true, 5000, true);
+ }
+ });
+ });
+
% endif
function validateLogic() {
diff --git a/plexpy/notifiers.py b/plexpy/notifiers.py
index 3cbf5540..69137af3 100644
--- a/plexpy/notifiers.py
+++ b/plexpy/notifiers.py
@@ -90,7 +90,8 @@ AGENT_IDS = {'growl': 0,
'discord': 20,
'androidapp': 21,
'groupme': 22,
- 'mqtt': 23
+ 'mqtt': 23,
+ 'zapier': 24
}
@@ -186,6 +187,10 @@ def available_notification_agents():
{'label': 'XBMC',
'name': 'xbmc',
'id': AGENT_IDS['xbmc']
+ },
+ {'label': 'Zapier',
+ 'name': 'zapier',
+ 'id': AGENT_IDS['zapier']
}
]
@@ -377,6 +382,8 @@ def get_agent_class(agent_id=None, config=None):
return GROUPME(config=config)
elif agent_id == 23:
return MQTT(config=config)
+ elif agent_id == 24:
+ return ZAPIER(config=config)
else:
return Notifier(config=config)
else:
@@ -652,13 +659,28 @@ class PrettyMetadata(object):
provider_name = 'Trakt.tv'
elif provider == 'lastfm':
provider_name = 'Last.fm'
+ else:
+ if self.media_type == 'movie':
+ provider_name = 'IMDb'
+ elif self.media_type in ('show', 'season', 'episode'):
+ provider_name = 'TheTVDB'
+ elif self.media_type in ('artist', 'album', 'track'):
+ provider_name = 'Last.fm'
return provider_name
def get_provider_link(self, provider=None):
+ provider_link = ''
if provider == 'plexweb':
provider_link = self.get_plex_url()
- else:
+ elif provider:
provider_link = self.parameters.get(provider + '_url', '')
+ else:
+ if self.media_type == 'movie':
+ provider_link = self.parameters.get('imdb_url', '')
+ elif self.media_type in ('show', 'season', 'episode'):
+ provider_link = self.parameters.get('thetvdb_url', '')
+ elif self.media_type in ('artist', 'album', 'track'):
+ provider_link = self.parameters.get('lastfm_url', '')
return provider_link
def get_caption(self, provider):
@@ -1919,23 +1941,24 @@ class IFTTT(Notifier):
headers=headers, json=data)
def return_config_options(self):
- config_option = [{'label': 'Ifttt Maker Channel Key',
+ config_option = [{'label': 'IFTTT Webhook Key',
'value': self.config['key'],
'name': 'ifttt_key',
- 'description': 'Your Ifttt key. You can get a key from'
- ' here.',
+ 'description': 'Your IFTTT webhook key. You can get a key from'
+ ' here.',
'input_type': 'text'
},
- {'label': 'Ifttt Event',
+ {'label': 'IFTTT Event',
'value': self.config['event'],
'name': 'ifttt_event',
- 'description': 'The Ifttt maker event to fire. You can include'
- ' the {action} to be substituted with the action name.'
+ 'description': 'The IFTTT maker event to fire. You can include'
+ ' {action}'
+ ' to be substituted with the action name.'
' The notification subject and body will be sent'
- ' as value1 and value2 respectively.',
+ ' as value1'
+ ' and value2 respectively.',
'input_type': 'text'
}
-
]
return config_option
@@ -2072,7 +2095,7 @@ class JOIN(Notifier):
{'label': 'Movie Link Source',
'value': self.config['movie_provider'],
'name': 'join_movie_provider',
- 'description': 'Select the source for movie links on the info cards. Leave blank for default.
'
+ 'description': 'Select the source for movie links in the notificaation. Leave blank for default.
'
'3rd party API lookup may need to be enabled under the notifications settings tab.',
'input_type': 'select',
'select_options': PrettyMetadata().get_movie_providers()
@@ -2080,7 +2103,7 @@ class JOIN(Notifier):
{'label': 'TV Show Link Source',
'value': self.config['tv_provider'],
'name': 'join_tv_provider',
- 'description': 'Select the source for tv show links on the info cards. Leave blank for default.
'
+ 'description': 'Select the source for tv show links in the notificaation. Leave blank for default.
'
'3rd party API lookup may need to be enabled under the notifications settings tab.',
'input_type': 'select',
'select_options': PrettyMetadata().get_tv_providers()
@@ -2088,7 +2111,7 @@ class JOIN(Notifier):
{'label': 'Music Link Source',
'value': self.config['music_provider'],
'name': 'join_music_provider',
- 'description': 'Select the source for music links on the info cards. Leave blank for default.',
+ 'description': 'Select the source for music links in the notificaation. Leave blank for default.',
'input_type': 'select',
'select_options': PrettyMetadata().get_music_providers()
}
@@ -2714,7 +2737,7 @@ class PUSHOVER(Notifier):
{'label': 'Movie Link Source',
'value': self.config['movie_provider'],
'name': 'pushover_movie_provider',
- 'description': 'Select the source for movie links on the info cards. Leave blank for default.
'
+ 'description': 'Select the source for movie links in the notification. Leave blank for default.
'
'3rd party API lookup may need to be enabled under the notifications settings tab.',
'input_type': 'select',
'select_options': PrettyMetadata().get_movie_providers()
@@ -2722,7 +2745,7 @@ class PUSHOVER(Notifier):
{'label': 'TV Show Link Source',
'value': self.config['tv_provider'],
'name': 'pushover_tv_provider',
- 'description': 'Select the source for tv show links on the info cards. Leave blank for default.
'
+ 'description': 'Select the source for tv show links in the notification. Leave blank for default.
'
'3rd party API lookup may need to be enabled under the notifications settings tab.',
'input_type': 'select',
'select_options': PrettyMetadata().get_tv_providers()
@@ -2730,7 +2753,7 @@ class PUSHOVER(Notifier):
{'label': 'Music Link Source',
'value': self.config['music_provider'],
'name': 'pushover_music_provider',
- 'description': 'Select the source for music links on the info cards. Leave blank for default.',
+ 'description': 'Select the source for music links in the notification. Leave blank for default.',
'input_type': 'select',
'select_options': PrettyMetadata().get_music_providers()
}
@@ -3403,6 +3426,104 @@ class XBMC(Notifier):
return config_option
+class ZAPIER(Notifier):
+ """
+ Zapier notifications
+ """
+ NAME = 'Zapier'
+ _DEFAULT_CONFIG = {'hook': '',
+ 'movie_provider': '',
+ 'tv_provider': '',
+ 'music_provider': ''
+ }
+
+ def _test_hook(self):
+ _test_data = {'subject': 'Subject',
+ 'body': 'Body',
+ 'action': 'Action',
+ 'poster_url': 'https://i.imgur.com',
+ 'provider_name': 'Provider Name',
+ 'provider_link': 'http://www.imdb.com',
+ 'plex_url': 'https://app.plex.tv/desktop'}
+
+ return self.agent_notify(_test_data=_test_data)
+
+ def agent_notify(self, subject='', body='', action='', **kwargs):
+ data = {'subject': subject.encode("utf-8"),
+ 'body': body.encode("utf-8"),
+ 'action': action.encode("utf-8")}
+
+ if kwargs.get('parameters', {}).get('media_type'):
+ # Grab formatted metadata
+ pretty_metadata = PrettyMetadata(kwargs['parameters'])
+
+ if pretty_metadata.media_type == 'movie':
+ provider = self.config['movie_provider']
+ elif pretty_metadata.media_type in ('show', 'season', 'episode'):
+ provider = self.config['tv_provider']
+ elif pretty_metadata.media_type in ('artist', 'album', 'track'):
+ provider = self.config['music_provider']
+ else:
+ provider = None
+
+ poster_url = pretty_metadata.get_poster_url()
+ provider_name = pretty_metadata.get_provider_name(provider)
+ provider_link = pretty_metadata.get_provider_link(provider)
+ plex_url = pretty_metadata.get_plex_url()
+
+ data['poster_url'] = poster_url
+ data['provider_name'] = provider_name
+ data['provider_link'] = provider_link
+ data['plex_url'] = plex_url
+
+ if kwargs.get('_test_data'):
+ data.update(kwargs['_test_data'])
+
+ headers = {'Content-type': 'application/json'}
+
+ return self.make_request(self.config['hook'], headers=headers, json=data)
+
+ def return_config_options(self):
+ config_option = [{'label': 'Zapier Webhook URL',
+ 'value': self.config['hook'],
+ 'name': 'zapier_hook',
+ 'description': 'Your Zapier webhook URL.',
+ 'input_type': 'text'
+ },
+ {'label': 'Test Zapier Webhook',
+ 'value': 'Send Test Data',
+ 'name': 'zapier_test_hook',
+ 'description': 'Click this button when prompted on then "Test Webhooks by Zapier" step.',
+ 'input_type': 'button'
+ },
+ {'label': 'Movie Link Source',
+ 'value': self.config['movie_provider'],
+ 'name': 'zapier_movie_provider',
+ 'description': 'Select the source for movie links in the notification. Leave blank for default.
'
+ '3rd party API lookup may need to be enabled under the notifications settings tab.',
+ 'input_type': 'select',
+ 'select_options': PrettyMetadata().get_movie_providers()
+ },
+ {'label': 'TV Show Link Source',
+ 'value': self.config['tv_provider'],
+ 'name': 'zapier_tv_provider',
+ 'description': 'Select the source for tv show links in the notification. Leave blank for default.
'
+ '3rd party API lookup may need to be enabled under the notifications settings tab.',
+ 'input_type': 'select',
+ 'select_options': PrettyMetadata().get_tv_providers()
+ },
+ {'label': 'Music Link Source',
+ 'value': self.config['music_provider'],
+ 'name': 'zapier_music_provider',
+ 'description': 'Select the source for music links in the notification. Leave blank for default.',
+ 'input_type': 'select',
+ 'select_options': PrettyMetadata().get_music_providers()
+ }
+ ]
+
+ return config_option
+
+
def upgrade_config_to_db():
logger.info(u"Tautulli Notifiers :: Upgrading to new notification system...")
diff --git a/plexpy/webserve.py b/plexpy/webserve.py
index c55804c7..7a186563 100644
--- a/plexpy/webserve.py
+++ b/plexpy/webserve.py
@@ -3200,6 +3200,16 @@ class WebInterface(object):
logger.warn(msg)
return msg
+ @cherrypy.expose
+ @cherrypy.tools.json_out()
+ @requireAuth(member_of("admin"))
+ def zapier_test_hook(self, zapier_hook='', **kwargs):
+ success = notifiers.ZAPIER(config={'hook': zapier_hook})._test_hook()
+ if success:
+ return {'result': 'success', 'msg': 'Test Zapier webhook sent.'}
+ else:
+ return {'result': 'error', 'msg': 'Failed to send test Zapier webhook.'}
+
@cherrypy.expose
@requireAuth(member_of("admin"))
def set_notification_config(self, **kwargs):