# Fetches room history in a room up to a given point in time (`limit`). # This is an example of using the messages stream. [access_token, room_id, limitStr] = System.argv {limit, _} = Integer.parse(limitStr) {:ok, client_pid} = Polyjuice.Client.start_link( "http://localhost:8008", access_token: access_token, sync: false ) client = Polyjuice.Client.get_client(client_pid) # Get a minimal sync that just contains room messages. We need to get a sync so # we have a previous batch. # FIXME: only include results from the selected room sync_filter = Polyjuice.Client.Filter.include_timeline_types(["m.room.message"]) |> Polyjuice.Client.Filter.include_state_types([]) |> Polyjuice.Client.Filter.include_presence_types([]) |> Polyjuice.Client.Filter.include_ephemeral_types([]) {:ok, initial_sync} = Polyjuice.Client.sync(client, set_presence: :offline, filter: sync_filter) timeline = initial_sync |> Map.get("rooms", %{}) |> Map.get("join", %{}) |> Map.get(room_id, %{}) |> Map.get("timeline") if timeline do prev_batch = Map.get(timeline, "prev_batch") # we will process events from latest to earliest, so reverse the events we # get from the sync events = Map.get(timeline, "events") |> Enum.reverse() if events && events != [] do # Create a stream of events. `stream_messages` gives a stream of message # batches as given by `GET /rooms/{roomid}/messages`. event_stream = if prev_batch do Polyjuice.Client.Room.stream_messages( client, room_id, prev_batch, :backward ) # Fetch the "chunk" property from each batch, which is a list of events # in that batch (from latest to earliest, since the direction is # `:backward`). |> Stream.map(&Map.get(&1, "chunk", [])) # Concatenate the events from the stream of batches to get a single # stream of events. |> Stream.concat() # Prepend the events that we got from the sync. |> (&Stream.concat(events, &1)).() else events end # Traverse the stream, and take messages until we get to one earlier than # our limit. event_stream |> Stream.take_while(&(Map.get(&1, "origin_server_ts", 0) >= limit)) # Reverse the stream so that we go from earliest to latest |> Enum.reverse() # Format the event |> Enum.each(&IO.puts("#{Map.get(&1, "sender")}> #{Map.get(&1, "content") |> Map.get("body")}")) else IO.puts("No messages") end else IO.puts("Unknown room #{room_id}") end