def send_request(destination): ret = yield self.transport_layer.make_membership_event( destination, room_id, user_id, membership, params, ) pdu_dict = ret.get("event", None) if not isinstance(pdu_dict, dict): raise InvalidResponseError("Bad 'event' field in response") logger.debug("Got response to make_%s: %s", membership, pdu_dict) pdu_dict["content"].update(content) # The protoevent received over the JSON wire may not have all # the required fields. Lets just gloss over that because # there's some we never care about if "prev_state" not in pdu_dict: pdu_dict["prev_state"] = [] ev = builder.EventBuilder(pdu_dict) defer.returnValue((destination, ev))
def make_membership_event(self, destinations, room_id, user_id, membership, content={},): """ Creates an m.room.member event, with context, without participating in the room. Does so by asking one of the already participating servers to create an event with proper context. Note that this does not append any events to any graphs. Args: destinations (str): Candidate homeservers which are probably participating in the room. room_id (str): The room in which the event will happen. user_id (str): The user whose membership is being evented. membership (str): The "membership" property of the event. Must be one of "join" or "leave". content (object): Any additional data to put into the content field of the event. Return: Deferred: resolves to a tuple of (origin (str), event (object)) where origin is the remote homeserver which generated the event. Fails with a ``CodeMessageException`` if the chosen remote server returns a 300/400 code. Fails with a ``RuntimeError`` if no servers were reachable. """ valid_memberships = {Membership.JOIN, Membership.LEAVE} if membership not in valid_memberships: raise RuntimeError( "make_membership_event called with membership='%s', must be one of %s" % (membership, ",".join(valid_memberships)) ) for destination in destinations: if destination == self.server_name: continue try: ret = yield self.transport_layer.make_membership_event( destination, room_id, user_id, membership ) pdu_dict = ret["event"] logger.debug("Got response to make_%s: %s", membership, pdu_dict) pdu_dict["content"].update(content) # The protoevent received over the JSON wire may not have all # the required fields. Lets just gloss over that because # there's some we never care about if "prev_state" not in pdu_dict: pdu_dict["prev_state"] = [] ev = builder.EventBuilder(pdu_dict) defer.returnValue( (destination, ev) ) break except CodeMessageException as e: if not 500 <= e.code < 600: raise else: logger.warn( "Failed to make_%s via %s: %s", membership, destination, e.message ) except Exception as e: logger.warn( "Failed to make_%s via %s: %s", membership, destination, e.message ) raise RuntimeError("Failed to send to any server.")