> ## 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.

# GIF Comment

> Create, edit, read, and query comments that hold a GIF from your own GIF provider.

A GIF often says in one tap what a reply would take a sentence to type: a laugh, a cheer, a shrug. GIF comments let your users answer a post or another comment with a GIF that stays animated, the way they already react in other apps.

You keep the GIF experience you choose. Your app uses its own GIF provider, such as GIPHY, with that provider's search and content filters, and social.plus stores only the GIF's link and size. A GIF comment is a regular comment: it comes back in comment queries, you can filter for it by the `gif` data type, and moderators review and remove it in the social.plus Console like any other comment.

Your app picks the GIF from its provider and passes the GIF link to the SDK. The SDK sends the link and the GIF size to social.plus. The SDK does not upload the GIF and does not load it. Your app loads and shows the GIF.

> [!NOTE]
>
> GIF comments are available in the Android, iOS, and TypeScript SDKs. This page has samples for these three platforms only.

## Parameters

| Operation | Parameter | Required | Platforms | Description |
| - | - | - | - | - |
| Create a GIF comment | Reference target | Yes | Android, iOS, TypeScript | The content that gets the comment, such as a post ID. |
| Create a GIF comment | GIF attachment | Yes | Android, iOS, TypeScript | `AmityComment.Attachment.GIF` on Android. `AmityCommentAttachment.gif(url:width:height:)` on iOS. An `Amity.GifAttachment` with `type: 'gif'` on TypeScript. A comment holds one GIF. |
| Create a GIF comment | `text` | No | Android, iOS, TypeScript | Text shown with the GIF. On TypeScript, set it as `data.text`. |
| Reply with a GIF | `parentId` | Yes | Android, iOS, TypeScript | ID of the comment that gets the reply. |
| Replace or remove the GIF | `commentId` | Yes | Android, iOS, TypeScript | ID of the comment to edit. |
| Replace or remove the GIF | Attachments | No | Android, iOS, TypeScript | A new GIF replaces the GIF. An empty list removes the GIF. Leave the attachments out to keep the GIF. |
| Query GIF comments | `dataTypes` | No | Android, iOS, TypeScript | An `any` or `exact` filter that holds `gif`. |

### GIF attachment fields

| Field | Type | Required | Rule |
| - | - | - | - |
| `url` | String | Yes | An `https` link. The link path ends in `.gif`. The link has at most 2,000 characters. |
| `width` | Integer | No | The width in pixels, from 1 to 4096. Leave it out when you do not know it. |
| `height` | Integer | No | The height in pixels, from 1 to 4096. Leave it out when you do not know it. |

The GIF host must be on the network's link allowlist. See [Allowlist Management](https://learn.social.plus/analytics-and-moderation/console/moderation/roles-and-privileges.md). The SDK does not check these rules. The SDK sends the values unchanged, and social.plus refuses a GIF that breaks a rule. See [Errors](#errors).

## Create a GIF comment

Build a GIF attachment from the link that your GIF provider returns. Pass the attachment to the comment creation API. Add text when the user typed text. The returned comment has `gif` in its data types. The comment also has `text` in its data types when it has text.

To create a comment with only a GIF, leave out the text on Android. On iOS, pass an empty string as `text`. On TypeScript, leave out `data`.

```kotlin Android theme={null}
// The link that your GIF provider returns.
val gifUrl = "https://media.example.com/gifs/thumbs-up.gif"

val gif = AmityComment.Attachment.GIF(
    url = gifUrl,
    width = 480,
    height = 270,
)

AmitySocialClient.newCommentRepository()
    .createComment()
    .post(postId = postId)
    .with()
    .attachments(gif)
    .text(text = "Nice one")
    .build()
    .send()
    .subscribe(
        { comment -> showSuccessMessage(comment.getCommentId()) },
        { error -> handleGeneralError(error) }
    )
```

```swift iOS theme={null}
// The link that your GIF provider returns.
let gifURL = "https://media.example.com/gifs/thumbs-up.gif"

let options = AmityCommentCreateOptions(
    referenceId: "post-id",
    referenceType: .post,
    text: "Nice one",
    attachments: [
        .gif(url: gifURL, width: 480, height: 270)
    ]
)

let comment = try await commentRepository.createComment(with: options)
showSuccessMessage(comment.commentId)
```

```typescript TypeScript theme={null}
import { CommentRepository } from '@amityco/ts-sdk';

// The link that your GIF provider returns.
const gifUrl = 'https://media.example.com/gifs/thumbs-up.gif';

const { data: comment } = await CommentRepository.createComment({
  referenceId: postId,
  referenceType: 'post',
  data: { text: 'Nice one' },
  attachments: [{ type: 'gif', url: gifUrl, width: 480, height: 270 }],
});

renderResults(comment);
```

## Reply with a GIF

Set `parentId` to the ID of the comment that gets the reply. A reply follows the same GIF rules as a top-level comment.

```kotlin Android theme={null}
val gif = AmityComment.Attachment.GIF(
    url = "https://media.example.com/gifs/clapping.gif"
)

AmitySocialClient.newCommentRepository()
    .createComment()
    .post(postId = postId)
    .parentId(parentId = commentId)
    .with()
    .attachments(gif)
    .build()
    .send()
    .subscribe(
        { reply -> showSuccessMessage(reply.getCommentId()) },
        { error -> handleGeneralError(error) }
    )
```

```swift iOS theme={null}
let options = AmityCommentCreateOptions(
    referenceId: "post-id",
    referenceType: .post,
    text: "",
    attachments: [
        .gif(url: "https://media.example.com/gifs/clapping.gif")
    ],
    parentId: "parent-comment-id"
)

let reply = try await commentRepository.createComment(with: options)
showSuccessMessage(reply.commentId)
```

```typescript TypeScript theme={null}
import { CommentRepository } from '@amityco/ts-sdk';

const { data: reply } = await CommentRepository.createComment({
  referenceId: postId,
  referenceType: 'post',
  parentId: commentId,
  attachments: [{ type: 'gif', url: 'https://media.example.com/gifs/clapping.gif' }],
});

renderResults(reply);
```

## Read the GIF on a comment

Read the GIF from the comment attachments. The width and the height are `null` on Android, `nil` on iOS, and `undefined` on TypeScript when the comment has no size.

```kotlin Android theme={null}
fun showGif(comment: AmityComment) {
    val gif = comment.getAttachments()
        .filterIsInstance<AmityComment.Attachment.GIF>()
        .firstOrNull() ?: return

    // Your app loads the GIF from the link.
    showSuccessMessage("${gif.getUrl()} ${gif.getWidth()} x ${gif.getHeight()}")
}
```

```swift iOS theme={null}
func showGif(of comment: AmityComment) {
    for case let .gif(url, width, height) in comment.attachments {
        // Your app loads the GIF from the link.
        showSuccessMessage("\(url) \(width ?? 0) x \(height ?? 0)")
    }
}
```

```typescript TypeScript theme={null}
function showGif(comment: Amity.Comment) {
  const gif = comment.attachments?.find(
    (attachment): attachment is Amity.GifAttachment => attachment.type === 'gif',
  );
  if (!gif) return;

  // Your app loads the GIF from the link.
  renderResults({ url: gif.url, width: gif.width, height: gif.height });
}
```

A deleted GIF comment keeps `gif` in its data types. The server returns it with no attachments. Right after a delete, the local copy of the comment can still hold the GIF until the next read. Check that the comment is not deleted before you show a GIF.

## Replace or remove the GIF

Edit the comment attachments to change the GIF.

| Change | Android | iOS | TypeScript |
| - | - | - | - |
| Replace the GIF | Call `.attachments(newGif)`. | Set `attachments: [.gif(url:width:height:)]`. | Set `attachments: [{ type: 'gif', url }]`. |
| Remove the GIF and keep the text | Call `.attachments()` with no arguments. | Set `attachments: []`. | Set `attachments: []`. |
| Keep the GIF | Do not call `.attachments(...)`. | Leave `attachments` as `nil`. | Leave out `attachments`. |

The examples below replace the GIF.

```kotlin Android theme={null}
val newGif = AmityComment.Attachment.GIF(
    url = "https://media.example.com/gifs/high-five.gif",
    width = 498,
    height = 280,
)

AmitySocialClient.newCommentRepository()
    .editComment(commentId = commentId)
    .attachments(newGif)
    .build()
    .apply()
    .subscribe(
        { updatedComment -> showSuccessMessage(updatedComment.getCommentId()) },
        { error -> handleGeneralError(error) }
    )
```

```swift iOS theme={null}
let options = AmityCommentUpdateOptions(
    attachments: [
        .gif(url: "https://media.example.com/gifs/high-five.gif", width: 498, height: 280)
    ]
)

let updatedComment = try await commentRepository.editComment(
    withId: "comment-id",
    options: options
)
showSuccessMessage(updatedComment.commentId)
```

```typescript TypeScript theme={null}
import { CommentRepository } from '@amityco/ts-sdk';

const { data: updatedComment } = await CommentRepository.updateComment(commentId, {
  attachments: [
    { type: 'gif', url: 'https://media.example.com/gifs/high-five.gif', width: 498, height: 280 },
  ],
});

renderResults(updatedComment);
```

> [!NOTE]
>
> A community can require review for comment edits. See [Edit Comment](https://learn.social.plus/social-plus-sdk/social/content-management/comments/actions/edit-comment.md) for the review rules.

## Query GIF comments

Set a data type filter with `gif` to show only comments that hold a GIF.

| Filter | Comments in the result |
| - | - |
| `any` with `gif` | Every comment that has a GIF, with text or without text. |
| `exact` with `gif` | Comments that have a GIF and no text. |
| `exact` with `gif` and `text` | Comments that have a GIF and text. |

An `exact` filter matches the data types as a set. The order of the values does not matter.

```kotlin Android theme={null}
import com.amity.socialcloud.sdk.api.social.comment.query.AmityCommentDataTypeFilter
import com.amity.socialcloud.sdk.api.social.comment.query.AmityCommentSortOption

AmitySocialClient.newCommentRepository()
    .getComments()
    .post(postId = postId)
    .dataTypes(
        AmityCommentDataTypeFilter.Any(
            dataTypes = listOf(AmityComment.DataType.GIF)
        )
    )
    .sortBy(AmityCommentSortOption.LAST_CREATED)
    .includeDeleted(includeDeleted = false)
    .build()
    .query()
    .subscribe(
        { pagingData -> getPagingData(pagingData) },
        { error -> handleGeneralError(error) }
    )
```

```swift iOS theme={null}
let gifOptions = AmityCommentQueryOptions(
    referenceId: "post-id",
    referenceType: .post,
    filterByParentId: false,
    dataTypes: .any([.gif]),
    orderBy: .descending,
    includeDeleted: false
)

token = commentRepository
    .getComments(with: gifOptions)
    .observe { collection, error in
        if let error {
            handleError(error)
            return
        }

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

```typescript TypeScript theme={null}
import { CommentRepository } from '@amityco/ts-sdk';

const unsubscribe = CommentRepository.getComments(
  {
    referenceType: 'post',
    referenceId: postId,
    dataTypes: {
      values: ['gif'],
      matchType: 'any',
    },
  },
  ({ data: gifComments, error }) => {
    if (error) {
      handleError(error);
      return;
    }

    renderResults(gifComments);
  },
);
```

## Errors

The SDK returns a GIF error to your app unchanged. The SDK does not retry the request.

| HTTP status | Error code | Cause | SDK value |
| - | - | - | - |
| `403` | `400309` | The GIF host is not on the network's link allowlist. | Android: `AmityError.LINK_NOT_ALLOWED`. iOS: `AmityErrorCode.linkNotAllowed`. TypeScript: `Amity.ServerError.LINK_NOT_ALLOWED`. |
| `400` | `400000` | The GIF breaks another rule. For example, the link is not `https`, a size is out of range, the comment has two GIFs, or the comment has a GIF and an image. | Android: `AmityError.BAD_REQUEST_ERROR`. iOS: `AmityErrorCode.badRequest`. TypeScript: `Amity.ServerError.BAD_REQUEST`. |

With optimistic creation on, a refused create keeps the local comment in a failed state. Your app can offer a retry.

## Notes

* A GIF comment holds one GIF and no other attachment. To show an image, create an [Image Comment](https://learn.social.plus/social-plus-sdk/social/content-management/comments/creation/image-comment.md).
* Realtime comment events carry the GIF in the comment attachments. No GIF-specific event exists. See [Social Realtime Events](https://learn.social.plus/social-plus-sdk/core-concepts/realtime-communication/realtime-events/social-realtime-events.md).

## Related Topics

> **[Image Comment](https://learn.social.plus/social-plus-sdk/social/content-management/comments/creation/image-comment.md)**
>
> Create comments with uploaded image attachments.

> **[Query Comments](https://learn.social.plus/social-plus-sdk/social/content-management/comments/retrieval/query-comments.md)**
>
> Query top-level comments, replies, and data types.

> **[Edit Comment](https://learn.social.plus/social-plus-sdk/social/content-management/comments/actions/edit-comment.md)**
>
> Update comment text, metadata, and attachments.

> **[GIF Posts](https://learn.social.plus/social-plus-sdk/social/content-management/posts/creation/gif-post.md)**
>
> Add GIFs to posts.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.