'Publish Topic Messaging to GCM servers
Ref: https://developers.google.com/cloud-messaging/topic-messaging
:param kwargs: dict mapping of key-value pairs of parameters
:return message_id
:raises GCMInvalidInputException: if the topic is empty'

def send_topic_message(self, **kwargs):

    if ('topic' not in kwargs):
        raise GCMInvalidInputException('Topic    name    missing!')
    elif (not kwargs['topic']):
        raise GCMInvalidInputException('Topic    name    cannot    be    empty!')
    retries = kwargs.pop('retries', 5)
    session = kwargs.pop('session', None)
    payload = self.construct_payload(**kwargs)
    backoff = self.BACKOFF_INITIAL_DELAY
    for attempt in range(retries):
        try:
            response = self.make_request(payload, is_json=True, session=session)
            return self.handle_topic_response(response)
        except (GCMUnavailableException, GCMTopicMessageException):
            if self.retry_after:
                GCM.log('[send_topic_message    -    Attempt    #{0}]    Retry-After    ~>    Sleeping    for    {1}'.format(attempt, self.retry_after))
                time.sleep(self.retry_after)
                self.retry_after = None
            else:
                sleep_time = ((backoff / 2) + random.randrange(backoff))
                nap_time = (float(sleep_time) / 1000)
                GCM.log('[send_topic_message    -    Attempt    #{0}]    Backoff    ~>    Sleeping    for    {1}'.format(attempt, nap_time))
                time.sleep(nap_time)
                if ((2 * backoff) < self.MAX_BACKOFF_DELAY):
                    backoff *= 2
    raise IOError(('Could    not    make    request    after    %d    attempts' % retries))
