Coder Social home page Coder Social logo

symantec / slack-autoarchive Goto Github PK

View Code? Open in Web Editor NEW
116.0 26.0 73.0 58 KB

If there has been no activity in a channel for awhile, you can automatically archive it using a cronjob.

License: Apache License 2.0

Python 98.38% Dockerfile 1.62%
slack automation archive python

slack-autoarchive's Introduction

Autoarchive unused slack channels

Requirements

  • python3
  • Install requirements.txt ( pip install -r requirements.txt )
  • An OAuth token from a Slack app on your workspace that has the following permission scopes:
    • channels:history
    • channels:read
    • channels:write
    • chat:write:bot
    • chat:write:user

Example Usages

The SLACK_TOKEN must be exposed as a environment variable before running your script. By default, the script will do a DRY_RUN. To perform a non-dry run, specify DRY_RUN=false as an environment variable as well. See sample usages below.

# Run the script in dry run archive mode...This will output a list of channels that will be archived.
SLACK_TOKEN=<TOKEN> python slack_autoarchive.py

# Run the script in active archive mode...THIS WILL ARCHIVE CHANNELS!
DRY_RUN=false SLACK_TOKEN=<TOKEN> python slack_autoarchive.py

How can I exempt my channel from being archived?

You can add the string '%noarchive' to your channel purpose or topic. (There is also a whitelist file or env variable if you prefer.)

What Channels Will Be Archived

A channel will be archived by this script is it doesn't meet any of the following criteria:

  • Has non-bot messages in the past 60 days.
  • Is whitelisted. A channel is considered to be whitelisted if the channel name contains keywords in the WHITELIST_KEYWORDS environment variable. Multiple keywords can be provided, separated by comma.

What Happens When A Channel Is Archived By This Script

  • *Don't panic! It can be unarchived by following these instructions However all previous members would be kicked out of the channel and not be automatically invited back.
  • A message will be dropped into the channel saying the channel is being auto archived because of low activity
  • You can always whitelist a channel if it indeed needs to be kept despite meeting the auto-archive criteria.

Custom Archive Messages

Just before a channel is archived, a message will be sent with information about the archive process. The default message is:

This channel has had no activity for %s days. It is being auto-archived. If you feel this is a mistake you can <https://get.slack.help/hc/en-us/articles/201563847-Archive-a-channel#unarchive-a-channel|unarchive this channel> to bring it back at any point.'

To provide a custom message, simply edit templates.json.

Known Issues

  • Since slack doesn't have a batch API, we have to hit the api a couple times for each channel. This makes the performance of this script slow. If you have thousands of channels (which some people do), get some coffee and be patient.

Docker

  • First build the docker image (in the root of the project)

docker build --tag autoarchive .

  • run the container (dryrun is set to true by default)

docker run -e SLACK_TOKEN=<YOUR_AWESOME_TOKEN> autoarchive

  • if your ready to archive run

docker run -e SLACK_TOKEN=<YOUR_AWESOME_TOKEN> -e DRY_RUN=false autoarchive

slack-autoarchive's People

Contributors

adamjdeacon avatar adamkaplan avatar alberto-sierra avatar broom9 avatar bytesandwich avatar girasquid avatar helgi avatar johntheodore avatar lozette avatar sethgoldin avatar tehshrike avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

slack-autoarchive's Issues

requests throttling not working

While trying the script, I would get random rate limit errors, which is unexpected since the code already has logic to prevent that from happening:

THIS IS A DRY RUN. NO CHANNELS ARE ACTUALLY ARCHIVED.
Find inactive channels...
.....................................{u'ok': False, u'error': u'ratelimited'}

I believe this is caused by the sys.exit code executed when ok is not true.
after removing this block, this is the result:

THIS IS A DRY RUN. NO CHANNELS ARE ACTUALLY ARCHIVED.
Find inactive channels...
.......................................Rate-limited. Retrying after 1.2ms
....................................................................................................Archive inactive channels...
Archiving channel... slack-test

See #13

Missing Requirements

Has bot messages in the past 60 days and has more than 5 members.

There is no check for 5 members, or specifically bot messages for that matter... I would suggest removing that from the README, but since I need this functionality, I'll try to add it.

Switch to pipeline-based code flow

(Issues that came up when archiving 3,950 channels in a massive Slack team, I may submit a fix myself)

Currently it takes ~3 hours to crawl the activity in my massive Slack team due to rate limiting. One major headache has been that sometimes bugs are exposed after 3-4 hours of churning, and it take another 3-4 hours to verify the fix.

This is largely because the code operates in batches:

  • Get all channels
  • Find last message in all channels
  • Filter to just the channels to archive
  • Archive all channels

It's a lot easier to debug if we move to a process where that flow is applies to each channel individually. Then, when the script crashes, it'll start again where it left off.

I have this hacked in right now – need to clean up and PR it

Scopes organization has changed

Running into an issue with:
TypeError: 'NoneType' object is not subscriptable

I went back to check the scopes on the token, and I'm seeing that channels:write doesn't exist anymore. Trying to figure out what scopes are actually required now.

TypeError: 'NoneType' not iterable

I apologize for creating what looks like an identical issue. This appears to be a different segment of code giving me the error.
See this screenshot:
Screen Shot 2022-01-20 at 3 55 02 PM

Setting WHITELIST_KEYWORDS to any value throws an error

Setting WHITELIST_KEYWORDS to any value throws an error:

$ export SLACK_TOKEN=[token]
$ export WHITELIST_KEYWORDS=xyzzy
$ PYTHONIOENCODING=UTF-8 python slack-autoarchive.py
THIS IS A DRY RUN. NO CHANNELS ARE ACTUALLY ARCHIVED.
.Traceback (most recent call last):
  File "slack-autoarchive.py", line 205, in <module>
    if (not is_channel_whitelisted(channel, whitelist_keywords) and
  File "slack-autoarchive.py", line 148, in is_channel_whitelisted
    if kw in channel['name']:
TypeError: coercing to Unicode: need string or buffer, list found

$ unset WHITELIST_KEYWORDS
$ PYTHONIOENCODING=UTF-8 python slack-autoarchive.py
THIS IS A DRY RUN. NO CHANNELS ARE ACTUALLY ARCHIVED.
.Archiving channel... alternative_facts
.Archiving channel... animals
...

Also tried comma-delimited lists of keywords and setting or unsetting PYTHONIOENCODING. Same error occurs.

TypeError: not enough arguments for format string

Receving this error when trying to run. The dry run works perfectly. This only happens when the Dry Run is set to False.

C:\Python36\slack-autoarchive-master>python slack-autoarchive.py
..Archiving channel... agile
Traceback (most recent call last):
File "slack-autoarchive.py", line 198, in
channel_reaper.main()
File "slack-autoarchive.py", line 191, in main
self.archive_channel(channel, alert_templates['channel_template'])
File "slack-autoarchive.py", line 162, in archive_channel
channel_message = alert % self.days_inactive
TypeError: not enough arguments for format string

TypeError: argument of type 'NoneType' is not iterable

root@bot:~/slack-autoarchive# docker run -e SLACK_TOKEN=xxxxx autoarchive
2020-04-09 23:40:35,604 - INFO - THIS IS A DRY RUN. NO CHANNELS ARE ACTUALLY ARCHIVED.
.Traceback (most recent call last):
  File "slack_autoarchive.py", line 253, in <module>
    CHANNEL_REAPER.main()
  File "slack_autoarchive.py", line 241, in main
    channel_disused = self.is_channel_disused(
  File "slack_autoarchive.py", line 152, in is_channel_disused
    (last_message_datetime, is_user) = self.get_last_message_timestamp(
  File "slack_autoarchive.py", line 124, in get_last_message_timestamp
    if 'messages' not in channel_history:
TypeError: argument of type 'NoneType' is not iterable

Same happens when calling script directly.

TypeError: 'NoneType' object has no attribute '__getitem__'

First off, thank you so much for this, awesome idea. I'm encountering the issue below as was hoping you had an idea for a fix.

SLACK_TOKEN=xxxxxxx python slack_autoarchive.py
2020-06-18 13:12:27,331 - INFO - THIS IS A DRY RUN. NO CHANNELS ARE ACTUALLY ARCHIVED.
Traceback (most recent call last):
File "slack_autoarchive.py", line 253, in
CHANNEL_REAPER.main()
File "slack_autoarchive.py", line 235, in main
for channel in self.get_all_channels():
File "slack_autoarchive.py", line 108, in get_all_channels
payload=payload)['channels']
TypeError: 'NoneType' object has no attribute 'getitem'

rate limiting

Slack has recently (in August 2017?) introduced rate limiting. Their API was limited when this script was written, so we queried every channel one at a time to get the history. It might be they added new API functionality to let us batch get history? If you have say 100 channels, it hits a limit. The output looks like this:

➜ slack-autoarchive git:(master) DRY_RUN=False python slack-autoarchive.py
Find inactive channels...
................................Traceback (most recent call last):
File "slack-autoarchive.py", line 152, in
inactive_channels = get_inactive_channels(all_unarchived_channels, TOO_OLD_DATETIME)
File "slack-autoarchive.py", line 82, in get_inactive_channels
channel_history = slack_api_http(api_endpoint=api_endpoint, payload=payload)
File "slack-autoarchive.py", line 37, in slack_api_http
raise Exception(e)
Exception: {"ok":false,"error":"ratelimited"}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.