summaryrefslogblamecommitdiff
path: root/examples/history.exs
blob: 7e5c8a55ff2b7ff0d5bf560e90c469350e5a1c92 (plain) (tree)
1
2
3
4
5
6
7
8
9





                                                                       

                                                
                             



                                                



















































                                                                                                    
# 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