質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.12%
Discord

Discordは、ゲーマー向けのボイスチャットアプリです。チャット・通話がブラウザ上で利用可能で、個人専用サーバーも開設できます。通話中でも音楽を流したり、PC画面を共有できるなど多機能な点が特徴です。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

解決済

jsonを複製した時、元のjsonに変更が加えられないようにしたい

sumwave
sumwave

総合スコア2

Discord

Discordは、ゲーマー向けのボイスチャットアプリです。チャット・通話がブラウザ上で利用可能で、個人専用サーバーも開設できます。通話中でも音楽を流したり、PC画面を共有できるなど多機能な点が特徴です。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

1回答

0リアクション

0クリップ

221閲覧

投稿2022/10/02 22:57

問題

Discord Botで音楽botを作っていて、その際に取得されているjsonをファイルに出力するとき、
いらないコードを{}に置き換えるコードを書いた結果、元のデータまで影響してしまいました。
僕が作っているbotの全体コードも置いておきます。1000行あるので見ないでもいいです。

環境

インストールしてるパッケージです。

  • Discord.js v14.5.0
  • @discordjs/voice
  • @discordjs/opus
  • libsodium-wrappers
  • ytdl-core
  • json-cyclic
  • dotenv

実現したいこと

js

let data = { voice: { text: "hoge" } }; let output = data.voice; output.text = "hogehoge"; console.log(output); console.log("データ: " + data.voice.text);

このコードの際ログには

{ text: "hogehoge" } データ: hoge

と出てほしいのですが、「データ: hoge」の部分が「データ: hogehoge」置き換わってしまいます。
これをどうにかして置き換えないようにしたいです。

テスト用のソースコード

ちょっと雑ですがお許しを...

js

import dotenv from "dotenv"; dotenv.config(); import fs from "fs"; import ytdl from "ytdl-core"; import { decycle } from "json-cyclic"; import { Client, Partials, GatewayIntentBits, EmbedBuilder } from "discord.js"; import { entersState, createAudioPlayer, createAudioResource, joinVoiceChannel, StreamType, AudioPlayerStatus } from "@discordjs/voice"; const client = new Client({ partials: [Partials.Channel], intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildVoiceStates, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent] }); let dynamic = { voice: {} }; client.on("ready", async () => { console.log("準備完了です~"); }); client.on("messageCreate", async message => { if (message.author.bot) return; if (!dynamic.voice[message.guildId]) { dynamic.voice[message.guildId] = { connection: {}, stream: {}, resource: {}, playing: null }; }; const uservoice = String(message.member.voice.channel).replace("<#", "").replace(">", ""); if (!dynamic.voice[message.guildId][uservoice] && uservoice != "null") { dynamic.voice[message.guildId][uservoice] = { repeat: 0, volumes: 50, playing: { url: "", username: "", title: "", time: "", thumbnails: "" }, playlist: [], selected: false }; }; switch (message.content.split(" ")[0]) { case "add": const url = message.content.split(" ")[1]; if (!uservoice) return message.reply(message.author.username + "さんがボイスチャットにいません...\n入ってからまたやってみてくださいね!"); if (!ytdl.validateURL(url)) return message.reply("`" + url + "`が理解できませんでした..."); const videoid = ytdl.getURLVideoID(url); let title, time, thumbnails; await ytdl.getInfo(url).then(info => { const data = info.player_response.videoDetails; title = data.title; time = data.lengthSeconds; thumbnails = data.thumbnail.thumbnails[0].url.split("?")[0]; }); dynamic.voice[message.guildId][uservoice].playlist.push({ url: videoid, username: message.author.username, title: title, time: time, thumbnails: thumbnails }); const embed = new EmbedBuilder().setTitle("状態").setDescription("再生リストを表示します。"); let list = ""; for (let i = 0; i != dynamic.voice[message.guildId][uservoice].playlist.length; i++) { list += "・" + (i + 1) + "本目"; if (i == 0) list += "(次再生されます。)"; list += "\n[**" + dynamic.voice[message.guildId][uservoice].playlist[i].title + "**](https://youtu.be/" + dynamic.voice[message.guildId][uservoice].playlist[i].url + ")" + "(" + (await timeString(dynamic.voice[message.guildId][uservoice].playlist[i].time)) + ")\n"; }; if (!dynamic.voice[message.guildId][uservoice].playlist[0]) list = "リストの内容はありません。"; embed.addFields({ name: "再生リスト", value: list }); if (dynamic.voice[message.guildId][uservoice].playlist[0]) embed.setThumbnail(dynamic.voice[message.guildId][uservoice].playlist[dynamic.voice[message.guildId][uservoice].playlist.length - 1].thumbnails); message.reply({ content: "追加ができました!", embeds: [embed] }); break; case "play": if (!uservoice) return message.reply(message.author.username + "さんがボイスチャットにいません...\n入ってからまたやってみてくださいね!"); if (dynamic.voice[message.guildId].playing == uservoice) return message.reply("既にVC再生をしています。"); if (dynamic.voice[message.guildId].playing) return message.reply("既に別のVCで再生をしています。"); if (!dynamic.voice[message.guildId][uservoice].playlist[0]) return message.reply("プレイリストが空です...`add [URL]`でプレイリストに追加してください!"); dynamic.voice[message.guildId].connection = joinVoiceChannel({ adapterCreator: message.guild.voiceAdapterCreator, channelId: uservoice, guildId: message.guildId, selfDeaf: true }); ytplay(message.guildId, uservoice); let viplay; const embed2 = new EmbedBuilder().setTitle("状態").setDescription("全ての状態を表示します。"); viplay = "```タイトル: " + dynamic.voice[message.guildId][uservoice].playing.title + "\n動画時間: " + (await timeString(dynamic.voice[message.guildId][uservoice].playing.time)) + "\nURL: https://youtu.be/" + dynamic.voice[message.guildId][uservoice].playing.url + "\n追加者: " + dynamic.voice[message.guildId][uservoice].playing.username + "```"; if (dynamic.voice[message.guildId].playing != uservoice) viplay = "現在再生されていません。"; embed2.addFields({ name: "再生中の曲の詳細", value: viplay }); let vilist = ""; for (let i = 0; i != dynamic.voice[message.guildId][uservoice].playlist.length; i++) { vilist += "・" + (i + 1) + "本目"; if (i == 0) vilist += "(次再生されます。)"; vilist += "\n[**" + dynamic.voice[message.guildId][uservoice].playlist[i].title + "**](https://youtu.be/" + dynamic.voice[message.guildId][uservoice].playlist[i].url + ")" + "(" + (await timeString(dynamic.voice[message.guildId][uservoice].playlist[i].time)) + ")\n"; }; if (!dynamic.voice[message.guildId][uservoice].playlist[0]) vilist = "リストの内容はありません。"; embed2.addFields({ name: "再生リスト", value: vilist }); embed2.setThumbnail(dynamic.voice[message.guildId][uservoice].playing.thumbnails); message.reply({ content: "曲の再生を始めます!", embeds: [embed2] }); break; case "stop": if (!uservoice) return message.reply(message.author.username + "さんがボイスチャットにいません...\n入ってからまたやってみてくださいね!"); if (dynamic.voice[message.guildId].playing != uservoice) return message.reply("現在、音楽を再生していません。後で実行してください。"); dynamic.voice[message.guildId].stream.destroy(); dynamic.voice[message.guildId].connection.destroy(); dynamic.voice[message.guildId].playing = null; message.reply({ content: "曲を止めました~" }); break; case "skip": output(outState.GetSubCommand, "skip"); if (dynamic.voice[message.guildId].playing != voiceid) return message.reply("現在、音楽を再生していません。後で実行してください。"); dynamic.voice[message.guildId].stream.destroy(); //ストリームの切断 message.reply("スキップしました!"); ytplay(message.guildId, uservoice); break; case "console": let json = dynamic; if (Object.keys(json.voice)[0]) { for (let i = 0; Object.keys(json.voice).length != i; i++) { json.voice[Object.keys(json.voice)[i]].connection = {}; json.voice[Object.keys(json.voice)[i]].stream = {}; json.voice[Object.keys(json.voice)[i]].resource = {}; }; }; fs.writeFile("dataOutput.json", JSON.stringify(decycle(json), null, "\t"), e => { if (e) throw e; }); message.reply("voiceのデータを出力しました!出力ファイルを確認しましょう!"); break; }; }); const ytplay = async (guildId, voiceid) => { if (dynamic.voice[guildId][voiceid].playlist[0]) { dynamic.voice[guildId][voiceid].playing = dynamic.voice[guildId][voiceid].playlist[0]; if (dynamic.voice[guildId][voiceid].repeat != 2) dynamic.voice[guildId][voiceid].playlist.shift(); if (dynamic.voice[guildId][voiceid].repeat == 1) dynamic.voice[guildId][voiceid].playlist.push(dynamic.voice[guildId][voiceid].playing); }; dynamic.voice[guildId].playing = voiceid; let player = createAudioPlayer(); dynamic.voice[guildId].connection.subscribe(player); dynamic.voice[guildId].stream = ytdl(dynamic.voice[guildId][voiceid].playing.url, { filter: format => format.audioCodec === 'opus' && format.container === 'webm', quality: "highest", highWaterMark: 32 * 1024 * 1024, }); dynamic.voice[guildId].resource = createAudioResource(dynamic.voice[guildId].stream, { inputType: StreamType.WebmOpus, inlineVolume: true }); dynamic.voice[guildId].resource.volume.setVolume(dynamic.voice[guildId][voiceid].volumes / 100); player.play(dynamic.voice[guildId].resource); await entersState(player, AudioPlayerStatus.Playing); await entersState(player, AudioPlayerStatus.Idle); ytplay(guildId, voiceid); }; /** * 秒のデータを文字列として置き換えます。 * @param seconds - 秒数を入力します。 * @returns - 時間、分、秒が組み合わさった文字列を出力します。 */ const timeString = async seconds => { let minutes = 0, hour = 0, timeset = ""; try { for (minutes; seconds > 59; minutes++) seconds -= 60; for (hour; minutes > 59; hour++) minutes -= 60; if (hour != 0) timeset += hour + "時間"; if (minutes != 0) timeset += minutes + "分"; if (seconds != 0) timeset += seconds + "秒"; } catch (e) { output(outState.Error, e); }; return timeset; }; client.login(process.env.token);

VCに入りadd https://youtu.be/00000000000で動画を追加し、playで再生。
再生中にconsoleと入力して再生が終わるまで待つとエラーが出ます。
consoleと入力した際、ファイルが出力されますのでご了承ください。

以下のような質問にはリアクションをつけましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

リアクションが多い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.12%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Discord

Discordは、ゲーマー向けのボイスチャットアプリです。チャット・通話がブラウザ上で利用可能で、個人専用サーバーも開設できます。通話中でも音楽を流したり、PC画面を共有できるなど多機能な点が特徴です。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。