discordiaでdiscordのBOTを作る際に躓いたところ

# discordiaとは

**Discordia**: Discordiaは、Lua（具体的には**Luvit**）を使用してDiscordのBOTを作成するためのライブラリです。DiscordのAPIに対するラッパーとして機能し、ユーザーがDiscordのBOTを簡単に作成できるようにします。Discordのメッセージの送受信、チャンネルの管理、ユーザーとのインタラクションなど、DiscordのBOTが必要とする機能を提供します。
[discordiaのgithub](https://github.com/SinisterRectus/Discordia)

ついでに...

**Luvit**: Luvitは、LuaとNode.jsの概念を組み合わせたプラットフォームです。Luaの軽量さと効率性、Node.jsの非同期I/Oとイベント駆動型のプログラミングの特性を組み合わせています。これにより、ウェブサーバー、リアルタイム通信アプリケーションなど、非同期I/Oを必要とするアプリケーションをLuaで効率的に開発することができます。

(以上の文章の大部分はChat-GPT4により生成されたものを採用しています。)




# discordiaの導入

## 1.luvitをインストール

https://luvit.io/install.html

(上のリンク内のサイトにも書いてありますが、ダウンロード後にパスを通しましょう。)

## 2.作業したいディレクトリでdiscordiaをインストール

```bash
lit install SinisterRectus/discordia
```

- **躓いたこと**:シェルで上記のコマンドを実行したところ、pythonのモジュールであるlitが反応し、インストールできなかった。
- **解決した方法**:`/home/user/bin`に入っている`lit`の名称を`lualit`に変更し、

```bash
lualit install SinisterRectus/discordia
```

とした。

# discordiaでBOTを作る

discordのDeveloper PotalでBOTを作成します。

https://discord.com/developers/applications


discordiaのwikiに詳しくBOTの作成方法が書いてあるため、自分のような初心者でもBOTが作成できます。
[discordiaのwiki](https://github.com/SinisterRectus/Discordia/wiki)

自分はwikiに従って以下のようなbotを作成しました。
<details><summary>コード</summary><div>

```lua
local discordia = require('discordia')
local client = discordia.Client()

client:on('ready', function()
    print('Logged in as ' .. client.user.username)
end)

local function code(str)
    return string.format('```\n%s```', str)
end

local function log(str)
    local file = io.open("luabot.log", "a") -- append mode
    if file then
        file:write("[LOG] " .. str .. "\n")
        file:close()
    end
end

local function LoadAsciiArtFromFile()
    local file = io.open("asciiart.txt", "r")
    if file then
        local asciiArt = file:read("*a")
        file:close()
        return asciiArt
    end
end

local sandbox = setmetatable({
    os = {},
    io = {},
    debug = {},
    package = {}
}, {
    __index = _G
})

local function exec(arg, msg)

    if not arg then
        return
    end
    ---if msg.author ~= msg.client.owner then return end

    arg = arg:gsub('```\n?', '') -- strip markdown codeblocks

    local lines = {} -- this is where our printed lines will collect

    sandbox.message = msg

    sandbox.print = function(...) -- intercept printed lines with this
        local ret = {}
        for i = 1, select('#', ...) do
            local arg = tostring(select(i, ...))
            table.insert(ret, arg)
        end
        local line = table.concat(ret, '\t')
        log(line) -- logging
        table.insert(lines, table.concat(ret, '\t'))
    end

    local fn, syntaxError = load(arg, 'DiscordBot', 't', sandbox)
    if not fn then
        return msg:reply(code(syntaxError))
    end

    local success, runtimeError = pcall(fn) -- run the code
    if not success then
        return msg:reply(code(runtimeError))
    end -- handle runtime errors

    lines = table.concat(lines, '\n')

    if #lines > 1990 then -- truncate long messages
        lines = lines:sub(1, 1990)
    end

    return msg:reply(code(lines))

end

client:on('messageCreate', function(message)
    if message.content == '!ping' then
        message.channel:send('Pong!')
    end
    if message.content == '!love' then
        local asciiArt = LoadAsciiArtFromFile()
        message.channel:send(asciiArt)
    end
    -- Only process messages starting with "!lua"
    if message.content:sub(1, 4) ~= '!lua' then
        return
    end

    -- Extract the code from the message
    local code = message.content:sub(5)

    -- Execute the code
    exec(code, message)
end)

client:run('Bot MyBotToken')
```
(MyBotTokenには自分のbotのトークンが入ります。)

</div></details>

このコードをluabot.luaとして保存し、

```bash
luvit luabot.lua
```

で実行しました(後にsystemctlでデーモン化した)。
BOTをDiscord Develper Portalの`OAuth2`の`URL Generator`からURLを発行し、サーバーに招待しました。
その後、discord内で権限(Permission)を付与しました。

- **躓いたところ**: discordのDMではBOTは反応するのに対し、サーバーのチャンネルでは反応しなかった。

DMで反応するところ:
![スクリーンショット (773).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3361032/4a3f0337-2dc9-ea97-e59c-ec8f8bb33db1.png)

サーバーのチャンネルで反応しないところ:
![スクリーンショット (774).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3361032/ca9c65d2-0ba2-7359-1e09-a299e5ed3b03.png)

- **解決した方法**:

Discord Developer Portalで以下の画像のように設定を変更したら、反応するようになった。
![スクリーンショット (775).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3361032/ad4013fd-c9f7-f362-8534-35d8c667b12d.png)

サーバーのチャンネルでも反応するところ:

![スクリーンショット (776).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3361032/a13b27b9-f436-4c30-3dfc-21409673c6b6.png)

# 終わりに

分からないことやご指摘がありましたら、コメントお願いします。