首页 > 解决方案 > 使用带有批处理的 Trello REST API 获取卡片封面图像

问题描述

我正在尝试从板上获取所有卡片的封面图像链接,但板端点仅提供封面图像的附件 ID。这可能很好,但我也看不到如何使用该 ID 来获取完整的图像链接。这是我的要求:

${TRELLO_API_ROOT}/boards/${boardId}?key=${TRELLO_KEY}&token=${TRELLO_TOKEN}&cards=all&card_customFieldItems=true&attachments=true&attachment_fields=all

这将返回每张卡片的所有卡片和封面图像详细信息,但这些信息对于获取完整图像路径似乎没有用:

cards: [{
  cover: {
    brightness: "light",
    color: null,
    idAttachment: "5eee7680d7b0295f6c52fc22",
    idUploadedBackground: null,
    size: "normal
  }
}]

我考虑过我可能需要使用批处理过程为每张卡片向卡片端点发出请求,但该过程仅限于 10 个请求。一块板很容易有超过 10 张卡,所以这似乎不是一个好的解决方案。

您是否需要向每张卡片发送请求才能获取封面图片?

编辑:我看到的唯一方法是针对附件端点对每张卡发出单独的请求。不过,这可能会产生很多请求:

const requests = data.cards.filter((item) => {
  return item.cover.idAttachment;
}).map((card) => {
  return fetch(`${TRELLO_API_ROOT}/cards/${card.id}/attachments/${card.cover.idAttachment}?key=${TRELLO_KEY}&token=${TRELLO_TOKEN}`)
})

Promise.all(requests)
  .then(responses => {
    return responses;
  })
  .then(responses => Promise.all(responses.map(res => res.json())))
  .then(attachments => {
    return attachments;
  });

标签: apiresttrello

解决方案


回答我自己的问题,因为我认为除了为每张卡发送单独的请求之外,没有其他解决方案。但我们至少可以通过使用batch.

和一个澄清; 如果卡片已被分配上传的图片作为封面,您只需请求封面图片附件 url。如果卡片封面是 Trello 现在提供的可用 Unplashed 图像之一,您将在常规boards端点请求中获得该图像 url,sharedSourceUrl如下所示:

{
  brightness: "light",
  color: null,
  edgeColor: "#776e5d",
  idAttachment: null,
  idUploadedBackground: "5efe2d6c4292a74f4c4051e0",
  scaled: (10) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}],
  sharedSourceUrl: "https://images.unsplash.com/photo-1593435220813-8e60f12e947a?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjcwNjZ9&w=2560&h=2048&q=90",
  size: "normal"
}

我不知道他们不会自动为上传的图片网址做同样的事情是否是一个过度网站,但如果是上传的话,似乎没有任何其他方法可以获取卡片图片。

因此,使用批处理,您需要确保一次只发送 10 个网址。这很简单,使用标准循环来构建数组。然后我们可以将批处理请求排队到 aPromise.all中,并通过将该封面 url 分配给相应的卡来处理响应。我们可以通过这种方式显着减少请求,但在第一个板获取期间提供封面 url 仍然很好。

fetch(`${TRELLO_API_ROOT}/boards/${boardId}?cards=visible&card_customFieldItems=true&key=${TRELLO_KEY}&token=${TRELLO_TOKEN}&attachments=true&attachment_fields=all`)
  .then(response => response.json())
  .then((data) => {
    const cardsWithCovers = data.cards.filter((item, i) => {
      return item.cover.idAttachment;
    });

    // Creating our batched request array for fetching cover urls.
    const batchedUrls = [];
    let batch = [];

    // Creating batches.
    for (let i = 0; i < cardsWithCovers.length; i++) {
      // Important here not to append the url root, api key, or token values. That's how the batch endpoint wants it.
      const url = `/cards/${cardsWithCovers[i].id}/attachments/${cardsWithCovers[i].cover.idAttachment}`;
      batch.push(url);
      // If we have our max 10 request urls, or it's the last item, push the request url group and reset batch array.
      if (batch.length === 10 || i === cardsWithCovers.length - 1) {
        batchedUrls.push(batch);
        batch = [];
      }
    }

    const requests = batchedUrls.map((urls) => {
      return fetch(`${TRELLO_API_ROOT}/batch?key=${TRELLO_KEY}&token=${TRELLO_TOKEN}&urls=${urls}`)
    });


    Promise.all(requests)
      .then(responses => Promise.all(responses.map(res => res.json())))
      .then(batchedData => {
      // Combine the batched array responses into a single array.
      const mergedCardsWithCovers = [].concat.apply([], batchedData);
      data.cards.forEach((card) => {
        // Finding the card cover image url and adding it to the card.
        const cover = mergedCardsWithCovers.find((cardWithCover) => {
          return card.cover.idAttachment === cardWithCover[200].id;
        });
        if (cover) card.cover.url = cover[200].url;
      });
    })
  })

推荐阅读