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

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

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

Electronは、HTML5とNode.jsというWebの技術を用いてデスクトップアプリケーションを作成できるクロスプラットフォームな実行環境です。

Discord

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

Node.js

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

ImageMagick

ImageMagickとは、画像の表示や操作を行うオープンソースのソフトウェアです。プログラムはCで書かれており、GIFやJPEG、PDFなど画像ファイルフォーマット100種類以上に対応しています。

Q&A

解決済

2回答

1816閲覧

discord.jsとchild_process(imagemagick - importコマンド)を使って画像を送信したい

Zel

総合スコア11

Electron

Electronは、HTML5とNode.jsというWebの技術を用いてデスクトップアプリケーションを作成できるクロスプラットフォームな実行環境です。

Discord

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

Node.js

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

ImageMagick

ImageMagickとは、画像の表示や操作を行うオープンソースのソフトウェアです。プログラムはCで書かれており、GIFやJPEG、PDFなど画像ファイルフォーマット100種類以上に対応しています。

0グッド

0クリップ

投稿2020/04/18 10:26

前提・実現したいこと

ImageMagick(import, base64)を使用してelectronのウインドウを取得して画像をdiscordに送信しようとしています。

発生している問題・エラーメッセージ

Bufferに変換してますが、このようなエラーになります。

/home/.../Documents/…DataResolver.js:109 Uncaught (in promise) TypeError [REQ_RESOURCE_TYPE]: The resource must be a string, Buffer or a valid file stream.

該当のソースコード

js

1require("child_process").exec(`import -window "${document.title}" PNG:- | base64`, (err, stdout, stderr) => { 2 var image = `data:image/png;base64,${stdout.replace(/\n/g, "")}`; 3 var toBuffer = new Buffer(image, "base64"); 4 client.channels.cache.get("chid").send({files: [{attachment: toBuffer}]}); 5});

試したこと

imageをattachmentに入れたりBufferをBuffer.fromに変えたりしました

補足情報(FW/ツールのバージョンなど)

electron - 8.2.1
discord.js - 12.x
nodejs - 12.x or 13.x
ubuntu - 19.10
ImageMagick(import and base64)

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

完結に言うとdiscord.jsはelectronのレンダラープロセスのような環境(※)での実行を想定して作られていないため、通常のNode.jsと同じであるメインプロセス側で実行するのが良いです

ただしメインプロセスからは直接HTML(DOM)にアクセスできないので、そういった処理をしているのであれば、多少複雑にはなりますがIPCと呼ばれるプロセス間通信などを行って、データをやり取りする必要があります

※正確にはnodeIntegrationを有効にした(状況から見てされていると思います)レンダラープロセスです。ここでは通常のブラウザとNode.jsの機能にアクセスできるため、Node.jsまたはブラウザしか想定していないライブラリは想定とは異なる動作を引き起こすことがあります

その他の選択肢としてdiscord.jsが公開しているWeb Buildを使用する選択肢もあります。基本的な動作としては変わらず、引き続き同様のエラーが出ることにはなりますが、Node.jsの仕様を無効にできるため、原因がすぐ分かるかと思います

ただしNode.jsを無効にする、つまりnodeIntegrationを無効にすることは、requireで読み込む他のNode.jsのライブラリやBufferなどの機能も使うことができなくなるため、場合によっては難しいかもしれません

最後に、今回のファイル送信に関してはBufferの代わりにArrayBufferを使用することで問題なく動くと思います(以上の理由からブラウザにはNode.jsの機能であるBufferを受け付けません)
BufferからArrayBufferに変換する方法は調べるといくつか出てきますが、buffer.bufferのようにBufferのインスタンスに対して.bufferプロパティにアクセスすることでArrayBufferを得ることができます
しかしこれは自分が該当箇所のソースを読んで気づいたことで、他のAPIでも挙動の違いがあると思うので、上記の方法をおすすめします(音声関連が使えない問題もありました)

調査して分かった情報などは electronでdiscord.jsを使うとブラウザ版として実行される にまとめたので興味があったらどうぞ

投稿2020/04/19 06:12

yuta0801

総合スコア270

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zel

2020/04/19 07:30

長い回答ありがとうございます、色々試してみます。
guest

0

まずelectronを省いた状態のdiscordbotを起動して、そこでテストしました

js

1 exec(`import -window "${args.join(' ')}" PNG:- | base64`, (err, stdout, stderr) => { 2 var base64_img = `${stdout.replace(/\n/g, "")}`; 3 var bufferImage = new Buffer.from(base64_img, "base64"); 4 5 message.channel.send({ 6 files: [ 7 { 8 attachment: bufferImage, 9 name: `window-${args.join(' ')}.png` 10 } 11 ] 12 }); 13 });

data:image/png;base64,はいりませんでした。

electronの場合このコードでも出来ませんでした。

エラー:

/home/.../Documents/…DataResolver.js:109 Uncaught (in promise) TypeError [REQ_RESOURCE_TYPE]: The resource must be a string, Buffer or a valid file stream.

投稿2020/04/18 22:31

編集2020/04/18 23:02
Zel

総合スコア11

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問