<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 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])))