mirror of https://github.com/zulip/zulip.git
Embedded bots: Add support for creating embedded bots via the API.
Adds support to add "Embedded bot" Service objects. This service handles every embedded bot. Extracted from "Embedded bots: Add support to add embedded bots from UI" by Robert Honig. Tweaked by tabbott to be disabled by default.
This commit is contained in:
parent
ce4ba9c178
commit
a88178afaf
|
@ -515,6 +515,7 @@ class UserProfile(ModelReprMixin, AbstractBaseUser, PermissionsMixin):
|
|||
DEFAULT_BOT,
|
||||
INCOMING_WEBHOOK_BOT,
|
||||
OUTGOING_WEBHOOK_BOT,
|
||||
EMBEDDED_BOT,
|
||||
]
|
||||
|
||||
SERVICE_BOT_TYPES = [
|
||||
|
|
|
@ -1001,3 +1001,43 @@ class BotTest(ZulipTestCase, UploadSerializeMixin):
|
|||
bot_info['interface_type'] = Service.GENERIC
|
||||
result = self.client_post("/json/bots", bot_info)
|
||||
self.assert_json_success(result)
|
||||
|
||||
def test_create_embedded_bot(self, **extras):
|
||||
# type: (**Any) -> None
|
||||
self.login(self.example_email('hamlet'))
|
||||
|
||||
# Test to create embedded bot with correct service_name
|
||||
bot_info = {
|
||||
'full_name': 'Embedded test bot',
|
||||
'short_name': 'embeddedservicebot',
|
||||
'bot_type': UserProfile.EMBEDDED_BOT,
|
||||
'service_name': 'converter',
|
||||
}
|
||||
bot_info.update(extras)
|
||||
with self.settings(EMBEDDED_BOTS_ENABLED=False):
|
||||
result = self.client_post("/json/bots", bot_info)
|
||||
self.assert_json_error(result, 'Embedded bots are not enabled.')
|
||||
|
||||
result = self.client_post("/json/bots", bot_info)
|
||||
self.assert_json_success(result)
|
||||
|
||||
bot_email = "embeddedservicebot-bot@zulip.testserver"
|
||||
bot_realm = get_realm('zulip')
|
||||
bot = get_user(bot_email, bot_realm)
|
||||
services = get_bot_services(bot.id)
|
||||
service = services[0]
|
||||
|
||||
self.assertEqual(len(services), 1)
|
||||
self.assertEqual(service.name, "converter")
|
||||
self.assertEqual(service.user_profile, bot)
|
||||
|
||||
# Test to create embedded bot with incorrect service_name
|
||||
bot_info = {
|
||||
'full_name': 'Embedded test bot',
|
||||
'short_name': 'embeddedservicebot',
|
||||
'bot_type': UserProfile.EMBEDDED_BOT,
|
||||
'service_name': 'not_existing_service',
|
||||
}
|
||||
bot_info.update(extras)
|
||||
result = self.client_post("/json/bots", bot_info)
|
||||
self.assert_json_error(result, 'Invalid embedded bot name.')
|
||||
|
|
|
@ -18,6 +18,7 @@ from zerver.lib.actions import do_change_avatar_fields, do_change_bot_owner, \
|
|||
do_change_default_events_register_stream, do_change_default_sending_stream, \
|
||||
do_create_user, do_deactivate_user, do_reactivate_user, do_regenerate_api_key
|
||||
from zerver.lib.avatar import avatar_url, get_gravatar_url, get_avatar_field
|
||||
from zerver.lib.integrations import EMBEDDED_BOTS
|
||||
from zerver.lib.response import json_error, json_success
|
||||
from zerver.lib.streams import access_stream_by_name
|
||||
from zerver.lib.upload import upload_avatar_image
|
||||
|
@ -233,6 +234,7 @@ def regenerate_bot_api_key(request, user_profile, email):
|
|||
)
|
||||
return json_success(json_result)
|
||||
|
||||
# Adds an outgoing webhook or embedded bot service.
|
||||
def add_service(name, user_profile, base_url=None, interface=None, token=None):
|
||||
# type: (Text, UserProfile, Text, int, Text) -> None
|
||||
Service.objects.create(name=name,
|
||||
|
@ -244,18 +246,26 @@ def add_service(name, user_profile, base_url=None, interface=None, token=None):
|
|||
@has_request_variables
|
||||
def add_bot_backend(request, user_profile, full_name_raw=REQ("full_name"), short_name_raw=REQ("short_name"),
|
||||
bot_type=REQ(validator=check_int, default=UserProfile.DEFAULT_BOT),
|
||||
payload_url=REQ(validator=check_url, default=None),
|
||||
payload_url=REQ(validator=check_url, default=""),
|
||||
service_name=REQ(default=None),
|
||||
interface_type=REQ(validator=check_int, default=Service.GENERIC),
|
||||
default_sending_stream_name=REQ('default_sending_stream', default=None),
|
||||
default_events_register_stream_name=REQ('default_events_register_stream', default=None),
|
||||
default_all_public_streams=REQ(validator=check_bool, default=None)):
|
||||
# type: (HttpRequest, UserProfile, Text, Text, int, Optional[Text], int, Optional[Text], Optional[Text], Optional[bool]) -> HttpResponse
|
||||
# type: (HttpRequest, UserProfile, Text, Text, int, Optional[Text], Optional[Text], int, Optional[Text], Optional[Text], Optional[bool]) -> HttpResponse
|
||||
short_name = check_short_name(short_name_raw)
|
||||
service_name = short_name
|
||||
service_name = service_name or short_name
|
||||
short_name += "-bot"
|
||||
full_name = check_full_name(full_name_raw)
|
||||
email = '%s@%s' % (short_name, user_profile.realm.get_bot_domain())
|
||||
form = CreateUserForm({'full_name': full_name, 'email': email})
|
||||
|
||||
if bot_type == UserProfile.EMBEDDED_BOT:
|
||||
if not settings.EMBEDDED_BOTS_ENABLED:
|
||||
return json_error(_("Embedded bots are not enabled."))
|
||||
if service_name not in [bot.name for bot in EMBEDDED_BOTS]:
|
||||
return json_error(_("Invalid embedded bot name."))
|
||||
|
||||
if not form.is_valid():
|
||||
# We validate client-side as well
|
||||
return json_error(_('Bad name or username'))
|
||||
|
@ -297,7 +307,7 @@ def add_bot_backend(request, user_profile, full_name_raw=REQ("full_name"), short
|
|||
user_file = list(request.FILES.values())[0]
|
||||
upload_avatar_image(user_file, user_profile, bot_profile)
|
||||
|
||||
if bot_type == UserProfile.OUTGOING_WEBHOOK_BOT:
|
||||
if bot_type in (UserProfile.OUTGOING_WEBHOOK_BOT, UserProfile.EMBEDDED_BOT):
|
||||
add_service(name=service_name,
|
||||
user_profile=bot_profile,
|
||||
base_url=payload_url,
|
||||
|
|
|
@ -34,6 +34,8 @@ EXTRA_INSTALLED_APPS = ["zilencer", "analytics"]
|
|||
CAMO_URI = ''
|
||||
OPEN_REALM_CREATION = True
|
||||
|
||||
EMBEDDED_BOTS_ENABLED = True
|
||||
|
||||
SAVE_FRONTEND_STACKTRACES = True
|
||||
EVENT_LOGS_ENABLED = True
|
||||
SYSTEM_ONLY_REALMS = set() # type: Set[str]
|
||||
|
|
|
@ -183,6 +183,7 @@ DEFAULT_SETTINGS = {
|
|||
'PUSH_NOTIFICATION_REDACT_CONTENT': False,
|
||||
'RATE_LIMITING': True,
|
||||
'SEND_LOGIN_EMAILS': True,
|
||||
'EMBEDDED_BOTS_ENABLED': False,
|
||||
}
|
||||
|
||||
# These settings are not documented in prod_settings_template.py.
|
||||
|
|
Loading…
Reference in New Issue