---
title: Publisher 
description: Publish application commands as a Service 
sidebar:
  order: 1
---
Publish application commands as a service!
## Usage 

**Initializing the Publisher**
```ts 
import { makeDependencies } from '@sern/handler';
import { Publisher } from '@sern/publisher';

await makeDependencies(({ add }) => {
    add('publisher', (deps) => new Publisher(deps['@sern/modules'], deps['@sern/emitter'], deps['@sern/logger'])); 
});
```
## Implicits
- Requires process.env to be populated
- A common provider of this is `dotenv`
```txt title=".env" 
DISCORD_TOKEN=<YOUR_TOKEN>
NODE_ENV=<production|development>
```
- Calls the discord API with the [PUT route](https://discord.com/developers/docs/interactions/application-commands#bulk-overwrite-global-application-commands). Wherever your commands directory is located, publish will override the existing application commands at Discord.


## Features
- Automatically syncs api with your command base
- generates JSON file of output (**.sern/command-data-remote.json**)
- supports a configuration that is the same as the original publish plugin.


Each command file can have an extra plugin `publishConfig` that follows `ValidPublishOptions`:
## Config
```ts 

enum IntegrationContextType {
    GUILD = 0,
    BOT_DM = 1,
    PRIVATE_CHANNEL = 2
}

type Contexts = IntegrationContextType | 0 | 1 | 2;

type ValidMemberPermissions = 
    | typeof PermissionFlagsBits  //discord.js enum
    | Array<typeof PermissionFlagsBits> 
    | bigint

interface PublishConfig {
    guildIds?: Array<`${number}`>;
    defaultMemberPermissions?: ValidMemberPermissions;
    integrationTypes?: Array<'Guild'|'User'>;
    contexts?: Array<Contexts>;
}
type ValidPublishOptions = 
    | PublishConfig
    | (absPath: string, module: CommandModule) => PublishConfig
```
:::tip 
These types are exported under @sern/publisher
:::

### Example: command published with integrationTypes

:::tip
Make sure you modify the install method in the Discord dev portal
:::

```ts title=src/commands/ping.ts
import { commandModule, CommandType } from '@sern/handler'
import { publishConfig } from '@sern/publisher'

export default commandModule( {
    type: CommandType.Slash,
    plugins: [
        publishConfig({ 
            integrationTypes: ['User'],
            contexts: [1,2]
        })
    ],
    description: `hello worl`,
    execute: (ctx) => { 
        ctx.reply('pong')
    }
})

```


### Example: command published in guild

```ts title=src/commands/ping.ts
import { commandModule, CommandType } from '@sern/handler'
import { publishConfig } from '@sern/publisher'

export default commandModule( {
    type: CommandType.Slash,
    plugins: [
        publishConfig({ 
            guildIds: ["889026545715400705"]
        })
    ],
    description: `hello world`,
    execute: (ctx) => { 
        ctx.reply('pong')
    }
})

```

### Explanation of each property in the plugin

:::tip
Not everyone likes to look at Discords Docs, so here you go
:::

- `guildIds`: Commands will be published to guilds specified.
  - Can have more than one guild id to publish certain commands in
  - These commands cannot be used in dms.

- `defaultMemberPermissions`: Only members with specified permissions can view the command
  - If you specify more than one, all perms are required!

- `integrationTypes`: able to specify guild install or user install commands
  - 'Guild': Command is only able to be used in guilds
  - 'User': Command can be installed to a users profile to be used everywhere (with limitations)
    - Guilds with less than 200 members, developer can specify if the command should be invisible to others (ephemeral)
    - Guild with >= 200 members, commands will be forced to be invisible by the Discord API.

- `contexts`: specify where the user installed commands can be used.
  - 0: Only available to be used by the user in GUILDS.
  - 1: Only available in Bot dms.
  - 2: Any private channel, such as a group dm outside of bots dms.
  - Also able to use IntegrationContextType enum from `@sern/publisher` if you don't want to use numbers.
