> ## Documentation Index
> Fetch the complete documentation index at: https://learn.social.plus/llms.txt
> Use this file to discover all available pages before exploring further.

# Story Impressions

> Mark synced stories as seen, mark story link clicks, and query reached users.

Story objects expose `impression`, `reach`, and `isSeen` state. Analytics helpers let you mark a synced story as seen and mark a story hyperlink as clicked.

<Warning>
  Call story analytics methods on synced story objects. Native and Flutter SDKs explicitly ignore unsynced stories for these analytics calls.
</Warning>

## Parameters

| Operation                  | Parameter             | Required | Description                                                       |
| -------------------------- | --------------------- | -------- | ----------------------------------------------------------------- |
| Mark story as seen         | Synced story object   | Yes      | Story object whose analytics helper records the seen event.       |
| Mark story link as clicked | Synced story object   | Yes      | Story object whose analytics helper records the link-click event. |
| Query reached users        | `viewId` / `viewedId` | Yes      | Story ID used to query reached users.                             |
| Query reached users        | `viewedType`          | Yes      | Viewed type value for stories.                                    |
| Query reached users        | `limit`               | No       | TypeScript page size for reached-user results.                    |

## Mark Story as Seen

Mark a synced story as seen after your UI decides the current user has viewed it.

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { StoryRepository } from '@amityco/ts-sdk';

  const unsubscribe = StoryRepository.getStoryByStoryId(storyId, ({ data, error }) => {
    if (error) {
      handleError(error);
      return;
    }

    data?.analytics.markAsSeen();
  });

  unsubscribe();
  ```

  ```swift iOS theme={null}
  token = storyRepository.getStory(storyId: "story-id").observe { object, error in
      if let error {
          handleError(error)
          return
      }

      object.snapshot?.analytics.markAsSeen()
  }
  ```

  ```kotlin Android theme={null}
  fun markStoryAsSeen(
      storyRepository: AmityStoryRepository,
      story: AmityStory
  ) {
      storyRepository.analytics(story).markAsSeen()
  }
  ```

  ```dart Flutter theme={null}
  void markStoryAsSeen(AmityStory story) {
    AmitySocialClient.newStoryRepository().analytics(story).markAsSeen();
  }
  ```
</CodeGroup>

## Mark Story Link as Clicked

Mark a story link as clicked when the user opens the hyperlink item from the story UI.

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { StoryRepository } from '@amityco/ts-sdk';

  const unsubscribe = StoryRepository.getStoryByStoryId(storyId, ({ data, error }) => {
    if (error) {
      handleError(error);
      return;
    }

    data?.analytics.markLinkAsClicked();
  });

  unsubscribe();
  ```

  ```swift iOS theme={null}
  token = storyRepository.getStory(storyId: "story-id").observe { object, error in
      if let error {
          handleError(error)
          return
      }

      object.snapshot?.analytics.markLinkAsClicked()
  }
  ```

  ```kotlin Android theme={null}
  fun markStoryLinkAsClicked(
      storyRepository: AmityStoryRepository,
      story: AmityStory
  ) {
      storyRepository.analytics(story).markLinkAsClicked()
  }
  ```

  ```dart Flutter theme={null}
  void markStoryLinkAsClicked(AmityStory story) {
    AmitySocialClient.newStoryRepository().analytics(story).markLinkAsClicked();
  }
  ```
</CodeGroup>

## Query Reached Users

Use reached-user APIs to retrieve users who viewed a story.

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { UserRepository } from '@amityco/ts-sdk';

  const unsubscribe = UserRepository.getReachedUsers(
    {
      viewId: storyId,
      viewedType: 'story',
      limit: 20,
    },
    ({ data, loading, error, hasNextPage, onNextPage }) => {
      if (error) {
        handleError(error);
        return;
      }

      if (!loading) {
        renderResults(data);
      }

      if (hasNextPage) {
        onNextPage?.();
      }
    },
  );

  unsubscribe();
  ```

  ```swift iOS theme={null}
  token = userRepository
      .getReachedUsers(viewedType: .story, viewedId: "story-id")
      .observe { collection, error in
          if let error {
              handleError(error)
              return
          }

          showSuccessMessage(collection.snapshots.count)
      }
  ```

  ```kotlin Android theme={null}
  fun queryStoryReachedUsers(
      userRepository: AmityUserRepository,
      storyId: String
  ) {
      userRepository.getReachedUsers(
          viewedType = AmityViewedType.STORY,
          viewedId = storyId
      )
          .doOnNext { users: PagingData<AmityUser> ->
              getPagingData(users)
          }
          .doOnError { error -> showErrorMessage(error = error) }
          .subscribe()
  }
  ```

  ```dart Flutter theme={null}
  Future<void> queryStoryReachedUsers(String storyId) async {
    final users = await AmityCoreClient.newUserRepository()
        .getViewedUsers(
          viewedType: AmityViewedType.STORY,
          viewedId: storyId,
        )
        .query();

    showError(users.length);
  }
  ```
</CodeGroup>

## Related Topics

<CardGroup cols={2}>
  <Card title="Get Stories" href="../retrieval/get-stories" icon="list">
    Retrieve stories before recording analytics events.
  </Card>

  <Card title="Create Story" href="../creation/create-story" icon="plus">
    Create stories with hyperlink items.
  </Card>
</CardGroup>
