【问题标题】:Discord.js meme command with meme subreddit returns image as 403 forbidden带有 meme subreddit 的 Discord.js meme 命令将图像返回为 403 禁止
【发布时间】:2020-08-04 13:58:45
【问题描述】:

我正在制作一个 meme 命令,该命令从 meme subreddit 发送一个随机 meme,在发现除了嵌入中的实际图像之外的所有内容后,我将图像记录到控制台并返回 403 错误。如果有人能够提供帮助,将不胜感激。

代码:

const https = require('https');
const Discord = require('discord.js');
const url = 'https://www.reddit.com/r/meme/hot/.json?limit=100'

module.exports = {
    name: 'meme',
    description: 'sends meme',
    execute(message, args) {

        https.get(url, (result) => {
            var body = ''
            result.on('data', (chunk) => {
                body += chunk
            })

            result.on('end', () => {
                var response = JSON.parse(body)
                var index = response.data.children[Math.floor(Math.random() * 99) + 1].data

                if (index.post_hint !== 'image') {

                    var text = index.selftext
                    const textembed = new Discord.MessageEmbed()
                        .setTitle(subRedditName)
                        .setColor(9384170)
                        .setDescription(`[${title}](${link})\n\n${text}`)
                        .setURL(`https://reddit.com/${subRedditName}`)

                    message.channel.send(textembed)
                }

                var image = index.preview.images[0].source.url
                var title = index.title
                var link = 'https://reddit.com' + index.permalink
                var subRedditName = index.subreddit_name_prefixed

                if (index.post_hint !== 'image') {
                    const textembed = new Discord.RichEmbed()
                        .setTitle(subRedditName)
                        .setColor(9384170)
                        .setDescription(`[${title}](${link})\n\n${text}`)
                        .setURL(`https://reddit.com/${subRedditName}`)

                    message.channel.send(textembed)
                }
                console.log(image);
                const imageembed = new Discord.MessageEmbed()
                    .setTitle(subRedditName)
                    .setImage(image)
                    .setColor(9384170)
                    .setDescription(`[${title}](${link})`)
                    .setURL(`https://reddit.com/${subRedditName}`)
                message.channel.send(imageembed)
            }).on('error', function (e) {
                console.log('Got an error: ', e)
            })
        })
    },


}

【问题讨论】:

    标签: javascript node.js https discord.js


    【解决方案1】:

    我调整了代码以使其适用于任何 subreddit。所以你只需做(前缀)meme funny,它会在前 100 个或更少的帖子中搜索 subreddit “funny”。我还添加了一个 nsfw 检查。如果您不在 discord 的 nsfw 频道中,那么它将遍历前 100 个帖子中的每一个,并检查它是否是 nsfw。如果是,那么它将从我将每个帖子推入的数组中删除。如果它找不到非 nsfw 帖子,那么它会在聊天中告诉你。但是,如果您在 nsfw 聊天中,那么它只会从它找到的前 100 个帖子中随机选择一个帖子。

    旁注:我找不到检查 subreddit 是否存在的方法,所以我只是检查结果是否超过 1000 个字符。任何存在的子版块应该有超过 1000 个字符。任何不存在的字符都应少于 1000 个字符。

    const prefix = '.'
    const args = message.content.substring(1).split(" ")
    if (message.content.startsWith(prefix){
        if (args[0] == 'meme'){
            if (args[1] != null){
                var url = `https://www.reddit.com/r/${args[1]}/hot/.json?limit=100`
            } else {
                var url = `https://www.reddit.com/r/meme/hot/.json?limit=100`
            }
                https.get(url, (result) => {
                    var body = ''
                    var chunked = false
                    result.on('data', (chunk) => {
                        body += chunk
                        if (chunked == false){
                            chunked = true
                        }
                    })
                    result.on('end', () => {
                        if (body.length > 1000){
                            var response = JSON.parse(body)
                            var postChildren = []
                            if (message.channel.nsfw == false){
                                var postsNumber = 0
                                for (var number = 0; number < response.data.children.length; number++){
                                    postChildren.push(number)
                                }
                                for (var found = false; found == false; postsNumber ++){
                                    if (postChildren.length > 0){
                                        var index1 = Math.floor(Math.random() * (postChildren.length))
                                        var index2 = postChildren[index1]
                                        if (response.data.children[index2].data.over_18 == true){
                                            postChildren.splice(index1, 1)
                                        } else {
                                            var index = response.data.children[index2].data
                                            var found = true
                                        }
                                    } else {
                                        var found = true
                                    }
                                }
                            } else {
                                var index = response.data.children[Math.floor(Math.random() * (response.data.children.length-1)) + 1].data
                            }
                            if (postChildren.length > 0 || message.channel.nsfw){
                                var title = index.title
                                var link = 'https://reddit.com' + index.permalink
                                var subRedditName = index.subreddit_name_prefixed
                                if (index.post_hint !== 'image') {
                                    var text = index.selftext
                                    if (title.length > 256) {
                                        title = (title.substring(0, 253) + "...")
                                    } 
                                    if (text.length > 2048) {
                                        text = (text.substring(0, 2045) + "...")
                                    } 
                                    const textembed = new Discord.MessageEmbed()
                                    .setTitle(title)
                                    .setColor('#ff0000')
                                    .setDescription(text)
                                    .setURL(`https://reddit.com/${subRedditName}`)
                                    message.channel.send(textembed)
                                }
                                if (index.post_hint == 'image'){
                                    var image = index.preview.images[0].source.url.replace('&amp;', '&')
                                    if (title.length > 256) {
                                        title = (title.substring(0, 253) + "...")
                                    } 
                                    const imageembed = new Discord.MessageEmbed()
                                    .setTitle(title)
                                    .setImage(image)
                                    .setColor('#ff0000')
                                    .setURL(link)
                                    message.channel.send(imageembed)  
                                }
                            } else {
                                message.channel.send('Could not find a meme that was not nsfw')
                            }
                        } else {
                            message.channel.send('Could not find subreddit!')
                        }
                    }).on('error', function (e) {
                        console.log('Got an error: ', e)
                    })
                })
        }
    }
    

    【讨论】:

      【解决方案2】:

      我试过你的代码,发现图片URL中的&amp;amp;被编码为&amp;amp;(例如:https://preview.redd.it/z8jsjzvkhq051.jpg?auto=webp&amp;amp;s=bb492d4861f48b62da806584f26bcc15f4d6663a)Redd.it无法理解并返回403错误。

      只需将图片 URL 中的 &amp;amp; 替换为 &amp;amp; 即可。

      const https = require('https');
      const Discord = require('discord.js');
      const url = 'https://www.reddit.com/r/meme/hot/.json?limit=100'
      
      module.exports = {
          name: 'meme',
          description: 'sends meme',
          execute(message, args) {
      
              https.get(url, (result) => {
                  var body = ''
                  result.on('data', (chunk) => {
                      body += chunk
                  })
      
                  result.on('end', () => {
                      var response = JSON.parse(body)
                      var index = response.data.children[Math.floor(Math.random() * 99) + 1].data
      
                      if (index.post_hint !== 'image') {
      
                          var text = index.selftext
                          const textembed = new Discord.MessageEmbed()
                              .setTitle(subRedditName)
                              .setColor(9384170)
                              .setDescription(`[${title}](${link})\n\n${text}`)
                              .setURL(`https://reddit.com/${subRedditName}`)
      
                          message.channel.send(textembed)
                      }
      
                      var image = index.preview.images[0].source.url.replace('&amp;', '&')
                      var title = index.title
                      var link = 'https://reddit.com' + index.permalink
                      var subRedditName = index.subreddit_name_prefixed
      
                      if (index.post_hint !== 'image') {
                          const textembed = new Discord.RichEmbed()
                              .setTitle(subRedditName)
                              .setColor(9384170)
                              .setDescription(`[${title}](${link})\n\n${text}`)
                              .setURL(`https://reddit.com/${subRedditName}`)
      
                          message.channel.send(textembed)
                      }
                      console.log(image);
                      const imageembed = new Discord.MessageEmbed()
                          .setTitle(subRedditName)
                          .setImage(image)
                          .setColor(9384170)
                          .setDescription(`[${title}](${link})`)
                          .setURL(`https://reddit.com/${subRedditName}`)
                      message.channel.send(imageembed)
                  }).on('error', function (e) {
                      console.log('Got an error: ', e)
                  })
              })
          },
      }
      

      【讨论】:

        【解决方案3】:

        这有点难以阅读,因为您重复了两次代码块(两个文本嵌入和 img 嵌入)

        第一个[Math.floor(Math.random() * 99) + 1] => [Math.floor(Math.random() * 100)] 第二个使它可以选择任何值,第一个永远不能为0。

        试试这个(在索引变量后插入代码)

        const isImage = index.post_hint === "image";
        const subRedditName = index.subreddit_name_prefixed;
        const title = index.title;
        const link = 'https://reddit.com' + index.permalink;
        const text = !isImage && index.selfText;
        const desc = `[${title}](${link})`;
        
        const embed = new Discord.MessageEmbed()
            .setTitle(subRedditName)
            .setColor(9384170)
            .setDescription(desc + (text ? `\n\n${text}` : ""))
            .setURL(`https://reddit.com/${subRedditName}`);
        
        if (isImage) {
            const img = index.preview.images[0].source.url;
            embed.setImage(img);
        }
        
        messsage.channel.send(embed);
        

        【讨论】:

        • 与不发送实际图像本身相同的问题。
        猜你喜欢
        • 2022-01-12
        • 2020-10-11
        • 2021-07-05
        • 2021-08-28
        • 2020-11-24
        • 2019-07-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多