# Managing messages

## How to create a message?

## Using REST methods

Accessing from the Client the method is create a message is pretty simple and straightforward.

```javascript
client.rest.channels.createMessage(channelID, options);
client.createMessage(channelID, options);
// e.g:
client.rest.channels.createMessage("abcd-12345", { content: "hi!" });
client.createMessage("abcd-12345", { content: "hi!" });
```

## Using the Message itself

The main differences between creating a message with the message itself rather than using REST, are that it is faster, and behaves differently: it replies to it.

### createMessage – Reply to the trigger message.

By replying to the trigger message, which is the message that triggers your application, that is most likely sent by a user: it creates an original response to it and acknowledges your message.

```typescript
Message.createMessage(options); // acknowledges and reply to the Message
```

### createFollowup

Send a follow-up message that replies to the original response, the current Message has to be acknowledged to be used.

```typescript
Message.createFollowup(options);
```

## How do I detect when a message is created, edited or deleted?

We use **client.on to detect when an event is triggered.**

### Detect when a message is created

```javascript
client.on("messageCreate", async (message) => {
    // Whatever you want to do when a message is created
}
```

### Detect when a message is edited

```javascript
client.on("messageUpdate", async (message, oldMessage) => {
    // Whatever you want to do when a message is edited
}
```

### Detect when a message is deleted

```javascript
client.on("messageUpdate", async () => {
    // Whatever you want to do when a message is deleted
}
```

{% hint style="info" %}
We're shipping TouchGuild with a wide range of events, [you can check them out here.](https://docs.touchguild.com/dev/interfaces/Events.ClientEvents)
{% endhint %}

## Create a message when someone says 'hi'

<pre class="language-javascript"><code class="lang-javascript">client.on("messageCreate", async (message) => {
    // the member property is a getter that returns a Promise
    // that's why we await it before using it.
    const member = await message.member;
    // We can get the app property and return if it is true
<strong>    // That prevents the app to send message infinitely
</strong>    // (app sends a message, it's immediately detected, so it resends and so on).
    if (member.app) return;
    // We check if the content fo the message is hi
    if (message.content == "hi") {
       // We create a message!
       message.createMessage({ content: "hey there!" });
    }
});
</code></pre>

### Another way to do that without storing the message 'member'

```javascript
client.on("messageCreate", async (message)=> {
    if (await (message.member).app) return;
    if (message.content == "hi") {
       message.createMessage({ content: "hey there!" });
    }
});
```

### Common mistakes

{% hint style="danger" %}
Not adding the condition to return in case the user that sent the message is a app

Yes, it is a fairly common mistake among beginners, by not putting this condition and send a message whatever the message is, this can cause sooner or later a creation of a bunch of messages in a short period of time.

```javascript
client.on("messageCreate", async (message)=> {
    if (message.content == "hi") {
       message.createMessage({ content: "hey there!" });
    }
    // this will loop
    message.createMessage({ content: "a message has been sent!" });
    
    // this will loop as well, as the sent message
    // is the same as the message content detected
    if (message.content == "hello") {
       message.createMessage({ content: "hello" });
    }
});
```

In this case, we're detecting if the message content is 'hi', which makes it unable to loop, but it could happen by running messageCreate outside the condition.
{% endhint %}

{% hint style="danger" %}
Using message.member directly without awaiting it

message.member is a getter method that returns a Promise, you have to await it to be able to access to its properties, in that case message.member.app will be undefined instead of a boolean.

```javascript
client.on("messageCreate", async (message)=> {
    if (message.member.app) return;
    if (message.content == "hi") {
       message.createMessage({ content: "hey there!" });
    }
});

```

OUTPUT (console):

```javascript
TypeError: Cannot read properties of undefined (reading 'app')
```

{% endhint %}

and don't forget to make the function asynchronous (async) if you're using await inside it!

## Replying to a message

The difference with creating a message and replying, is that the reply mentions the user, and links the new message to a 'replied message'

Though replying is already built-in the Message component methods, you can still&#x20;

It is very similar to creating a message, you only add the property `replyMessageIds`

```javascript
client.on("messageCreate", async (message)=> {
    const member = await message.member;
    if (member.app) return;
    if (message.content == "hi"){
       message.createMessage({
          content: "hey there!",
          // replyMessageIds is a list of message IDs you're replying to.
          // (aditionally)
          replyMessageIDs: [message.id]
       });
    }
});
```

## Logging things to a specific channel

```javascript
client.on("messageUpdate", async (message)=> {
    client.createMessage("channel id", { content: `A message has been updated (channel id: ${message.channelID})` });
});
```

## Deleting messages containing swear words

```javascript
client.on("messageCreate", (message) => {
    if (message.content.includes("fuck")) message.delete();
});
```

## Editing messages

There's different ways to edit messages sent by the app.

### 1. Storing new messages.

```javascript
client.on("messageCreate", async (message)=> {
   const member = await message.member;
   if (member.app) return;
   if (message.content == "!ping"){
       // store inside a let the message
       let reply = await message.createMessage({ content: ".." });
       // edit the stored, recently created message.
       await reply.editMessage({ content: "pong!" });
   }
});
```

### 2. Using editLast

{% hint style="info" %}
&#x20;This method called editLast was previously editLastMessage in older TouchGuild versions
{% endhint %}

```javascript
client.on("messageCreate", async (message)=> {
   const member = await message.member;
   if (member.app) return;
   if (message.content == "!ping"){
       await message.createMessage({ content: ".." });
       await message.editLastMessage({ content: "pong!" });
   }
});
```

### 2. Using editOriginal

```typescript
client.on("messageCreate", async (message) => {
   const member = await message.member;
   if (member.app) return;
   if (message.content == "!ping"){
       const res = await message.createMessage({ content: ".." });
       res.editOriginal({ content: "res edited!" });
       // it is way more useful when you only have a children of an original
       // response message
   }
});
```

### 2. Using editFollowup

A derivative of editLast, that only works on followups.


---

# 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://guide.touchguild.com/managing-messages.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.
