Commit 6e977583 authored by ozzeh's avatar ozzeh
Browse files

0.6 begin initial support for server specific groups

parent d80c904c
.DS_Store
.vscode/
.idea/
\ No newline at end of file
.idea/
env/
venv/
\ No newline at end of file
#!/bin/bash
python -m grpc_tools.protoc -I proto --python_out=./ --grpc_python_out=./ proto/grpc_madmin/*.proto
python -m grpc_tools.protoc -I proto --python_out=. --grpc_python_out=. --python_grpc_out=. proto/grpc_madmin/*.proto
# Generated by the Protocol Buffers compiler. DO NOT EDIT!
# source: grpc_madmin/generic.proto
# plugin: grpclib.plugin.main
# Generated by the Protocol Buffers compiler. DO NOT EDIT!
# source: grpc_madmin/invite.proto
# plugin: grpclib.plugin.main
import abc
import typing
import grpclib.const
import grpclib.client
if typing.TYPE_CHECKING:
import grpclib.server
import grpc_madmin.generic_pb2
import grpc_madmin.invite_pb2
class InviteServiceBase(abc.ABC):
@abc.abstractmethod
async def DoUserInvites(self, stream: 'grpclib.server.Stream[grpc_madmin.invite_pb2.UserInviteRequest, grpc_madmin.generic_pb2.GenericResponse]') -> None:
pass
def __mapping__(self) -> typing.Dict[str, grpclib.const.Handler]:
return {
'/grpc_madmin.invite.InviteService/DoUserInvites': grpclib.const.Handler(
self.DoUserInvites,
grpclib.const.Cardinality.UNARY_UNARY,
grpc_madmin.invite_pb2.UserInviteRequest,
grpc_madmin.generic_pb2.GenericResponse,
),
}
class InviteServiceStub:
def __init__(self, channel: grpclib.client.Channel) -> None:
self.DoUserInvites = grpclib.client.UnaryUnaryMethod(
channel,
'/grpc_madmin.invite.InviteService/DoUserInvites',
grpc_madmin.invite_pb2.UserInviteRequest,
grpc_madmin.generic_pb2.GenericResponse,
)
# Generated by the Protocol Buffers compiler. DO NOT EDIT!
# source: grpc_madmin/user.proto
# plugin: grpclib.plugin.main
import abc
import typing
import grpclib.const
import grpclib.client
if typing.TYPE_CHECKING:
import grpclib.server
import grpc_madmin.generic_pb2
import grpc_madmin.user_pb2
class UserServiceBase(abc.ABC):
@abc.abstractmethod
async def OnUpdateUser(self, stream: 'grpclib.server.Stream[grpc_madmin.user_pb2.UserAccessUpdated, grpc_madmin.generic_pb2.GenericResponse]') -> None:
pass
@abc.abstractmethod
async def ListSSGs(self, stream: 'grpclib.server.Stream[grpc_madmin.user_pb2.RequestSSGListing, grpc_madmin.user_pb2.ServerSpecificGroup]') -> None:
pass
def __mapping__(self) -> typing.Dict[str, grpclib.const.Handler]:
return {
'/grpc_madmin.user.UserService/OnUpdateUser': grpclib.const.Handler(
self.OnUpdateUser,
grpclib.const.Cardinality.UNARY_UNARY,
grpc_madmin.user_pb2.UserAccessUpdated,
grpc_madmin.generic_pb2.GenericResponse,
),
'/grpc_madmin.user.UserService/ListSSGs': grpclib.const.Handler(
self.ListSSGs,
grpclib.const.Cardinality.UNARY_STREAM,
grpc_madmin.user_pb2.RequestSSGListing,
grpc_madmin.user_pb2.ServerSpecificGroup,
),
}
class UserServiceStub:
def __init__(self, channel: grpclib.client.Channel) -> None:
self.OnUpdateUser = grpclib.client.UnaryUnaryMethod(
channel,
'/grpc_madmin.user.UserService/OnUpdateUser',
grpc_madmin.user_pb2.UserAccessUpdated,
grpc_madmin.generic_pb2.GenericResponse,
)
self.ListSSGs = grpclib.client.UnaryStreamMethod(
channel,
'/grpc_madmin.user.UserService/ListSSGs',
grpc_madmin.user_pb2.RequestSSGListing,
grpc_madmin.user_pb2.ServerSpecificGroup,
)
......@@ -21,7 +21,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
package='grpc_madmin.user',
syntax='proto3',
serialized_options=None,
serialized_pb=_b('\n\x16grpc_madmin/user.proto\x12\x10grpc_madmin.user\x1a\x19grpc_madmin/generic.proto\"\\\n\x11UserAccessUpdated\x12\x0f\n\x07\x61uth_id\x18\x01 \x01(\x05\x12\x10\n\x08sso_uuid\x18\x02 \x01(\t\x12\x10\n\x08username\x18\x03 \x01(\t\x12\x12\n\ndiscord_id\x18\x04 \x01(\x03\x32h\n\x0bUserService\x12Y\n\x0cOnUpdateUser\x12#.grpc_madmin.user.UserAccessUpdated\x1a$.grpc_madmin.generic.GenericResponseb\x06proto3')
serialized_pb=_b('\n\x16grpc_madmin/user.proto\x12\x10grpc_madmin.user\x1a\x19grpc_madmin/generic.proto\"\xc2\x01\n\x11UserAccessUpdated\x12\x0f\n\x07\x61uth_id\x18\x01 \x01(\x05\x12\x10\n\x08sso_uuid\x18\x02 \x01(\t\x12\x10\n\x08username\x18\x03 \x01(\t\x12\x12\n\ndiscord_id\x18\x04 \x01(\x03\x12\x1e\n\x16primary_character_name\x18\x05 \x01(\t\x12 \n\x18primary_corporation_name\x18\x06 \x01(\t\x12\"\n\x1aprimary_corporation_ticker\x18\x07 \x01(\t\"I\n\x10UserGroupRequest\x12\x0f\n\x07user_id\x18\x01 \x01(\x03\x12\x10\n\x08guild_id\x18\x02 \x01(\x03\x12\x12\n\ngroup_name\x18\x03 \x01(\t\"O\n\x13ServerSpecificGroup\x12\x10\n\x08guild_id\x18\x01 \x01(\x03\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x18\n\x10requestable_name\x18\x03 \x01(\t\"%\n\x11RequestSSGListing\x12\x10\n\x08guild_id\x18\x01 \x01(\x03\x32\xc2\x01\n\x0bUserService\x12Y\n\x0cOnUpdateUser\x12#.grpc_madmin.user.UserAccessUpdated\x1a$.grpc_madmin.generic.GenericResponse\x12X\n\x08ListSSGs\x12#.grpc_madmin.user.RequestSSGListing\x1a%.grpc_madmin.user.ServerSpecificGroup0\x01\x62\x06proto3')
,
dependencies=[grpc__madmin_dot_generic__pb2.DESCRIPTOR,])
......@@ -63,6 +63,72 @@ _USERACCESSUPDATED = _descriptor.Descriptor(
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='primary_character_name', full_name='grpc_madmin.user.UserAccessUpdated.primary_character_name', index=4,
number=5, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='primary_corporation_name', full_name='grpc_madmin.user.UserAccessUpdated.primary_corporation_name', index=5,
number=6, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='primary_corporation_ticker', full_name='grpc_madmin.user.UserAccessUpdated.primary_corporation_ticker', index=6,
number=7, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=72,
serialized_end=266,
)
_USERGROUPREQUEST = _descriptor.Descriptor(
name='UserGroupRequest',
full_name='grpc_madmin.user.UserGroupRequest',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='user_id', full_name='grpc_madmin.user.UserGroupRequest.user_id', index=0,
number=1, type=3, cpp_type=2, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='guild_id', full_name='grpc_madmin.user.UserGroupRequest.guild_id', index=1,
number=2, type=3, cpp_type=2, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='group_name', full_name='grpc_madmin.user.UserGroupRequest.group_name', index=2,
number=3, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
......@@ -75,11 +141,90 @@ _USERACCESSUPDATED = _descriptor.Descriptor(
extension_ranges=[],
oneofs=[
],
serialized_start=71,
serialized_end=163,
serialized_start=268,
serialized_end=341,
)
_SERVERSPECIFICGROUP = _descriptor.Descriptor(
name='ServerSpecificGroup',
full_name='grpc_madmin.user.ServerSpecificGroup',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='guild_id', full_name='grpc_madmin.user.ServerSpecificGroup.guild_id', index=0,
number=1, type=3, cpp_type=2, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='name', full_name='grpc_madmin.user.ServerSpecificGroup.name', index=1,
number=2, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='requestable_name', full_name='grpc_madmin.user.ServerSpecificGroup.requestable_name', index=2,
number=3, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=343,
serialized_end=422,
)
_REQUESTSSGLISTING = _descriptor.Descriptor(
name='RequestSSGListing',
full_name='grpc_madmin.user.RequestSSGListing',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='guild_id', full_name='grpc_madmin.user.RequestSSGListing.guild_id', index=0,
number=1, type=3, cpp_type=2, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=424,
serialized_end=461,
)
DESCRIPTOR.message_types_by_name['UserAccessUpdated'] = _USERACCESSUPDATED
DESCRIPTOR.message_types_by_name['UserGroupRequest'] = _USERGROUPREQUEST
DESCRIPTOR.message_types_by_name['ServerSpecificGroup'] = _SERVERSPECIFICGROUP
DESCRIPTOR.message_types_by_name['RequestSSGListing'] = _REQUESTSSGLISTING
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
UserAccessUpdated = _reflection.GeneratedProtocolMessageType('UserAccessUpdated', (_message.Message,), {
......@@ -89,6 +234,27 @@ UserAccessUpdated = _reflection.GeneratedProtocolMessageType('UserAccessUpdated'
})
_sym_db.RegisterMessage(UserAccessUpdated)
UserGroupRequest = _reflection.GeneratedProtocolMessageType('UserGroupRequest', (_message.Message,), {
'DESCRIPTOR' : _USERGROUPREQUEST,
'__module__' : 'grpc_madmin.user_pb2'
# @@protoc_insertion_point(class_scope:grpc_madmin.user.UserGroupRequest)
})
_sym_db.RegisterMessage(UserGroupRequest)
ServerSpecificGroup = _reflection.GeneratedProtocolMessageType('ServerSpecificGroup', (_message.Message,), {
'DESCRIPTOR' : _SERVERSPECIFICGROUP,
'__module__' : 'grpc_madmin.user_pb2'
# @@protoc_insertion_point(class_scope:grpc_madmin.user.ServerSpecificGroup)
})
_sym_db.RegisterMessage(ServerSpecificGroup)
RequestSSGListing = _reflection.GeneratedProtocolMessageType('RequestSSGListing', (_message.Message,), {
'DESCRIPTOR' : _REQUESTSSGLISTING,
'__module__' : 'grpc_madmin.user_pb2'
# @@protoc_insertion_point(class_scope:grpc_madmin.user.RequestSSGListing)
})
_sym_db.RegisterMessage(RequestSSGListing)
_USERSERVICE = _descriptor.ServiceDescriptor(
......@@ -97,8 +263,8 @@ _USERSERVICE = _descriptor.ServiceDescriptor(
file=DESCRIPTOR,
index=0,
serialized_options=None,
serialized_start=165,
serialized_end=269,
serialized_start=464,
serialized_end=658,
methods=[
_descriptor.MethodDescriptor(
name='OnUpdateUser',
......@@ -109,6 +275,15 @@ _USERSERVICE = _descriptor.ServiceDescriptor(
output_type=grpc__madmin_dot_generic__pb2._GENERICRESPONSE,
serialized_options=None,
),
_descriptor.MethodDescriptor(
name='ListSSGs',
full_name='grpc_madmin.user.UserService.ListSSGs',
index=1,
containing_service=None,
input_type=_REQUESTSSGLISTING,
output_type=_SERVERSPECIFICGROUP,
serialized_options=None,
),
])
_sym_db.RegisterServiceDescriptor(_USERSERVICE)
......
......@@ -20,6 +20,11 @@ class UserServiceStub(object):
request_serializer=grpc__madmin_dot_user__pb2.UserAccessUpdated.SerializeToString,
response_deserializer=grpc__madmin_dot_generic__pb2.GenericResponse.FromString,
)
self.ListSSGs = channel.unary_stream(
'/grpc_madmin.user.UserService/ListSSGs',
request_serializer=grpc__madmin_dot_user__pb2.RequestSSGListing.SerializeToString,
response_deserializer=grpc__madmin_dot_user__pb2.ServerSpecificGroup.FromString,
)
class UserServiceServicer(object):
......@@ -33,6 +38,13 @@ class UserServiceServicer(object):
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def ListSSGs(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def add_UserServiceServicer_to_server(servicer, server):
rpc_method_handlers = {
......@@ -41,6 +53,11 @@ def add_UserServiceServicer_to_server(servicer, server):
request_deserializer=grpc__madmin_dot_user__pb2.UserAccessUpdated.FromString,
response_serializer=grpc__madmin_dot_generic__pb2.GenericResponse.SerializeToString,
),
'ListSSGs': grpc.unary_stream_rpc_method_handler(
servicer.ListSSGs,
request_deserializer=grpc__madmin_dot_user__pb2.RequestSSGListing.FromString,
response_serializer=grpc__madmin_dot_user__pb2.ServerSpecificGroup.SerializeToString,
),
}
generic_handler = grpc.method_handlers_generic_handler(
'grpc_madmin.user.UserService', rpc_method_handlers)
......
# Generated by the Protocol Buffers compiler. DO NOT EDIT!
# source: grpc_madmin/utils.proto
# plugin: grpclib.plugin.main
import abc
import typing
import grpclib.const
import grpclib.client
if typing.TYPE_CHECKING:
import grpclib.server
import grpc_madmin.generic_pb2
import grpc_madmin.utils_pb2
class UtilsServiceBase(abc.ABC):
@abc.abstractmethod
async def GenerateRandomWords(self, stream: 'grpclib.server.Stream[grpc_madmin.utils_pb2.RandomWordsRequest, grpc_madmin.generic_pb2.GenericResponse]') -> None:
pass
def __mapping__(self) -> typing.Dict[str, grpclib.const.Handler]:
return {
'/grpc_madmin.utils.UtilsService/GenerateRandomWords': grpclib.const.Handler(
self.GenerateRandomWords,
grpclib.const.Cardinality.UNARY_UNARY,
grpc_madmin.utils_pb2.RandomWordsRequest,
grpc_madmin.generic_pb2.GenericResponse,
),
}
class UtilsServiceStub:
def __init__(self, channel: grpclib.client.Channel) -> None:
self.GenerateRandomWords = grpclib.client.UnaryUnaryMethod(
channel,
'/grpc_madmin.utils.UtilsService/GenerateRandomWords',
grpc_madmin.utils_pb2.RandomWordsRequest,
grpc_madmin.generic_pb2.GenericResponse,
)
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: grpc_madmin/utils.proto
import sys
_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
from grpc_madmin import generic_pb2 as grpc__madmin_dot_generic__pb2
DESCRIPTOR = _descriptor.FileDescriptor(
name='grpc_madmin/utils.proto',
package='grpc_madmin.utils',
syntax='proto3',
serialized_options=None,
serialized_pb=_b('\n\x17grpc_madmin/utils.proto\x12\x11grpc_madmin.utils\x1a\x19grpc_madmin/generic.proto\"5\n\x12RandomWordsRequest\x12\x0c\n\x04seed\x18\x01 \x01(\x03\x12\x11\n\tnum_words\x18\x02 \x01(\x05\x32r\n\x0cUtilsService\x12\x62\n\x13GenerateRandomWords\x12%.grpc_madmin.utils.RandomWordsRequest\x1a$.grpc_madmin.generic.GenericResponseb\x06proto3')
,
dependencies=[grpc__madmin_dot_generic__pb2.DESCRIPTOR,])
_RANDOMWORDSREQUEST = _descriptor.Descriptor(
name='RandomWordsRequest',
full_name='grpc_madmin.utils.RandomWordsRequest',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='seed', full_name='grpc_madmin.utils.RandomWordsRequest.seed', index=0,
number=1, type=3, cpp_type=2, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='num_words', full_name='grpc_madmin.utils.RandomWordsRequest.num_words', index=1,
number=2, type=5, cpp_type=1, label=1,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
serialized_options=None, file=DESCRIPTOR),
],
extensions=[
],
nested_types=[],
enum_types=[
],
serialized_options=None,
is_extendable=False,
syntax='proto3',
extension_ranges=[],
oneofs=[
],
serialized_start=73,
serialized_end=126,
)
DESCRIPTOR.message_types_by_name['RandomWordsRequest'] = _RANDOMWORDSREQUEST
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
RandomWordsRequest = _reflection.GeneratedProtocolMessageType('RandomWordsRequest', (_message.Message,), {
'DESCRIPTOR' : _RANDOMWORDSREQUEST,
'__module__' : 'grpc_madmin.utils_pb2'
# @@protoc_insertion_point(class_scope:grpc_madmin.utils.RandomWordsRequest)
})
_sym_db.RegisterMessage(RandomWordsRequest)
_UTILSSERVICE = _descriptor.ServiceDescriptor(
name='UtilsService',
full_name='grpc_madmin.utils.UtilsService',
file=DESCRIPTOR,
index=0,
serialized_options=None,
serialized_start=128,
serialized_end=242,
methods=[
_descriptor.MethodDescriptor(
name='GenerateRandomWords',
full_name='grpc_madmin.utils.UtilsService.GenerateRandomWords',
index=0,
containing_service=None,
input_type=_RANDOMWORDSREQUEST,
output_type=grpc__madmin_dot_generic__pb2._GENERICRESPONSE,
serialized_options=None,
),
])
_sym_db.RegisterServiceDescriptor(_UTILSSERVICE)
DESCRIPTOR.services_by_name['UtilsService'] = _UTILSSERVICE
# @@protoc_insertion_point(module_scope)
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
import grpc
from grpc_madmin import generic_pb2 as grpc__madmin_dot_generic__pb2
from grpc_madmin import utils_pb2 as grpc__madmin_dot_utils__pb2
class UtilsServiceStub(object):
# missing associated documentation comment in .proto file
pass
def __init__(self, channel):
"""Constructor.
Args:
channel: A grpc.Channel.
"""
self.GenerateRandomWords = channel.unary_unary(
'/grpc_madmin.utils.UtilsService/GenerateRandomWords',
request_serializer=grpc__madmin_dot_utils__pb2.RandomWordsRequest.SerializeToString,
response_deserializer=grpc__madmin_dot_generic__pb2.GenericResponse.FromString,
)
class UtilsServiceServicer(object):
# missing associated documentation comment in .proto file
pass
def GenerateRandomWords(self, request, context):
# missing associated documentation comment in .proto file
pass
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def add_UtilsServiceServicer_to_server(servicer, server):
rpc_method_handlers = {
'GenerateRandomWords': grpc.unary_unary_rpc_method_handler(
servicer.GenerateRandomWords,
request_deserializer=grpc__madmin_dot_utils__pb2.RandomWordsRequest.FromString,
response_serializer=grpc__madmin_dot_generic__pb2.GenericResponse.SerializeToString,
),
}
generic_handler = grpc.method_handlers_generic_handler(
'grpc_madmin.utils.UtilsService', rpc_method_handlers)
server.add_generic_rpc_handlers((generic_handler,))
......@@ -9,8 +9,28 @@ message UserAccessUpdated {
string sso_uuid = 2;
string username = 3;
int64 discord_id = 4;
string primary_character_name = 5;
string primary_corporation_name = 6;
string primary_corporation_ticker = 7;
}
message UserGroupRequest {
int64 user_id = 1;
int64 guild_id = 2;
string group_name = 3;
}
message ServerSpecificGroup {
int64 guild_id = 1;
string name = 2;
string requestable_name = 3;
}
message RequestSSGListing {
int64 guild_id = 1;
}
service UserService {