Makes full Domain Connect discovery of a domain and returns full url to request sync consent.

        :param domain: str
        :param provider_id: str
        :param service_id: str
        :param redirect_uri: str
        :param params: dict
        :param state: str
        :param group_ids: list(str)
        :return: (str, str)
            first field is an url which shall be used to redirect the browser to
            second field is an indication of error
        :raises: NoDomainConnectRecordException
            when no _domainconnect record found
        :raises: NoDomainConnectSettingsException
            when settings are not found
        :raises: InvalidDomainConnectSettingsException
            when settings contain missing fields

def get_domain_connect_template_sync_url(self, domain, provider_id, service_id, redirect_uri=None, params=None,
                                             state=None, group_ids=None):
        """Makes full Domain Connect discovery of a domain and returns full url to request sync consent.

        :param domain: str
        :param provider_id: str
        :param service_id: str
        :param redirect_uri: str
        :param params: dict
        :param state: str
        :param group_ids: list(str)
        :return: (str, str)
            first field is an url which shall be used to redirect the browser to
            second field is an indication of error
        :raises: NoDomainConnectRecordException
            when no _domainconnect record found
        :raises: NoDomainConnectSettingsException
            when settings are not found
        :raises: InvalidDomainConnectSettingsException
            when settings contain missing fields
        """
        # TODO: support for signatures
        # TODO: support for provider_name (for shared templates)

        if params is None:
            params = {}

        config = self.get_domain_config(domain)

        self.check_template_supported(config, provider_id, service_id)

        if config.urlSyncUX is None:
            raise InvalidDomainConnectSettingsException("No sync URL in config")

        sync_url_format = '{}/v2/domainTemplates/providers/{}/services/{}/' \
                          'apply?domain={}&host={}&{}'

        if redirect_uri is not None:
            params["redirect_uri"] = redirect_uri
        if state is not None:
            params["state"] = state
        if group_ids is not None:
            params["groupId"] = ",".join(group_ids)

        return sync_url_format.format(config.urlSyncUX, provider_id, service_id, config.domain_root, config.host,
                                      urllib.parse.urlencode(sorted(params.items(), key=lambda val: val[0])))