# Discord Message

> Discord message with author, embeds, attachments, and mentions.

- Name: `discord-message`
- Categories: discord
- Depends on: `@open-types/discord-shared`
- Detail page: https://open-types.dev/types/discord-message

## Install

```bash
# Types only
npx shadcn add @open-types/discord-message

# Types + Zod v4 validators
npx shadcn add @open-types/discord-message-zod

# Types + real-world examples
npx shadcn add @open-types/discord-message-examples
```

## Types

```typescript
import type { DiscordUser } from "./discord-shared";

export interface DiscordEmbedField {
  name: string;
  value: string;
  inline?: boolean;
}

export interface DiscordEmbed {
  title?: string;
  description?: string;
  url?: string;
  color?: number;
  timestamp?: string;
  fields?: DiscordEmbedField[];
}

export interface DiscordAttachment {
  id: string;
  filename: string;
  size: number;
  url: string;
  content_type?: string;
}

export interface DiscordMessage {
  id: string;
  channel_id: string;
  author: DiscordUser;
  content: string;
  timestamp: string;
  edited_timestamp: string | null;
  tts: boolean;
  mention_everyone: boolean;
  mentions: DiscordUser[];
  attachments: DiscordAttachment[];
  embeds: DiscordEmbed[];
  pinned: boolean;
  type: number;
}
```

## Zod validator

```typescript
import * as z from "zod";
import type {
  DiscordEmbedField,
  DiscordEmbed,
  DiscordAttachment,
  DiscordMessage,
} from "../types/discord-message";
import { discordUserSchema } from "./discord-shared";

export const discordEmbedFieldSchema = z.object({
  name: z.string(),
  value: z.string(),
  inline: z.boolean().optional(),
}) satisfies z.ZodType<DiscordEmbedField>;

export const discordEmbedSchema = z.object({
  title: z.string().optional(),
  description: z.string().optional(),
  url: z.string().optional(),
  color: z.number().optional(),
  timestamp: z.string().optional(),
  fields: z.array(discordEmbedFieldSchema).optional(),
}) satisfies z.ZodType<DiscordEmbed>;

export const discordAttachmentSchema = z.object({
  id: z.string(),
  filename: z.string(),
  size: z.number(),
  url: z.string(),
  content_type: z.string().optional(),
}) satisfies z.ZodType<DiscordAttachment>;

export const discordMessageSchema = z.object({
  id: z.string(),
  channel_id: z.string(),
  author: discordUserSchema,
  content: z.string(),
  timestamp: z.string(),
  edited_timestamp: z.string().nullable(),
  tts: z.boolean(),
  mention_everyone: z.boolean(),
  mentions: z.array(discordUserSchema),
  attachments: z.array(discordAttachmentSchema),
  embeds: z.array(discordEmbedSchema),
  pinned: z.boolean(),
  type: z.number(),
}) satisfies z.ZodType<DiscordMessage>;

export type {
  DiscordEmbedField,
  DiscordEmbed,
  DiscordAttachment,
  DiscordMessage,
} from "../types/discord-message";
```

## Examples

```typescript
// Source: https://discord.com/developers/docs/resources/channel#message-object
// Captured: 2026-05
import type {
  DiscordEmbedField,
  DiscordEmbed,
  DiscordAttachment,
  DiscordMessage,
} from "../types/discord-message";
import {
  discordIds,
  discordUserOpenTypes,
  discordUserHuman,
} from "./shared/discord.examples";

const embedFieldEnv = {
  name: "Environment",
  value: "production",
  inline: true,
} as const satisfies DiscordEmbedField;

export const discordEmbedFieldExamples = {
  inline: embedFieldEnv,
  block: { name: "Notes", value: "Release notes attached." } satisfies DiscordEmbedField,
  longValue: {
    name: "Changelog",
    value: "- Added: foo\n- Fixed: bar\n- Removed: legacy code",
  } satisfies DiscordEmbedField,
} as const;

const embedDeploy = {
  title: "Deploy complete",
  description: "The latest release is live.",
  url: "https://open-types.dev",
  color: 5763719,
  timestamp: "2026-04-13T10:00:00.000Z",
  fields: [embedFieldEnv],
} as const satisfies DiscordEmbed;

export const discordEmbedExamples = {
  full: embedDeploy,
  empty: {} satisfies DiscordEmbed,
  titleOnly: { title: "Heads up!" } satisfies DiscordEmbed,
  multiField: {
    ...embedDeploy,
    fields: [embedFieldEnv, discordEmbedFieldExamples.block],
  } satisfies DiscordEmbed,
} as const;

const attachmentText = {
  id: "2222222222",
  filename: "release-notes.txt",
  size: 2048,
  url: "https://cdn.discordapp.com/attachments/222/release-notes.txt",
  content_type: "text/plain",
} as const satisfies DiscordAttachment;

export const discordAttachmentExamples = {
  text: attachmentText,
  image: {
    id: "2222222223",
    filename: "screenshot.png",
    size: 102400,
    url: "https://cdn.discordapp.com/attachments/222/screenshot.png",
    content_type: "image/png",
  } satisfies DiscordAttachment,
  noContentType: {
    id: "2222222224",
    filename: "data.bin",
    size: 8192,
    url: "https://cdn.discordapp.com/attachments/222/data.bin",
  } satisfies DiscordAttachment,
} as const;

const message = {
  id: discordIds.messageId,
  channel_id: discordIds.channel,
  author: discordUserOpenTypes,
  content: "Deployment finished successfully.",
  timestamp: "2026-04-13T10:00:00.000Z",
  edited_timestamp: null,
  tts: false,
  mention_everyone: false,
  mentions: [discordUserOpenTypes],
  attachments: [attachmentText],
  embeds: [embedDeploy],
  pinned: false,
  type: 0,
} as const satisfies DiscordMessage;

export const discordMessageExamples = {
  rich: message,
  plain: {
    ...message,
    id: "3333333334",
    content: "hello",
    mentions: [],
    attachments: [],
    embeds: [],
  } satisfies DiscordMessage,
  edited: {
    ...message,
    id: "3333333335",
    edited_timestamp: "2026-04-13T10:05:00.000Z",
  } satisfies DiscordMessage,
  fromHuman: {
    ...message,
    id: "3333333336",
    author: discordUserHuman,
    content: "I deployed it manually",
    mentions: [],
    attachments: [],
    embeds: [],
  } satisfies DiscordMessage,
  pinned: { ...message, id: "3333333337", pinned: true } satisfies DiscordMessage,
} as const;
```
