code: def save_message(self):
          
          if self.object_id and not self.__is_draft:
              # we are only allowed to save some properties:
              allowed_changes = {self._cc('isRead'), self._cc('categories'), self._cc('flag')}  # allowed changes to be saved by this method
              changes = {tc for tc in self._track_changes if tc in allowed_changes}
  
              if not changes:
                  return True  # there's nothing to update
  
              url = self.build_url(self._endpoints.get('get_message').format(id=self.object_id))
  
              data = self.to_api_data(restrict_keys=changes)
  
              response = self.con.patch(url, data=data)
  
              if not response:
                  return False
  
              self._track_changes.clear()  # reset the tracked changes as they are all saved
              self.__modified = self.protocol.timezone.localize(dt.datetime.now())
  
              return True
          else:
              # fallback to save_draft
              return self.save_draft()
docs: 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