Home About Me

Running Yunzai-Bot on Linux with Docker: Fixing the Missing Plugin Files

The Linux Docker setup for Yunzai-Bot is usually explained in broad strokes. The more concrete problem is in the Docker script referenced by the official docs: three JavaScript files under Gitee do not sync successfully, and the error [session-a24140b4] Repository or file not found appears. That leaves the three JS plugin files broken. The walkthrough below covers a Linux Docker installation and provides working replacements for those files.

A preconfigured archive is available at https://caiyun.139.com/m/i?135Ce8H2tpZTS with extraction code qHeX. It includes some plugins; the Gitee version lacks a few plugins. The data directory has been removed, so the later commands need to be run again.

Server and environment

Recommended: 2 CPU cores, 2 GB RAM, and 60–100 GB disk. Recommended OS: alios. Docker must be available and running.

Install Docker

Option 1: script

curl -fsSL get.docker.com -o get-docker.sh
sudo sh get-docker.sh --mirror Aliyun

Option 2: manual configuration

For CentOS / OpenAnolis / OpenCloudOS:

yum install docker-ce -y
# The following lines apply when the package cannot be detected
#yum install -y yum-utils device-mapper-persistent-data lvm2
#yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
#sed -i 's+download.docker.com+mirrors.tuna.tsinghua.edu.cn/docker-ce+' /etc/yum.repos.d/docker-ce.repo
#yum makecache
#yum install docker-ce -y

For Debian and Ubuntu:

apt update
apt upgrade -y
apt install curl vim wget gnupg dpkg apt-transport-https lsb-release ca-certificates
curl -sS https://download.docker.com/linux/debian/gpg | gpg --dearmor > /usr/share/keyrings/docker-ce.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-ce.gpg] https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/debian $(lsb_release -sc) stable" > /etc/apt/sources.list.d/docker.list
apt update
apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin

After installation, run:

status status docker//Check whether Docker exists
status start docker//Start Docker if it exists
status enable docker//Enable on boot

Use the preconfigured archive

Upload the archive (a control panel such as BT is convenient), then run:

cd /  # Recommended: install in the main directory for easy BT panel management
wget <paste the cloud drive download link here>

Unzip it:

unzip yunzai-bot.zip

Then download the container and configure it:

cd /yunzai-bot && docker-compose up -d && docker exec -it yunzai-bot node app login

If a login exception appears, check the official documentation for the corresponding fix.

Manual installation

Run the helper script:

cd / && bash <(curl -sSL http://yunzai.org/install_v3)

After the script finishes, do not start the container yet. Configure the Yunzai-Bot plugins first:

cd /yunzai-bot/yunzai
cd ./plugins/example

Large plugins can be cloned under /yunzai-bot/yunzai; JS plugins go under plugins/example.

If the three JS files report errors, copy the following contents into the corresponding JS files.

一言.js

import plugin from '../../lib/plugins/plugin.js'
import fetch from 'node-fetch'

export class example extends plugin {
  constructor () {
    super({
      /** Feature name */
      name: '一言',
      /** Feature description */
      dsc: '简单开发示例',
      /** https://oicqjs.github.io/oicq/#events */
      event: 'message',
      /** Priority, lower number = higher priority */
      priority: 5000,
      rule: [
        {
          /** Command regex match */
          reg: '^#一言$',
          /** Execution method */
          fnc: 'hitokoto'
        }
      ]
    })
  }

  /**
   * #一言
   * @param e Event parameter passed by oicq
   */
  async hitokoto (e) {
    /** User command message */
    logger.info('[用户命令]', e.msg)
    /** Hitokoto API address */
    let url = 'https://v1.hitokoto.cn/'
    /** Call API to fetch data */
    let res = await fetch(url).catch((err) => logger.error(err))
    /** Check whether API request succeeded */
    if (!res) {
      logger.error('[一言] 接口请求失败')
      return await this.reply('一言接口请求失败')
    }
    /** API result: convert JSON string to object */
    res = await res.json()
    /** Write log */
    logger.info(`[接口结果] 一言:${res.hitokoto}`)
    /** Final reply message */
    await this.reply(`一言:${res.hitokoto}`)
  }
}

主动复读.js

import plugin from '../../lib/plugins/plugin.js'

export class example2 extends plugin {
  constructor () {
    super({
      name: '复读',
      dsc: '复读用户发送的内容,然后撤回',
      /** https://oicqjs.github.io/oicq/#events */
      event: 'message',
      priority: 5000,
      rule: [
        {
          /** Command regex match */
          reg: '^#复读$',
          /** Execution method */
          fnc: 'repeat'
        }
      ]
    })
  }

  /** Repeat */
  async repeat () {
    /** Set context; subsequent received content will execute doRep */
    this.setContext('doRep')
    /** Reply */
    await this.reply('请发送要复读的内容', false, { at: true })
  }

  /** Receive content */
  doRep () {
    /** Repeat content */
    this.reply(this.e.message, false, { recallMsg: 5 })
    /** End context */
    this.finish('doRep')
  }
}

进群退群通知.js

import plugin from '../../lib/plugins/plugin.js'
import { segment } from 'oicq'

export class newcomer extends plugin {
  constructor () {
    super({
      name: '欢迎新人',
      dsc: '新人入群欢迎',
      /** https://oicqjs.github.io/oicq/#events */
      event: 'notice.group.increase',
      priority: 5000
    })
  }

  /** Executed once for every received message */
  async accept () {
    /** Define group welcome content */
    let msg = '欢迎新人!'
    /** Cooldown 30s */
    let cd = 30
    if (this.e.user_id == Bot.uin) return
    /** cd */
    let key = `Yz:newcomers:${this.e.group_id}`
    if (await redis.get(key)) return
    redis.set(key, '1', { EX: cd })
    /** Reply */
    await this.reply([
      segment.at(this.e.user_id),
      // segment.image(),
      msg
    ])
  }
}

export class outNotice extends plugin {
  constructor () {
    super({
      name: '退群通知',
      dsc: 'xx退群了',
      event: 'notice.group.decrease'
    })
    /** Leave-group prompt */
    this.tips = '退群了'
  }

  async accept () {
    if (this.e.user_id == Bot.uin) return
    let name, msg
    if (this.e.member) {
      name = this.e.member.card || this.e.member.nickname
    }
    if (name) {
      msg = `${name}(${this.e.user_id}) ${this.tips}`
    } else {
      msg = `${this.e.user_id} ${this.tips}`
    }
    logger.mark(`[退出通知]${this.e.logText} ${msg}`)
    await this.reply(msg)
  }
}

After cloning large plugins or fixing the three broken JS files, edit the Compose file:

cd /yunzai-bot && vim docker-compose.yaml

Configure docker-compose.yaml according to the plugins you have:

version: "3.9"
services:
  yunzai-bot:
    container_name: yunzai-bot
    image: swr.cn-south-1.myhuaweicloud.com/sirly/yunzai-bot:v3plus
    restart: always
    volumes:
      - ./yunzai/config:/app/Yunzai-Bot/config/config/ # Configuration files
      - ./yunzai/genshin_config:/app/Yunzai-Bot/plugins/genshin/config # Configuration files
      - ./yunzai/logs:/app/Yunzai-Bot/logs # Log files
      - ./yunzai/data:/app/Yunzai-Bot/data # Data files
      - ./yunzai/plugins/example:/app/Yunzai-Bot/plugins/example # JS plugins
      # The following directories are plugin directories; after installing a plugin, add the mapping manually
      - ./yunzai/plugins/miao-plugin:/app/Yunzai-Bot/plugins/miao-plugin # Miao plugin
      - ./yunzai/plugins/py-plugin:/app/Yunzai-Bot/plugins/py-plugin # New py plugin
      - ./yunzai/plugins/xiaoyao-cvs-plugin:/app/Yunzai-Bot/plugins/xiaoyao-cvs-plugin # Illustration plugin
      - ./yunzai/plugins/guoba-plugin:/app/Yunzai-Bot/plugins/guoba-plugin # Guoba plugin
      - ./yunzai/plugins/TRSS-Plugin:/app/Yunzai-Bot/plugins/TRSS-Plugin
      - ./yunzai/plugins/xianxin-plugin:/app/Yunzai-Bot/plugins/xianxin-plugin
      - ./yunzai/plugins/yenai-plugin:/app/Yunzai-Bot/plugins/yenai-plugin
    ports:
      - 50831:50831#Guoba plugin mapping port
    depends_on:
      redis: { condition: service_healthy }
  redis:
    container_name: yunzai-redis
    image: redis:alpine
    restart: always
    volumes:
      - ./redis/data:/data
      - ./redis/logs:/logs
    healthcheck:
      test: ["CMD", "redis-cli", "PING"]
      start_period: 10s
      interval: 5s
      timeout: 1s

Then start and log in:

cd /yunzai-bot && docker-compose up -d && docker exec -it yunzai-bot node app login

If the bot sends you a private message, the configuration is working. Every time you upload a plugin, update docker-compose.yaml and run:

cd /yunzai-bot && docker-compose up -d