def save_message(self):
if self.object_id and not self.__is_draft:<EOL><INDENT>allowed_changes = {self._cc('<STR_LIT>'), self._cc('<STR_LIT>'), self._cc('<STR_LIT>')}  <EOL>changes = {tc for tc in self._track_changes if tc in allowed_changes}<EOL>if not changes:<EOL><INDENT>return True  <EOL><DEDENT>url = self.build_url(self._endpoints.get('<STR_LIT>').format(id=self.object_id))<EOL>data = self.to_api_data(restrict_keys=changes)<EOL>response = self.con.patch(url, data=data)<EOL>if not response:<EOL><INDENT>return False<EOL><DEDENT>self._track_changes.clear()  <EOL>self.__modified = self.protocol.timezone.localize(dt.datetime.now())<EOL>return True<EOL><DEDENT>else:<EOL><INDENT>return self.save_draft()<EOL><DEDENT>
Saves changes to a message.
        If the message is a new or saved draft it will call 'save_draft' otherwise
        this will save only properties of a message that are draft-independent such as:
            - is_read
            - category
            - flag
        :return: Success / Failure
        :rtype: bool