# 10.4: Getting Message Threads/Conversations

Right now, we can send a request to our API and get the messages a user has sent and another request to retrieve the messages another user has sent to that user.

For displaying a conversation in Angular, it will help if we have a way to display the message conversation or thread between the two users. That's what we'll work on next.

## Implementing GetMessageThread() Service Method

In `MessageService`, implement the GetMessageThread() method:

```csharp
public async Task<IEnumerable<MessageToReturn>> GetMessageThread(int userId, int recipientId)
{
    var messages = await _context.Messages
                        .Include(u => u.Sender).ThenInclude(p => p.Photos)
                        .Include(u => u.Recipient).ThenInclude(p => p.Photos)
                        .Where(m => (m.RecipientId == userId &&
                                     m.SenderId == recipientId &&
                                     m.RecipientDeleted == false)
                                    ||
                                    (m.RecipientId == recipientId &&
                                     m.SenderId == userId &&
                                     m.SenderDeleted == false))
                        .Select(u => new MessageToReturn
                        {
                            Id = u.Id,
                            SenderId = u.SenderId,
                            SenderKnownAs = u.Sender.KnownAs,
                            SenderPhotoUrl = u.Sender.Photos.FirstOrDefault(p => p.IsMain).Url,
                            RecipientId = u.RecipientId,
                            RecipientKnownAs = u.Recipient.KnownAs,
                            RecipientPhotoUrl = u.Recipient.Photos.FirstOrDefault(p => p.IsMain).Url,
                            Content = u.Content,
                            IsRead = u.IsRead,
                            DateRead = u.DateRead,
                            DateSent = u.DateSent
                        })
                        .OrderByDescending(m => m.DateSent)
                        .ToListAsync();

    return messages;
}
```

We're running a single query. The only new part is the `.Where` clause. We're getting both the two Id parameters passed to the method to get all cases where the `userId` is the recipient as well as the sender and the `recipientId` is the sender and the recipient. So, basically all messages either user has sent or received from the other user.

Based on whether the userId (which represents our logged in user) is the sender or the receiver - we'll only return messages where either the recipient (our user) hasn't deleted the message or the sender (our user) hasn't deleted the message.

This is a bit tricky to explain. So, try thinking about the code line-by-line until you feel comfortable moving on.

## Add GetMessageThread() Controller Method

We'll have to add a new endpoint (`thread`) to differentiate this endpoint from the `GetMessage()` endpoint.

```csharp
[HttpGet("thread/{id}")]
public async Task<IActionResult> GetMessageThread(int userId, int id)
{
    if (userId != int.Parse(User.FindFirst(ClaimTypes.NameIdentifier).Value))
        return Unauthorized();

    var messages = await _messageService.GetMessageThread(userId, id);

    return Ok(messages);
}
```

## Testing in Postman

Before we test the method thread - make sure that you have several messages sent and received between two different users so we have more than just the single message we've been testing so far.

Next, send a `GET` request to:

`http://localhost:5000/api/users/{userId}/messages/thread/{recipientId}`

Where `userId` is the id of the user you have a token for - and the `recipientId` is the id of the other user you've sent messages to.

You should get a `200 OK` response with all messages - both sent and received - between the two users returned in the body:

![GetMessageThread](/files/-LAU8vVmitcSb6ebVZab)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://eleven-fifty-academy.gitbook.io/dotnet-302-core/10-messaging/10.4-getting-message-threads-conversations.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
