Slack limpa todas as mensagens (~ 8K) em um canal

85

Atualmente, temos um canal no Slack com cerca de 8 mil mensagens, todas provenientes da integração com o Jenkins. Existe alguma maneira programática de excluir todas as mensagens desse canal? A interface da web pode excluir apenas 100 mensagens por vez.

Hann
fonte

Respostas:

71

Eu descobri rapidamente que alguém já fez um ajudante: limpador de folga para isso.

E para mim é apenas:

slack-cleaner --token=<TOKEN> --message --channel jenkins --user "*" --perform

Hann
fonte
Outra opção vem do npm , só não tentei ainda.
Hann
3
Onde posso encontrar meu token e canal?
kk78626
6
--user "*"também é necessário para fazê-lo funcionar. Além disso, se você deseja realmente executar a tarefa de remoção, deve adicionar --perform.
Shayan Salehian
7
O fork github.com/sgratzl/slack-cleaner é mais ativo e inclui recursos como --quietnão exibir todas as mensagens sendo excluídas no stdout.
perplexidade de
25

Eu escrevi um script de nó simples para excluir mensagens de canais e bate-papos públicos / privados. Você pode modificar e usá-lo.

https://gist.github.com/firatkucuk/ee898bc919021da621689f5e47e7abac

Primeiro, modifique seu token na seção de configuração de scripts e execute o script:

node ./delete-slack-messages CHANNEL_ID

Obtenha um token OAuth:

  1. Acesse https://api.slack.com/apps
  2. Clique em 'Criar novo aplicativo' e nomeie seu aplicativo (temporário).
  3. No painel de navegação lateral, vá para 'Oauth e permissões'
  4. Nessa página, encontre a seção 'Escopos'. Clique em 'Adicionar um escopo OAuth' e adicione 'canais: histórico' e 'bate-papo: gravação'. (ver escopos)
  5. Na parte superior da página, clique em 'Instalar aplicativo no espaço de trabalho'. Confirme e, ao recarregar a página, copie o token de acesso OAuth.

Encontre o ID do canal

Além disso, o ID do canal pode ser visto na URL do navegador quando você abre o Slack no navegador. por exemplo

https://mycompany.slack.com/messages/MY_CHANNEL_ID/

ou

https://app.slack.com/client/WORKSPACE_ID/MY_CHANNEL_ID
Fırat KÜÇÜK
fonte
2
Obrigado por isso. Uma coisa que noto é que ele fica mais lento depois que algumas mensagens são excluídas.
Bertl
3
Geralmente, há uma limitação de taxa. É por isso que, após um período de tempo, as operações de exclusão vão parar ou ficar mais lentas.
Fırat KÜÇÜK de
2
Funciona como um encanto! Obrigado por isso!
brianrhea
1
Usei, fácil, doce. Observe que a resposta acima atualmente diz para usar tokens legados, que não são mais suportados, mas Firat já atualizou a própria essência com essas informações e fornece a lista de escopos OAuth necessários. Foi surpreendentemente rápido e fácil criar o aplicativo slack necessário para obter o token OAuth e adicionar a lista de escopos - estou falando de 100 segundos.
Daryn de
23

O comando de limpeza padrão não funcionou para mim, apresentando o seguinte erro:

$ slack-cleaner --token=<TOKEN> --message --channel <CHANNEL>

Running slack-cleaner v0.2.4
Channel, direct message or private group not found

mas a seguir funcionou sem nenhum problema para limpar as mensagens do bot

slack-cleaner --token <TOKEN> --message --group <CHANNEL> --bot --perform --rate 1 

ou

slack-cleaner --token <TOKEN> --message --group <CHANNEL> --user "*" --perform --rate 1 

para limpar todas as mensagens.

Eu uso o limite de taxa de 1 segundo para evitar HTTP 429 Too Many Requestserros por causa do limite de API de folga. Em ambos os casos, o nome do canal foi fornecido sem #sinal

Samir
fonte
11

!!ATUALIZAR!!

como @ niels-van-reijmersdal mencionado no comentário.

Este recurso foi removido. Veja este tópico para mais informações: twitter.com/slackhq/status/467182697979588608?lang=en

!! END UPDATE !!

Aqui está uma boa resposta do SlackHQ no twitter, e funciona sem qualquer coisa de terceiros. https://twitter.com/slackhq/status/467182697979588608?lang=en

Você pode excluir em massa por meio da página de arquivos ( http://my.slack.com/archives ) de um canal específico: procure por "excluir mensagens" no menu

Braggae
fonte
1
Apenas colocar isso lá fora, isso só funciona para canais e não para mensagens diretas.
TheRodeo
1
Isso exclui apenas as últimas 10 mensagens de cada vez
MatPag
1
Não, costumava apagar muitas mensagens com este método. Era cerca de 100 ou algo assim.
Braggae
1
Eu apenas usei. Se primeiro mostrasse apenas 10, mas depois de excluí-los, ele mostraria o resto (o canal tinha menos de 100 mensagens no total, então ainda poderia ser limitado a 100).
Albin
6
Isso não parece funcionar para mim. Ele redireciona para http: // <teamname> .slack.com / messages / <messageid> (parece ser o último canal que eu vi)
Devil's Advocate
10

Para qualquer pessoa que não precise fazer isso de forma programática, esta é uma maneira rápida :

(provavelmente apenas para usuários pagos)

  1. Abra o canal na web ou no aplicativo de desktop e clique na engrenagem (canto superior direito).
  2. Escolha "Opções adicionais ..." para abrir o menu de arquivamento. notas
  3. Selecione "Definir a política de retenção de mensagens do canal".
  4. Defina "Reter todas as mensagens por um número específico de dias".
  5. Todas as mensagens anteriores a esse horário são excluídas permanentemente!

Eu normalmente defino esta opção para "1 dia" para deixar o canal com algum contexto, então eu volto para as configurações acima e defino sua política de retenção para o "padrão" para continuar a armazená-los de agora em diante.

Observações:
Luke aponta: Se a opção estiver oculta: você deve ir para as configurações de administrador do espaço de trabalho global, Retenção e exclusão de mensagens e marcar "Permitir que os membros do espaço de trabalho substituam essas configurações"

Hicsy
fonte
2
Na verdade, está apenas escondido. Para fazer com que pareça, você deve ir para as configurações de administrador do espaço de trabalho global, Retenção e exclusão de mensagens, e marcar "Permitir que os membros do espaço de trabalho substituam essas configurações".
Lucas
Obrigado, eu atualizei para incluir seu comentário. Observe também que oferecemos até mesmo pagar ao Slack pelo tempo de desenvolvimento para excluir retrospectivamente, mas eles disseram que simplesmente não era possível além da edição corporativa (devido ao ambiente diferente para armazenar dados).
Hicsy
Conforme mencionado por @Hicsy, a opção "Retenção e exclusão de mensagens" é um "Recurso pago"
Phil,
4

Opção 1 Você pode definir um canal do Slack para excluir mensagens automaticamente após 1 dia, mas fica um pouco oculto. Primeiro, você precisa ir para as configurações do espaço de trabalho do Slack, Retenção e exclusão de mensagens, e marcar "Permitir que os membros do espaço de trabalho substituam essas configurações". Depois disso, no cliente Slack você pode abrir um canal, clicar na engrenagem e clicar em "Editar retenção de mensagem ..."

Opção 2 A ferramenta de linha de comando slack-cleaner que outros mencionaram.

Opção 3 Abaixo está um pequeno script Python que uso para limpar canais privados. Pode ser um bom ponto de partida se você quiser um controle mais programático da exclusão. Infelizmente, o Slack não tem API de exclusão em massa, e eles limitam a taxa de exclusão individual a 50 por minuto, então isso leva inevitavelmente muito tempo.

# -*- coding: utf-8 -*-
"""
Requirement: pip install slackclient
"""
import multiprocessing.dummy, ctypes, time, traceback, datetime
from slackclient import SlackClient
legacy_token = raw_input("Enter token of an admin user. Get it from https://api.slack.com/custom-integrations/legacy-tokens >> ")
slack_client = SlackClient(legacy_token)


name_to_id = dict()
res = slack_client.api_call(
  "groups.list", # groups are private channels, conversations are public channels. Different API.
  exclude_members=True, 
  )
print ("Private channels:")
for c in res['groups']:
    print(c['name'])
    name_to_id[c['name']] = c['id']

channel = raw_input("Enter channel name to clear >> ").strip("#")
channel_id = name_to_id[channel]

pool=multiprocessing.dummy.Pool(4) #slack rate-limits the API, so not much benefit to more threads.
count = multiprocessing.dummy.Value(ctypes.c_int,0)
def _delete_message(message):
    try:
        success = False
        while not success:
            res= slack_client.api_call(
                  "chat.delete",
                  channel=channel_id,
                  ts=message['ts']
                )
            success = res['ok']
            if not success:
                if res.get('error')=='ratelimited':
#                    print res
                    time.sleep(float(res['headers']['Retry-After']))
                else:
                    raise Exception("got error: %s"%(str(res.get('error'))))
        count.value += 1
        if count.value % 50==0:
            print(count.value)
    except:
        traceback.print_exc()

retries = 3
hours_in_past = int(raw_input("How many hours in the past should messages be kept? Enter 0 to delete them all. >> "))
latest_timestamp = ((datetime.datetime.utcnow()-datetime.timedelta(hours=hours_in_past)) - datetime.datetime(1970,1,1)).total_seconds()
print("deleting messages...")
while retries > 0:
    #see https://api.slack.com/methods/conversations.history
    res = slack_client.api_call(
      "groups.history",
      channel=channel_id,
      count=1000,
      latest=latest_timestamp,)#important to do paging. Otherwise Slack returns a lot of already-deleted messages.
    if res['messages']:
        latest_timestamp = min(float(m['ts']) for m in res['messages'])
    print datetime.datetime.utcfromtimestamp(float(latest_timestamp)).strftime("%r %d-%b-%Y")

    pool.map(_delete_message, res['messages'])
    if not res["has_more"]: #Slack API seems to lie about this sometimes
        print ("No data. Sleeping...")
        time.sleep(1.0)
        retries -= 1
    else:
        retries=10

print("Done.")

Observe que o script precisará ser modificado para listar e limpar os canais públicos. Os métodos de API para esses são canais. * Em vez de grupos. *

Lucas
fonte
1

Como outras respostas aludem, os limites de taxa do Slack tornam isso complicado - o limite de taxa é relativamente baixo para sua API chat.delete a cerca de 50 solicitações por minuto.

A melhor estratégia que respeita o limite de taxa é recuperar mensagens do canal que você deseja limpar e, em seguida, excluir as mensagens em lotes abaixo de 50 executados em um intervalo mínimo.

Eu construí um projeto contendo um exemplo deste lote que você pode facilmente bifurcar e implantar no Autocode - ele permite que você limpe um canal através do comando de barra (e permite que você restrinja o acesso ao comando a apenas alguns usuários, é claro!). Quando você executa /cmd clearem um canal, ele marca esse canal para limpeza e executa o seguinte código a cada minuto até excluir todas as mensagens no canal:

console.log(`About to clear ${messages.length} messages from #${channel.name}...`);

let deletionResults = await async.mapLimit(messages, 2, async (message) => {
  try {
    await lib.slack.messages['@0.6.1'].destroy({
      id: clearedChannelId,
      ts: message.ts,
      as_user: true
    });
    return {
      successful: true
    };
  } catch (e) {
    return {
      successful: false,
      retryable: e.message && e.message.indexOf('ratelimited') !== -1
    };
  }
});

Você pode ver o código completo e um guia para implantar sua própria versão aqui: https://autocode.com/src/jacoblee/slack-clear-messages/

Jacob Lee
fonte
0

Se você gosta do Python e obteve um token de API legado da API do slack, pode excluir todas as mensagens privadas enviadas a um usuário com o seguinte:

import requests
import sys
import time
from json import loads

# config - replace the bit between quotes with your "token"
token = 'xoxp-854385385283-5438342854238520-513620305190-505dbc3e1c83b6729e198b52f128ad69'

# replace 'Carl' with name of the person you were messaging
dm_name = 'Carl'

# helper methods
api = 'https://slack.com/api/'
suffix = 'token={0}&pretty=1'.format(token)

def fetch(route, args=''):
  '''Make a GET request for data at `url` and return formatted JSON'''
  url = api + route + '?' + suffix + '&' + args
  return loads(requests.get(url).text)

# find the user whose dm messages should be removed
target_user = [i for i in fetch('users.list')['members'] if dm_name in i['real_name']]
if not target_user:
  print(' ! your target user could not be found')
  sys.exit()

# find the channel with messages to the target user
channel = [i for i in fetch('im.list')['ims'] if i['user'] == target_user[0]['id']]
if not channel:
  print(' ! your target channel could not be found')
  sys.exit()

# fetch and delete all messages
print(' * querying for channel', channel[0]['id'], 'with target user', target_user[0]['id'])
args = 'channel=' + channel[0]['id'] + '&limit=100'
result = fetch('conversations.history', args=args)
messages = result['messages']
print(' * has more:', result['has_more'], result.get('response_metadata', {}).get('next_cursor', ''))
while result['has_more']:
  cursor = result['response_metadata']['next_cursor']
  result = fetch('conversations.history', args=args + '&cursor=' + cursor)
  messages += result['messages']
  print(' * next page has more:', result['has_more'])

for idx, i in enumerate(messages):
  # tier 3 method rate limit: https://api.slack.com/methods/chat.delete
  # all rate limits: https://api.slack.com/docs/rate-limits#tiers
  time.sleep(1.05)
  result = fetch('chat.delete', args='channel={0}&ts={1}'.format(channel[0]['id'], i['ts']))
  print(' * deleted', idx+1, 'of', len(messages), 'messages', i['text'])
  if result.get('error', '') == 'ratelimited':
    print('\n ! sorry there have been too many requests. Please wait a little bit and try again.')
    sys.exit()
duhaime
fonte
-1

Existe uma ferramenta de folga para excluir todas as mensagens de folga em seu espaço de trabalho. Confira: https://www.messagebender.com

Mrdev
fonte
-2

Esta é uma ótima extensão do Chrome para excluir em massa suas mensagens slack channel / group / im - https://slackext.com/deleter , onde você pode filtrar as mensagens por estrela, intervalo de tempo ou usuários. BTW, ele também suporta carregar todas as mensagens na versão recente, então você pode carregar suas mensagens ~ 8k conforme necessário.

Huan
fonte