Как получить сообщения Slack через API, определенный постоянной ссылкой? - PullRequest
0 голосов
/ 13 апреля 2020

Я пытаюсь получить список напоминаний Slack, который отлично работает, используя метод Slack API reminders.list. Однако напоминания, которые устанавливаются с помощью SlackBot (то есть, запрашивая Slackbot напомнить мне о сообщении), возвращают соответствующую постоянную ссылку этого сообщения как text:

{
    "ok": true,
    "reminders": [
        {
            "id": "Rm012C299C1E",
            "creator": "UV09YANLX",
            "text": "https:\/\/team.slack.com\/archives\/DUNB811AM\/p1583441290000300",
            "user": "UV09YANLX",
            "recurring": false,
            "time": 1586789303,
            "complete_ts": 0
        },

Вместо отображения постоянной ссылки, я бы естественно, хотел бы показать сообщение, о котором я хотел бы напомнить. Однако я не смог найти никаких подсказок в документации Slack API о том, как извлечь сообщение, идентифицированное с помощью постоянной ссылки. Ссылка предположительно генерируется chat.getPermalink, но, кажется, нет очевидного chat.getMessageByPermalink или около того.

Я пытался интерпретировать элементы пути как channel и метку времени, но метку времени (преобразованную из пример выше: 1583441290.000300), похоже, не соответствует. По крайней мере, я не получаю сообщение, которое ожидал получить при передаче от latest до conversations.history и limit до 1.

1 Ответ

0 голосов
/ 24 апреля 2020

Пройдя немного дольше, вот как я наконец справился с JS:

async function downloadSlackMsgByPermalink(permalink) {
  const pathElements = permalink.substring(8).split('/');
  const channel = pathElements[2];

  var url;
  if (permalink.includes('thread_ts')) {
    // Threaded message, use conversations.replies endpoint
    var ts = pathElements[3].substring(0, pathElements[3].indexOf('?'));
    ts = ts.substring(0, ts.length-6) + '.' + ts.substring(ts.length-6);

    var latest = pathElements[3].substring(pathElements[3].indexOf('thread_ts=')+10);
    if (latest.indexOf('&') != -1) latest = latest.substring(0, latest.indexOf('&'));

    url = `https://slack.com/api/conversations.replies?token=${encodeURIComponent(slackAccessToken)}&channel=${channel}&ts=${ts}&latest=${latest}&inclusive=true&limit=1`;
  } else {
    // Non-threaded message, use conversations.history endpoint
    var latest = pathElements[3].substring(1);
    if (latest.indexOf('?') != -1) latest = latest.substring(0, latest.indexOf('?'));
    latest = latest.substring(0, latest.length-6) + '.' + latest.substring(latest.length-6);
    url = `https://slack.com/api/conversations.history?token=${encodeURIComponent(slackAccessToken)}&channel=${channel}&latest=${latest}&inclusive=true&limit=1`;
  }
  const response = await fetch(url);
  const result = await response.json();
  if (result.ok === true) {
    return result.messages[0];
  }
}

Он не был протестирован до последней версии, но первые результаты выглядят хорошо:

  • Уловка с конечной точкой conversations.history заключалась в том, чтобы включить параметр inclusive=true
  • Сообщения могли бы быть многопоточными - отдельная конечная точка conversations.replies необходима для извлечения этих
  • в качестве Slack API состояние документов: ts и thread_ts выглядят как временные метки, но это не так. Однако использование их немного похоже на временные метки (т.е. обрезание некоторых символов сзади и вставка точки), к счастью, работает.
  • Естественно, переменная slackAccessToken должна быть установлена ​​заранее

Я знаю, что способ извлечения и преобразования компонентов URL в приведенном выше коде может быть не самым элегантным решением, но он подтверждает концепцию: -)

...