mirror of
https://github.com/zulip/zulip.git
synced 2025-10-27 18:13:58 +00:00
outgoing webhooks: Consolidate interfaces into lib/outgoing_webhook.py
This commit is contained in:
@@ -13,7 +13,8 @@ from requests import Response
|
||||
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from zerver.models import Realm, UserProfile, get_realm_by_email_domain, get_user_profile_by_id, get_client
|
||||
from zerver.models import Realm, UserProfile, get_realm_by_email_domain, get_user_profile_by_id, get_client, \
|
||||
GENERIC_INTERFACE, Service, SLACK_INTERFACE, email_to_domain, get_service_profile
|
||||
from zerver.lib.actions import check_send_message
|
||||
from zerver.lib.queue import queue_json_publish
|
||||
from zerver.lib.validator import check_dict, check_string
|
||||
@@ -64,6 +65,96 @@ class OutgoingWebhookServiceInterface(object):
|
||||
# type: (Response, Dict[Text, Any]) -> Optional[str]
|
||||
raise NotImplementedError()
|
||||
|
||||
class GenericOutgoingWebhookService(OutgoingWebhookServiceInterface):
|
||||
|
||||
def process_event(self, event):
|
||||
# type: (Dict[Text, Any]) -> Tuple[Dict[str, Any], Any]
|
||||
rest_operation = {'method': 'POST',
|
||||
'relative_url_path': '',
|
||||
'base_url': self.base_url,
|
||||
'request_kwargs': {}}
|
||||
request_data = {"data": event['command'],
|
||||
"message": event['message'],
|
||||
"token": self.token}
|
||||
return rest_operation, json.dumps(request_data)
|
||||
|
||||
def process_success(self, response, event):
|
||||
# type: (Response, Dict[Text, Any]) -> Optional[str]
|
||||
response_json = json.loads(response.text)
|
||||
|
||||
if "response_not_required" in response_json and response_json['response_not_required']:
|
||||
return None
|
||||
if "response_string" in response_json:
|
||||
return str(response_json['response_string'])
|
||||
else:
|
||||
return ""
|
||||
|
||||
def process_failure(self, response, event):
|
||||
# type: (Response, Dict[Text, Any]) -> Optional[str]
|
||||
return str(response.text)
|
||||
|
||||
class SlackOutgoingWebhookService(OutgoingWebhookServiceInterface):
|
||||
|
||||
def process_event(self, event):
|
||||
# type: (Dict[Text, Any]) -> Tuple[Dict[str, Any], Any]
|
||||
rest_operation = {'method': 'POST',
|
||||
'relative_url_path': '',
|
||||
'base_url': self.base_url,
|
||||
'request_kwargs': {}}
|
||||
|
||||
if event['message']['type'] == 'private':
|
||||
raise NotImplementedError("Private messaging service not supported.")
|
||||
|
||||
service = get_service_profile(event['user_profile_id'], str(self.service_name))
|
||||
request_data = [("token", self.token),
|
||||
("team_id", event['message']['sender_realm_str']),
|
||||
("team_domain", email_to_domain(event['message']['sender_email'])),
|
||||
("channel_id", event['message']['stream_id']),
|
||||
("channel_name", event['message']['display_recipient']),
|
||||
("timestamp", event['message']['timestamp']),
|
||||
("user_id", event['message']['sender_id']),
|
||||
("user_name", event['message']['sender_full_name']),
|
||||
("text", event['command']),
|
||||
("trigger_word", event['trigger']),
|
||||
("service_id", service.id),
|
||||
]
|
||||
|
||||
return rest_operation, request_data
|
||||
|
||||
def process_success(self, response, event):
|
||||
# type: (Response, Dict[Text, Any]) -> Optional[str]
|
||||
response_json = json.loads(response.text)
|
||||
response_text = ""
|
||||
if "text" in response_json:
|
||||
response_text = response_json["text"]
|
||||
return response_text
|
||||
|
||||
def process_failure(self, response, event):
|
||||
# type: (Response, Dict[Text, Any]) -> Optional[str]
|
||||
return str(response.text)
|
||||
|
||||
AVAILABLE_OUTGOING_WEBHOOK_INTERFACES = {
|
||||
GENERIC_INTERFACE: GenericOutgoingWebhookService,
|
||||
SLACK_INTERFACE: SlackOutgoingWebhookService,
|
||||
} # type: Dict[Text, Any]
|
||||
|
||||
def get_service_interface_class(interface):
|
||||
# type: (Text) -> Any
|
||||
if interface is None or interface not in AVAILABLE_OUTGOING_WEBHOOK_INTERFACES:
|
||||
return AVAILABLE_OUTGOING_WEBHOOK_INTERFACES[GENERIC_INTERFACE]
|
||||
else:
|
||||
return AVAILABLE_OUTGOING_WEBHOOK_INTERFACES[interface]
|
||||
|
||||
def get_outgoing_webhook_service_handler(service):
|
||||
# type: (Service) -> Any
|
||||
|
||||
service_interface_class = get_service_interface_class(service.interface_name())
|
||||
service_interface = service_interface_class(base_url=service.base_url,
|
||||
token=service.token,
|
||||
user_profile=service.user_profile,
|
||||
service_name=service.name)
|
||||
return service_interface
|
||||
|
||||
def send_response_message(bot_id, message, response_message_content):
|
||||
# type: (str, Dict[str, Any], Text) -> None
|
||||
recipient_type_name = message['type']
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
from __future__ import absolute_import
|
||||
from typing import Any, Dict, Text
|
||||
|
||||
from zerver.models import GENERIC_INTERFACE, Service, SLACK_INTERFACE
|
||||
from zerver.outgoing_webhooks.generic import GenericOutgoingWebhookService
|
||||
from zerver.outgoing_webhooks.slack import SlackOutgoingWebhookService
|
||||
|
||||
AVAILABLE_OUTGOING_WEBHOOK_INTERFACES = {
|
||||
GENERIC_INTERFACE: GenericOutgoingWebhookService,
|
||||
SLACK_INTERFACE: SlackOutgoingWebhookService,
|
||||
} # type: Dict[Text, Any]
|
||||
|
||||
def get_service_interface_class(interface):
|
||||
# type: (Text) -> Any
|
||||
if interface is None or interface not in AVAILABLE_OUTGOING_WEBHOOK_INTERFACES:
|
||||
return AVAILABLE_OUTGOING_WEBHOOK_INTERFACES[GENERIC_INTERFACE]
|
||||
else:
|
||||
return AVAILABLE_OUTGOING_WEBHOOK_INTERFACES[interface]
|
||||
|
||||
def get_outgoing_webhook_service_handler(service):
|
||||
# type: (Service) -> Any
|
||||
|
||||
service_interface_class = get_service_interface_class(service.interface_name())
|
||||
service_interface = service_interface_class(base_url=service.base_url,
|
||||
token=service.token,
|
||||
user_profile=service.user_profile,
|
||||
service_name=service.name)
|
||||
return service_interface
|
||||
@@ -1,35 +0,0 @@
|
||||
from __future__ import absolute_import
|
||||
from typing import Any, Dict, Text, Tuple, Callable, Mapping, Optional
|
||||
import json
|
||||
from requests import Response
|
||||
from zerver.models import UserProfile
|
||||
|
||||
from zerver.lib.outgoing_webhook import OutgoingWebhookServiceInterface
|
||||
|
||||
class GenericOutgoingWebhookService(OutgoingWebhookServiceInterface):
|
||||
|
||||
def process_event(self, event):
|
||||
# type: (Dict[Text, Any]) -> Tuple[Dict[str, Any], Any]
|
||||
rest_operation = {'method': 'POST',
|
||||
'relative_url_path': '',
|
||||
'base_url': self.base_url,
|
||||
'request_kwargs': {}}
|
||||
request_data = {"data": event['command'],
|
||||
"message": event['message'],
|
||||
"token": self.token}
|
||||
return rest_operation, json.dumps(request_data)
|
||||
|
||||
def process_success(self, response, event):
|
||||
# type: (Response, Dict[Text, Any]) -> Optional[str]
|
||||
response_json = json.loads(response.text)
|
||||
|
||||
if "response_not_required" in response_json and response_json['response_not_required']:
|
||||
return None
|
||||
if "response_string" in response_json:
|
||||
return str(response_json['response_string'])
|
||||
else:
|
||||
return ""
|
||||
|
||||
def process_failure(self, response, event):
|
||||
# type: (Response, Dict[Text, Any]) -> Optional[str]
|
||||
return str(response.text)
|
||||
@@ -1,47 +0,0 @@
|
||||
from __future__ import absolute_import
|
||||
from typing import Any, Dict, Text, Tuple, Callable, Mapping, Optional
|
||||
import json
|
||||
from requests import Response
|
||||
from zerver.models import UserProfile, email_to_domain, get_service_profile
|
||||
|
||||
from zerver.lib.outgoing_webhook import OutgoingWebhookServiceInterface
|
||||
|
||||
class SlackOutgoingWebhookService(OutgoingWebhookServiceInterface):
|
||||
|
||||
def process_event(self, event):
|
||||
# type: (Dict[Text, Any]) -> Tuple[Dict[str, Any], Any]
|
||||
rest_operation = {'method': 'POST',
|
||||
'relative_url_path': '',
|
||||
'base_url': self.base_url,
|
||||
'request_kwargs': {}}
|
||||
|
||||
if event['message']['type'] == 'private':
|
||||
raise NotImplementedError("Private messaging service not supported.")
|
||||
|
||||
service = get_service_profile(event['user_profile_id'], str(self.service_name))
|
||||
request_data = [("token", self.token),
|
||||
("team_id", event['message']['sender_realm_str']),
|
||||
("team_domain", email_to_domain(event['message']['sender_email'])),
|
||||
("channel_id", event['message']['stream_id']),
|
||||
("channel_name", event['message']['display_recipient']),
|
||||
("timestamp", event['message']['timestamp']),
|
||||
("user_id", event['message']['sender_id']),
|
||||
("user_name", event['message']['sender_full_name']),
|
||||
("text", event['command']),
|
||||
("trigger_word", event['trigger']),
|
||||
("service_id", service.id),
|
||||
]
|
||||
|
||||
return rest_operation, request_data
|
||||
|
||||
def process_success(self, response, event):
|
||||
# type: (Response, Dict[Text, Any]) -> Optional[str]
|
||||
response_json = json.loads(response.text)
|
||||
response_text = ""
|
||||
if "text" in response_json:
|
||||
response_text = response_json["text"]
|
||||
return response_text
|
||||
|
||||
def process_failure(self, response, event):
|
||||
# type: (Response, Dict[Text, Any]) -> Optional[str]
|
||||
return str(response.text)
|
||||
@@ -7,10 +7,10 @@ import mock
|
||||
import json
|
||||
|
||||
from requests.models import Response
|
||||
from zerver.lib.outgoing_webhook import GenericOutgoingWebhookService, \
|
||||
SlackOutgoingWebhookService
|
||||
from zerver.lib.test_classes import ZulipTestCase
|
||||
from zerver.models import Service
|
||||
from zerver.outgoing_webhooks.generic import GenericOutgoingWebhookService
|
||||
from zerver.outgoing_webhooks.slack import SlackOutgoingWebhookService
|
||||
|
||||
class Test_GenericOutgoingWebhookService(ZulipTestCase):
|
||||
|
||||
@@ -87,7 +87,7 @@ class Test_SlackOutgoingWebhookService(ZulipTestCase):
|
||||
user_profile=None,
|
||||
service_name='test-service')
|
||||
|
||||
@mock.patch('zerver.outgoing_webhooks.slack.get_service_profile', return_value=mock_service)
|
||||
@mock.patch('zerver.lib.outgoing_webhook.get_service_profile', return_value=mock_service)
|
||||
def test_process_event(self, mock_get_service_profile):
|
||||
# type: (mock.Mock) -> None
|
||||
rest_operation, request_data = self.handler.process_event(self.event)
|
||||
|
||||
@@ -38,11 +38,10 @@ from zerver.lib.db import reset_queries
|
||||
from zerver.lib.redis_utils import get_redis_client
|
||||
from zerver.lib.str_utils import force_str
|
||||
from zerver.context_processors import common_context
|
||||
from zerver.lib.outgoing_webhook import do_rest_call
|
||||
from zerver.lib.outgoing_webhook import do_rest_call, get_outgoing_webhook_service_handler
|
||||
from zerver.models import get_bot_services
|
||||
from zulip import Client
|
||||
from zerver.lib.bot_lib import EmbeddedBotHandler
|
||||
from zerver.outgoing_webhooks import get_outgoing_webhook_service_handler
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
Reference in New Issue
Block a user