Как развернуть для своей команды архив slack сообщений c синхронизацией и поиском

  • Tutorial
Я сам сторонник идеи что если нравится продукт то нужно покупать его и своими деньгами поддержать программистов.
Но иногда бывает что компания на этот софт денег тратить не может или не хочет. Особенно сложно платить от 100$ в месяц когда есть бесплатные аналоги или если чаты используются в некоммерческих целях.

Я опишу как можно развернуть сервис для хранения истории всех публичных сообщений вашей команды в slack и избавиться от основного, неприятного, иногда выбешивающего ограничения — up to 10k of your team’s most recent messages (можно смотреть и искать только среди 10 000 последних сообщений)

Среди готовых решений есть:


По подробнее расскажу про последнее решение, оно мне больше всего понравилось.

Как можно легко заметить основная идея принадлежит Lê Việt Hồng ( github.com/suoinguon ) я взял его решение за основу и начал добавлять туда разные фичи.
Так как это обычное Django приложение то новые фичи туда добавлять оказалось очень просто.

По сравнению с оригиналом теперь появились:
  • Полнотекстовый поиск по истории django-watson
  • Индексация только публичных групп и пониженный уровень токена только с необходимыми правами
  • Форматирование сообщений как в slack, включая смайлы django-emoji
  • Обновление всех библиотек и поддержка django 1.10
  • Импорт данных из выгружженого архива
  • Исправлены недочеты в логике получения данныз по API
  • Добавлены новые страницы — сообщения пользователя, статистика с помощью django orm
  • Добавлена навигация для того чтобы можно было отправить ссылку на конкретное сообщение c учетом пагинации django-pagination


Среди дальнейших планов хочется отметить:
  • Поддержать работы с несколькими командами
  • Улучшить работу с отображением файлов
  • Добавить возможность сложного поиска
  • Добавить больше веселой или полезной статистики


Создание сервера


А теперь к делу, давайте развернем себе этот проект.
Первым делом нам понадобится виртуальный сервер. Для небольших команд будет достаточно минимальной конфигурации.

Например, что можно запустить быстро и дешево:
vscale.io


www.digitalocean.com


aws.amazon.com/ru/ec2

(если регистрируетесь первый
раз то первый год одной машины будет бесплатно)

0.0065$ в час
512mb
1 vcpu
Ebs disk


Итого можно получить отдельный сервер за 200 рублей в месяц или вообще бесплатно на первое время.
Я проверял скрипт на Centos7 поэтому при создании выбираем её, узнаем её ip адрес или доменное имя и запоминаем их, они потребуется на следующем шагу.

Регистрируем slack приложение



Далее нам нужно зарегистрировать slack приложение для доступа к API

  1. Заходим на страницу api.slack.com/applications
  2. Создаем новое приложение


  3. Добавляем адрес только что созданного сервера в oauth redirects


  4. Сохраняем себе Client ID и Client Secret




Запускаем приложение


  1. Подключаемся по ssh на сервер
  2. Запускаем команду
  3. curl -O https://raw.githubusercontent.com/menemy/slack-backup/master/provisioning_on_centos7.sh
    
  4. Исправляем три настройки в начале скрипта
  5. SLACK_CLIENT_ID=[your_client_id]
  6. SLACK_CLIENT_SECRET=[your_client_secret]
  7. DOMAIN=[your_domain]
  8. Исправляем права и запускаем
  9. chmod 777 provisioning_on_amazonlinux.sh
  10. sudo ./provisioning_on_amazonlinux.sh
  11. Всё, после этого приложение запущено и доступно по вашему адресу, история синхронизируется раз в пять минут
  12. Нужно зайти на сайт и предоставить доступ в свой аккаунт slack


Опционально, восстанавливаем историю сообщений


Если вы узнали об этом решении поздно — не беда, slack на самом деле продолжает хранить вашу историю и позволяет выгрузить всю историю в виде zip архива.
Но это только для администраторов группу.

  1. Зайдите на страницу my.slack.com/services/export
  2. Создайте выгрузку
  3. Дождитесь окончания
  4. Обновите страницу и скачайть zip файл
  5. Загрузите файл на сервер и выгрузите в папку /usr/local/src/slack-backup/full_history/
  6. Запустите команду python /usr/local/src/slack-backup/manage.py restore_backup
  7. Дождитесь окончания, это может занять время




Буду рад если мои старания будут полезны. Если есть вопросы по работе или необходима помощь с установкой буду рад помочь в комментариях.
Ads
AdBlock has stolen the banner, but banners are not teeth — they will be back

More

Comments 27

    0
    Есть ещё вот такая open source альтернатива Slack:
    https://www.mattermost.org/
    без подобных ограничений и необходимости пилить костыли.

    Сам сёрвис и веб-приложение работает без проблем. Я столкнулся со сложностью конфигураций push-notifications для мобильных приложений: там надо ставить для этого отдельный push-сервис, и потом связывать его с Googe и с Apple… Я уже не стал возиться.
      +1
      я бы не сказал, что он работает без проблем. Лично у меня были проблемы с отображением gui(под linux), не сворачивался в трей и как-то крито срабатывали нотификации. Сам по себе продукт очень сырой.
      –1
      Упростите инсталляцию, сделайте так чтобы спрашивало при инсталляции те самые 3 параметра, которые в скрипте надо править, тогда тех, кто будет юзать Ваше приложение будет больше и фидбэка будет больше, если конечно хотите развивать его(Ваш прроект) дальше…

      P.S.
      Сам я слак не юзаю, знакомился как-то, он мне показался через чур замудрённым в плане UI, между слаком и хипчатом всё таки выбрал последний, у него были менее жесткие ограничения на бесплатном уровне. Тем не менее у хипчата тоже ограничения по хранению истории, ноя ограничился написание простого скрипта стнкующего по апи в sqlite хистори, до написания какого-либо WUI так руки и не дошли…
        +1
        Спасибо за замечание, сделал интерактивную версию скрипта
        curl -O https://raw.githubusercontent.com/menemy/slack-backup/master/provisioning_on_centos7_interactive.sh
        


        0
        Можно сделать альтернативный клиент на нод-вебките, вставить куда-нибудь див с инпутом поиска и отправлять запросы на апи своего сервера :D
          0
          Тоже решал эту проблему. Написал на node.js/express 10-строчник который отправляет все это в Logstash-Elasticsearch-Kibana крутящиеся в докере. Последняя решила проблему морды для поиска. На все про все — час возни. При желании легко написать бота для slack который будет прямо в чате и искать через ES API.

          Если найду этот 10-строчник, поделюсь, самого сервиса давно нет.
            –1
            Говнокод! :(
              +1
              Вам шашечки или ехать?
              0
              Индексация только публичных групп и пониженный уровень токена только с необходимыми правами

              Т.е. поиск по приватным группам не производится?
                0
                1) Приватные группы по умолчанию не выгружаются при экспорте
                2) Не хочется брать на себя ответственность хранения чей то публичной переписки
                  0
                  1) А вообще таковая возможность имеется?

                  У нас бОльшая часть групп — приватные, поэтому это критичная фича.
                    0
                    Так же как и DM, а вот хранит ли это чудо именно direct message history? а то в моём случае только это и нужно
                      0
                      Оригинал хранит приватные группы. Можете посмотреть в его сторону https://github.com/snakazawa/slack-backup

                      Или посмотрите на один из проектов которые я в начале привел. Они чисто для личного использования скачивают. Просто очень скользкий момент хранения приватных сообщений без шифрования на сервере с доступом админа сервера.
                  0
                  Хочу пользоваться крутым но платным продуктом, а денег нет или не хочу платить, а тут еще есть аналоги бесплатные и жаба душит еще сильнее => надо хакнуть
                  Узнаю русского человека! )
                    0
                    Так никто не хакает ничего)
                    Никакие ограничения slack не обходятся. Просто используется его API для того чтобы хранить копию своих сообщений.

                    И это не только для бесплатности, но может быть использовано как бекап своих сообщений на черный день.
                      0
                      О как, а расскажите, пожалуйста, если не секрет, сами Вы много приобрели платных продуктов?

                      Пользоваться все хотят, купить или платить каждый месяц не все готовы, вполне понятно, что на бесплатных планах урезано всё, но никто и не говорит, что это плохо и надо «хакнуть», речь идёт о банальном хранении своей переписки, кому-то важно хранить всю хистори и лимита в 10к сообщений(или сколько там у слака на бесплатном плане) мало, вот народ и придумывает способы решить это.
                        0
                        Для личного использования я всё покупаю, для мобильного все за деньги, для мака всё за деньги, единственное пришлось отказаться от фотошопа и заменить его на Pixelmator. Есть разные подписки которые то же ежемесячно оплачиваются.

                        Вы просто путаете мои личные траты и траты на софт на работе где решают другие люди и лицензии стоят других денег.
                          0

                          Прошу прощения, если я Вас задел, мой комментарий был адресован stankevichEvg, а не Вам.


                          Я также разделяю Ваши взгляды о тратах "на работе" и "для себя", более того, у меня был опыт ещё более грустный работы в одной конторе: там юзалось исключительно всё бесплатное, чтобы не платить и из месенджеров юзался только скайп, а мне хотелось привнести в работу больше удобства: я загорелся настроить работу через хипчат/слак чтобы все уведомления с редмайна приходили в чат, чтобы все ошибки на проекте с sentry также прилетали в чат, чтобы с gitlab тоже всё прилетало в чат и чтобы деплой делался ботом =)


                          Заюзал я хипчат, как уже говорил, но тоже столкнулся с ограничением на бесплатном плане и мне его не хватало, а покупать за свои деньги аккаунт для конторы, я естественно, не буду.

                      0
                      Благодарю! Полезная фича для слака.
                      Осталось только разобраться с https в uwsgi.
                        0
                        http://uwsgi-docs.readthedocs.io/en/latest/HTTPS.html
                        Думаю можно так, но вообще для чего то серьезного лучше оставить в uwsgi только python, остальное вынести в nginx

                        Среди дальнейших шагов для улучшения безопасности в settings_local.py
                        • Нужно выключить дебаг (DEBUG=False)
                        • Заполнить ALLOWED_HOSTS
                        • Изменить SECRET_KEY
                        • Заполнить ADMINS

                        И установить fail2ban для веб сервера и ssh
                        0
                        Простите, а куда делся provisioning_on_amazonlinux.sh?
                        Вижу on_centos7, on_centos7_interactive, а также упоминание provisioning_on_amazonlinux.sh, но только в README.md
                          0
                          Удалил, так как не было возможности проверить самому. Как будет возможность протестирую и выложу.
                            0
                            Кстати, после мелких правок provisioning-скрипта завелось и под дебиан (правда без пакета uwsgi-router-http), по крону смотрю парсится раз в 5 минут, но у меня по наблюдениям история синхронизируется только через час, хотя по логам ошибок никаких не вываливается.
                            И кстати — большое спасибо за решение, понравилось и очень удобно.
                          0
                          Альтернатива — http://slackarchive.io/, бесплатный сервис хостинга архива. Но есть больше недостаточно — отсутствие аутентификации.
                            0
                            10. sudo ./provisioning_on_amazonlinux.sh

                            Во-первых, не provisioning_on_amazonlinux.sh, а provisioning_on_centos7.sh (та же ошибка в README). Но это мелочи.

                            11. Всё, после этого приложение запущено и доступно по вашему адресу, история синхронизируется раз в пять минут
                            12. Нужно зайти на сайт и предоставить доступ в свой аккаунт slack


                            Чего-то не работает. CentOS 7.2 на Азуре ( 3.10.0-327.36.3.el7.x86_64). Порт 80 открыт, но никто не отвечает.
                            При выполнении скрипта в конце пошли ошибки:
                            Complete!
                            Loaded plugins: fastestmirror, langpacks
                            Loading mirror speeds from cached hostfile
                            No package uwsgi available.
                            No package uwsgi-router-http available.
                            No package uwsgi-plugin-python available.
                            Error: Nothing to do
                            Cloning into 'slack-backup'...
                            remote: Counting objects: 368, done.
                            remote: Total 368 (delta 0), reused 0 (delta 0), pack-reused 368
                            Receiving objects: 100% (368/368), 260.74 KiB | 0 bytes/s, done.
                            Resolving deltas: 100% (220/220), done.
                            sudo: pip: command not found
                            Traceback (most recent call last):
                              File "manage.py", line 8, in <module>
                                from django.core.management import execute_from_command_line
                            ImportError: No module named django.core.management
                            Traceback (most recent call last):
                              File "manage.py", line 8, in <module>
                                from django.core.management import execute_from_command_line
                            ImportError: No module named django.core.management
                            Traceback (most recent call last):
                              File "manage.py", line 8, in <module>
                                from django.core.management import execute_from_command_line
                            ImportError: No module named django.core.management
                            Traceback (most recent call last):
                              File "manage.py", line 8, in <module>
                                from django.core.management import execute_from_command_line
                            ImportError: No module named django.core.management
                            Traceback (most recent call last):
                              File "manage.py", line 8, in <module>
                                from django.core.management import execute_from_command_line
                            ImportError: No module named django.core.management
                            FirewallD is not running
                            FirewallD is not running
                            sh: /usr/sbin/uwsgi: No such file or directory
                            
                              0
                              В общем сначала надо установить PIP:

                              curl "https://bootstrap.pypa.io/get-pip.py" -o "get-pip.py"
                              

                              python get-pip.py
                              


                              Но сильно лучше не стало.
                              Повторный запуск (после удаления папки /usr/local/src/slack-backup):
                              ошибки
                              Successfully installed django-emoji
                              Traceback (most recent call last):
                                File "manage.py", line 10, in <module>
                                  execute_from_command_line(sys.argv)
                                File "/usr/lib/python2.7/site-packages/django/core/management/__init__.py", line 367, in execute_from_command_line
                                  utility.execute()
                                File "/usr/lib/python2.7/site-packages/django/core/management/__init__.py", line 359, in execute
                                  self.fetch_command(subcommand).run_from_argv(self.argv)
                                File "/usr/lib/python2.7/site-packages/django/core/management/base.py", line 294, in run_from_argv
                                  self.execute(*args, **cmd_options)
                                File "/usr/lib/python2.7/site-packages/django/core/management/base.py", line 342, in execute
                                  self.check()
                                File "/usr/lib/python2.7/site-packages/django/core/management/base.py", line 374, in check
                                  include_deployment_checks=include_deployment_checks,
                                File "/usr/lib/python2.7/site-packages/django/core/management/base.py", line 361, in _run_checks
                                  return checks.run_checks(**kwargs)
                                File "/usr/lib/python2.7/site-packages/django/core/checks/registry.py", line 81, in run_checks
                                  new_errors = check(app_configs=app_configs)
                                File "/usr/lib/python2.7/site-packages/django/core/checks/urls.py", line 14, in check_url_config
                                  return check_resolver(resolver)
                                File "/usr/lib/python2.7/site-packages/django/core/checks/urls.py", line 24, in check_resolver
                                  for pattern in resolver.url_patterns:
                                File "/usr/lib/python2.7/site-packages/django/utils/functional.py", line 35, in __get__
                                  res = instance.__dict__[self.name] = self.func(instance)
                                File "/usr/lib/python2.7/site-packages/django/urls/resolvers.py", line 313, in url_patterns
                                  patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
                                File "/usr/lib/python2.7/site-packages/django/utils/functional.py", line 35, in __get__
                                  res = instance.__dict__[self.name] = self.func(instance)
                                File "/usr/lib/python2.7/site-packages/django/urls/resolvers.py", line 306, in urlconf_module
                                  return import_module(self.urlconf_name)
                                File "/usr/lib64/python2.7/importlib/__init__.py", line 37, in import_module
                                  __import__(name)
                                File "/usr/local/src/slack-backup/slackbackup/urls.py", line 15, in <module>
                                  url(r'^emoji/', include('emoji.urls')),
                                File "/usr/lib/python2.7/site-packages/django/conf/urls/__init__.py", line 50, in include
                                  urlconf_module = import_module(urlconf_module)
                                File "/usr/lib64/python2.7/importlib/__init__.py", line 37, in import_module
                                  __import__(name)
                              ImportError: No module named urls
                              Traceback (most recent call last):
                                File "manage.py", line 10, in <module>
                                  execute_from_command_line(sys.argv)
                                File "/usr/lib/python2.7/site-packages/django/core/management/__init__.py", line 367, in execute_from_command_line
                                  utility.execute()
                                File "/usr/lib/python2.7/site-packages/django/core/management/__init__.py", line 359, in execute
                                  self.fetch_command(subcommand).run_from_argv(self.argv)
                                File "/usr/lib/python2.7/site-packages/django/core/management/base.py", line 294, in run_from_argv
                                  self.execute(*args, **cmd_options)
                                File "/usr/lib/python2.7/site-packages/django/core/management/base.py", line 342, in execute
                                  self.check()
                                File "/usr/lib/python2.7/site-packages/django/core/management/base.py", line 374, in check
                                  include_deployment_checks=include_deployment_checks,
                                File "/usr/lib/python2.7/site-packages/django/core/management/commands/migrate.py", line 62, in _run_checks
                                  issues.extend(super(Command, self)._run_checks(**kwargs))
                                File "/usr/lib/python2.7/site-packages/django/core/management/base.py", line 361, in _run_checks
                                  return checks.run_checks(**kwargs)
                                File "/usr/lib/python2.7/site-packages/django/core/checks/registry.py", line 81, in run_checks
                                  new_errors = check(app_configs=app_configs)
                                File "/usr/lib/python2.7/site-packages/django/core/checks/urls.py", line 14, in check_url_config
                                  return check_resolver(resolver)
                                File "/usr/lib/python2.7/site-packages/django/core/checks/urls.py", line 24, in check_resolver
                                  for pattern in resolver.url_patterns:
                                File "/usr/lib/python2.7/site-packages/django/utils/functional.py", line 35, in __get__
                                  res = instance.__dict__[self.name] = self.func(instance)
                                File "/usr/lib/python2.7/site-packages/django/urls/resolvers.py", line 313, in url_patterns
                                  patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
                                File "/usr/lib/python2.7/site-packages/django/utils/functional.py", line 35, in __get__
                                  res = instance.__dict__[self.name] = self.func(instance)
                                File "/usr/lib/python2.7/site-packages/django/urls/resolvers.py", line 306, in urlconf_module
                                  return import_module(self.urlconf_name)
                                File "/usr/lib64/python2.7/importlib/__init__.py", line 37, in import_module
                                  __import__(name)
                                File "/usr/local/src/slack-backup/slackbackup/urls.py", line 15, in <module>
                                  url(r'^emoji/', include('emoji.urls')),
                                File "/usr/lib/python2.7/site-packages/django/conf/urls/__init__.py", line 50, in include
                                  urlconf_module = import_module(urlconf_module)
                                File "/usr/lib64/python2.7/importlib/__init__.py", line 37, in import_module
                                  __import__(name)
                              ImportError: No module named urls
                              Traceback (most recent call last):
                                File "manage.py", line 10, in <module>
                                  execute_from_command_line(sys.argv)
                                File "/usr/lib/python2.7/site-packages/django/core/management/__init__.py", line 367, in execute_from_command_line
                                  utility.execute()
                                File "/usr/lib/python2.7/site-packages/django/core/management/__init__.py", line 359, in execute
                                  self.fetch_command(subcommand).run_from_argv(self.argv)
                                File "/usr/lib/python2.7/site-packages/django/core/management/base.py", line 294, in run_from_argv
                                  self.execute(*args, **cmd_options)
                                File "/usr/lib/python2.7/site-packages/django/core/management/base.py", line 342, in execute
                                  self.check()
                                File "/usr/lib/python2.7/site-packages/django/core/management/base.py", line 374, in check
                                  include_deployment_checks=include_deployment_checks,
                                File "/usr/lib/python2.7/site-packages/django/core/management/base.py", line 361, in _run_checks
                                  return checks.run_checks(**kwargs)
                                File "/usr/lib/python2.7/site-packages/django/core/checks/registry.py", line 81, in run_checks
                                  new_errors = check(app_configs=app_configs)
                                File "/usr/lib/python2.7/site-packages/django/core/checks/urls.py", line 14, in check_url_config
                                  return check_resolver(resolver)
                                File "/usr/lib/python2.7/site-packages/django/core/checks/urls.py", line 24, in check_resolver
                                  for pattern in resolver.url_patterns:
                                File "/usr/lib/python2.7/site-packages/django/utils/functional.py", line 35, in __get__
                                  res = instance.__dict__[self.name] = self.func(instance)
                                File "/usr/lib/python2.7/site-packages/django/urls/resolvers.py", line 313, in url_patterns
                                  patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
                                File "/usr/lib/python2.7/site-packages/django/utils/functional.py", line 35, in __get__
                                  res = instance.__dict__[self.name] = self.func(instance)
                                File "/usr/lib/python2.7/site-packages/django/urls/resolvers.py", line 306, in urlconf_module
                                  return import_module(self.urlconf_name)
                                File "/usr/lib64/python2.7/importlib/__init__.py", line 37, in import_module
                                  __import__(name)
                                File "/usr/local/src/slack-backup/slackbackup/urls.py", line 15, in <module>
                                  url(r'^emoji/', include('emoji.urls')),
                                File "/usr/lib/python2.7/site-packages/django/conf/urls/__init__.py", line 50, in include
                                  urlconf_module = import_module(urlconf_module)
                                File "/usr/lib64/python2.7/importlib/__init__.py", line 37, in import_module
                                  __import__(name)
                              ImportError: No module named urls
                              Traceback (most recent call last):
                                File "manage.py", line 10, in <module>
                                  execute_from_command_line(sys.argv)
                                File "/usr/lib/python2.7/site-packages/django/core/management/__init__.py", line 367, in execute_from_command_line
                                  utility.execute()
                                File "/usr/lib/python2.7/site-packages/django/core/management/__init__.py", line 359, in execute
                                  self.fetch_command(subcommand).run_from_argv(self.argv)
                                File "/usr/lib/python2.7/site-packages/django/core/management/base.py", line 294, in run_from_argv
                                  self.execute(*args, **cmd_options)
                                File "/usr/lib/python2.7/site-packages/django/core/management/base.py", line 342, in execute
                                  self.check()
                                File "/usr/lib/python2.7/site-packages/django/core/management/base.py", line 374, in check
                                  include_deployment_checks=include_deployment_checks,
                                File "/usr/lib/python2.7/site-packages/django/core/management/base.py", line 361, in _run_checks
                                  return checks.run_checks(**kwargs)
                                File "/usr/lib/python2.7/site-packages/django/core/checks/registry.py", line 81, in run_checks
                                  new_errors = check(app_configs=app_configs)
                                File "/usr/lib/python2.7/site-packages/django/core/checks/urls.py", line 14, in check_url_config
                                  return check_resolver(resolver)
                                File "/usr/lib/python2.7/site-packages/django/core/checks/urls.py", line 24, in check_resolver
                                  for pattern in resolver.url_patterns:
                                File "/usr/lib/python2.7/site-packages/django/utils/functional.py", line 35, in __get__
                                  res = instance.__dict__[self.name] = self.func(instance)
                                File "/usr/lib/python2.7/site-packages/django/urls/resolvers.py", line 313, in url_patterns
                                  patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
                                File "/usr/lib/python2.7/site-packages/django/utils/functional.py", line 35, in __get__
                                  res = instance.__dict__[self.name] = self.func(instance)
                                File "/usr/lib/python2.7/site-packages/django/urls/resolvers.py", line 306, in urlconf_module
                                  return import_module(self.urlconf_name)
                                File "/usr/lib64/python2.7/importlib/__init__.py", line 37, in import_module
                                  __import__(name)
                                File "/usr/local/src/slack-backup/slackbackup/urls.py", line 15, in <module>
                                  url(r'^emoji/', include('emoji.urls')),
                                File "/usr/lib/python2.7/site-packages/django/conf/urls/__init__.py", line 50, in include
                                  urlconf_module = import_module(urlconf_module)
                                File "/usr/lib64/python2.7/importlib/__init__.py", line 37, in import_module
                                  __import__(name)
                              ImportError: No module named urls
                              


                              Т.е.: ImportError: No module named urls

                              Ну и «FirewallD is not running» остались.

                              enemy_spb есть идеи?
                                0
                                За это время могли поменяться зависимости. Как будет время постараюсь перепроверить.

                            Only users with full accounts can post comments. Log in, please.