From 7174ad650c37bb7afd7d88df404e35ff80375659 Mon Sep 17 00:00:00 2001 From: Dmitry Novikov Date: Wed, 10 Apr 2019 17:30:21 +0300 Subject: [PATCH] messanger update --- agent/monitoring_agent.py | 5 +- devapp/views.py | 4 +- docs/notifications.md | 15 +++ messenger/locale/ru/LC_MESSAGES/django.po | 107 ++++++++++-------- messenger/models.py | 11 +- messenger/tasks.py | 8 +- .../templates/messenger/messenger_list.html | 13 ++- .../messenger/vibermessenger_form.html | 2 - .../messenger/vibersubscriber_list.html | 41 +++++++ messenger/urls.py | 11 +- messenger/views.py | 45 +++++--- taskapp/handle.py | 4 +- 12 files changed, 180 insertions(+), 86 deletions(-) mode change 100644 => 100755 agent/monitoring_agent.py create mode 100644 docs/notifications.md create mode 100644 messenger/templates/messenger/vibersubscriber_list.html diff --git a/agent/monitoring_agent.py b/agent/monitoring_agent.py old mode 100644 new mode 100755 index bc99216..a3eda3e --- a/agent/monitoring_agent.py +++ b/agent/monitoring_agent.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 import sys import re +import os from hashlib import sha256 from typing import Iterable, Union, AnyStr @@ -8,7 +9,7 @@ import requests API_AUTH_SECRET = 'your api key' -SERVER_DOMAIN = 'http://localhost:8000' +SERVER_DOMAIN = 'http://127.0.0.1:8000' MAC_ADDR_REGEX = r'^([0-9A-Fa-f]{1,2}[:-]){5}([0-9A-Fa-f]{1,2})$' @@ -41,7 +42,7 @@ def validate_status(text: str): def send_request(mac, stat, sign_hash): r = requests.get( - "%(domain)s/dev/on_device_event/" % {'domain': SERVER_DOMAIN}, + os.path.join(SERVER_DOMAIN, 'dev', 'on_device_event'), params={ 'mac': mac, 'status': stat, diff --git a/devapp/views.py b/devapp/views.py index 707168e..c37a46a 100644 --- a/devapp/views.py +++ b/devapp/views.py @@ -18,7 +18,7 @@ from djing.lib import safe_int, ProcessLocked, DuplicateEntry from djing.lib.decorators import json_view from djing.lib.decorators import only_admins, hash_auth_view from djing.lib.mixins import LoginAdminPermissionMixin, LoginAdminMixin -from djing.tasks import multicast_email_notify +# from djing.tasks import multicast_email_notify from easysnmp import EasySNMPTimeoutError, EasySNMPError from group_app.models import Group from abonapp.models import Abon @@ -772,7 +772,7 @@ class OnDeviceMonitoringEvent(global_base_views.SecureApiView): device_down.comment ) } - multicast_email_notify.delay(msg_text=text, account_ids=user_ids) + #multicast_email_notify.delay(msg_text=text, account_ids=user_ids) multicast_viber_notify.delay(None, account_id_list=user_ids, message_text=text) return { 'text': 'notification successfully sent' diff --git a/docs/notifications.md b/docs/notifications.md new file mode 100644 index 0000000..afc91ce --- /dev/null +++ b/docs/notifications.md @@ -0,0 +1,15 @@ +### Подключение мониторинга +Для того чтобы отправлять события из мониторинга в биллинг можно воспользоваться скриптом **agent/monitoring_agent.py**. +Скопируйте его в место, откуда он будет доступен мониторингу, задайте права, сделайте исполняемым. Так же его надо +отредактировать, 2 параметра: *API_AUTH_SECRET* и *SERVER_DOMAIN*. + +**API_AUTH_SECRET** — Параметр с таким же именем есть в настройках биллинга, это секретное слово для авторизации +скриптов, сгенерируйте секретное слово посложнее если сами настраивайте весь биллинг или узнайте его в настройках +биллинга если оно уже есть. + +**SERVER_DOMAIN** — Полный url к биллингу по http\[s\]. + +Скрипт отправляет *HTTP GET* запросы с параметрами, например: +http://domain/dev/on_device_event/?mac=ff:ff:ff:ff:ff:ff&status=\[UP|DOWN|UNREACHABLE\]&sign=\. + +После этого биллинг отмечает состояние устройства и рассылает оповещения для тех у кого эти оповещения включены. diff --git a/messenger/locale/ru/LC_MESSAGES/django.po b/messenger/locale/ru/LC_MESSAGES/django.po index 951a44d..cffa517 100644 --- a/messenger/locale/ru/LC_MESSAGES/django.po +++ b/messenger/locale/ru/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-02-06 13:45+0300\n" +"POT-Creation-Date: 2019-04-10 17:28+0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Dmitry Novikov nerosketch@gmail.com\n" "Language: ru\n" @@ -18,89 +18,92 @@ msgstr "" "%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n" "%100>=11 && n%100<=14)? 2 : 3);\n" -#: models.py:16 templates/messenger/messenger_list.html:20 +#: models.py:15 templates/messenger/messenger_list.html:20 msgid "Title" msgstr "Название" -#: models.py:18 +#: models.py:17 msgid "Viber" msgstr "Вайбер" -#: models.py:20 +#: models.py:19 msgid "Bot type" msgstr "Тип бота" -#: models.py:21 templates/messenger/messenger_list.html:22 +#: models.py:20 templates/messenger/messenger_list.html:22 msgid "Slug" msgstr "Ссыль" -#: models.py:28 models.py:92 +#: models.py:27 models.py:109 msgid "messenger" msgstr "Мэссенджер" -#: models.py:29 templates/messenger/messenger_list.html:7 +#: models.py:28 templates/messenger/messenger_list.html:7 #: templates/messenger/messenger_list.html:12 #: templates/messenger/vibermessenger_form.html:8 +#: templates/messenger/vibersubscriber_list.html:7 msgid "Messengers" msgstr "Мэссенджэры" -#: models.py:48 +#: models.py:47 msgid "Bot secret token" msgstr "Секретный токен viber" -#: models.py:49 models.py:108 +#: models.py:48 models.py:125 msgid "Avatar" msgstr "Аватар" -#: models.py:83 +#: models.py:100 msgid "Viber messenger" msgstr "Viber мэссенджэр" -#: models.py:84 +#: models.py:101 msgid "Viber messengers" msgstr "Viber мэссенджэры" -#: models.py:89 +#: models.py:106 msgid "Message" msgstr "Сообщение" -#: models.py:90 +#: models.py:107 msgid "Date" msgstr "Дата" -#: models.py:91 +#: models.py:108 msgid "Sender" msgstr "Отправитель" -#: models.py:93 +#: models.py:110 msgid "Subscriber" msgstr "Подписчик" -#: models.py:100 +#: models.py:117 msgid "Viber message" msgstr "Сообщение viber" -#: models.py:101 +#: models.py:118 msgid "Viber messages" msgstr "Сообщения viber" -#: models.py:106 +#: models.py:123 msgid "User unique id in viber" msgstr "Уникальный id viber" -#: models.py:107 +#: models.py:124 templates/messenger/vibersubscriber_list.html:22 msgid "Name" msgstr "Имя" -#: models.py:109 +#: models.py:126 msgid "System account" msgstr "Системная учётная запись" -#: models.py:116 +#: models.py:133 msgid "Viber subscriber" msgstr "Подписчик viber" -#: models.py:117 +#: models.py:134 templates/messenger/messenger_list.html:37 +#: templates/messenger/vibersubscriber_list.html:8 +#: templates/messenger/vibersubscriber_list.html:13 msgid "Viber subscribers" msgstr "Подписчики viber" @@ -116,75 +119,83 @@ msgstr "Добавить" msgid "Type" msgstr "Тип" -#: templates/messenger/messenger_list.html:33 +#: templates/messenger/messenger_list.html:34 msgid "Edit" msgstr "Изменить" -#: templates/messenger/messenger_list.html:40 -msgid "messengers was not found" +#: templates/messenger/messenger_list.html:45 +msgid "Messengers was not found" msgstr "Мэссенджеры не найдены" -#: templates/messenger/messenger_list.html:49 +#: templates/messenger/messenger_list.html:54 msgid "New" msgstr "Новый" #: templates/messenger/vibermessenger_form.html:10 -msgid "Update messenger" -msgstr "Обновить мэссенджэр" - -#: templates/messenger/vibermessenger_form.html:11 msgid "Change viber" msgstr "Изменить viber" -#: templates/messenger/vibermessenger_form.html:13 -msgid "Add messenger" -msgstr "Добавить мэссенджэр" - -#: templates/messenger/vibermessenger_form.html:14 +#: templates/messenger/vibermessenger_form.html:12 msgid "Add viber" msgstr "Добавить viber" -#: templates/messenger/vibermessenger_form.html:25 +#: templates/messenger/vibermessenger_form.html:23 msgid "Change messenger" msgstr "Изменить мэссенджэр" -#: templates/messenger/vibermessenger_form.html:28 +#: templates/messenger/vibermessenger_form.html:26 msgid "Add new messenger" msgstr "Добавить мэссенджэр" -#: templates/messenger/vibermessenger_form.html:39 +#: templates/messenger/vibermessenger_form.html:37 msgid "Save" msgstr "Сохранить" -#: templates/messenger/vibermessenger_form.html:43 +#: templates/messenger/vibermessenger_form.html:41 msgid "Send webhook" msgstr "Отправить webhook" -#: views.py:38 +#: templates/messenger/vibersubscriber_list.html:21 +msgid "uid" +msgstr "" + +#: templates/messenger/vibersubscriber_list.html:23 +msgid "Account" +msgstr "Учётка" + +#: templates/messenger/vibersubscriber_list.html:35 +msgid "Subscribers was not found" +msgstr "Подписчики не найдены" + +#: views.py:36 msgid "Unexpected bot type" msgstr "Не известный тип бота" -#: views.py:51 +#: views.py:49 msgid "New viber messenger successfully created" msgstr "Новый viber мэссенджэр успешно создан" -#: views.py:62 +#: views.py:60 msgid "Viber messenger successfully updated" msgstr "viber мэссенджэр успешно обновлён" -#: views.py:73 +#: views.py:71 msgid "Viber messenger successfully deleted" msgstr "viber мэссенджэр успешно удалён" -#: views.py:132 +#: views.py:125 msgid "My telephone number" msgstr "Мой номер телефона" -#: views.py:150 +#: views.py:148 +msgid "" +"Your account is attached. Now you will be receive notifications from billing" +msgstr "" +"Ваша учётка из биллинга привязана. Теперь вы будете получать оповещения из " +"биллинга." + +#: views.py:152 msgid "" "Telephone not found, please specify telephone number in account in billing" msgstr "" "Номер телефона не найден. Укажите свой номер телефона в учётке в биллинге" - -msgid "Your account is attached. Now you will be receive notifications from billing" -msgstr "Ваша учётка из биллинга привязана. Теперь вы будете получать оповещения из биллинга." diff --git a/messenger/models.py b/messenger/models.py index 685aad2..499a668 100644 --- a/messenger/models.py +++ b/messenger/models.py @@ -56,7 +56,7 @@ class ViberMessenger(Messenger): )) return self._viber_cache - def send_message(self, to: UserProfile, msg): + def send_message_to_acc(self, to: UserProfile, msg): try: viber = self.get_viber() vs = to.vibersubscriber @@ -67,7 +67,7 @@ class ViberMessenger(Messenger): except ViberSubscriber.DoesNotExist: pass - def send_messages(self, receivers, msg_text: str): + def send_message_to_accs(self, receivers, msg_text: str): """ :param receivers: QuerySet of accounts_app.UserProfile :param msg_text: text message @@ -78,6 +78,13 @@ class ViberMessenger(Messenger): for vs in ViberSubscriber.objects.filter(account__in=receivers).iterator(): viber.send_messages(str(vs.uid), msg) + def send_message_to_id(self, subscriber_id: str, msg): + viber = self.get_viber() + if issubclass(msg.__class__, Message): + viber.send_messages(subscriber_id, msg) + else: + viber.send_messages(subscriber_id, TextMessage(text=msg)) + def send_webhook(self): pub_url = getattr(settings, 'VIBER_BOT_PUBLIC_URL') listen_url = resolve_url('messenger:listen_viber_bot', self.slug) diff --git a/messenger/tasks.py b/messenger/tasks.py index 39f103f..af756df 100644 --- a/messenger/tasks.py +++ b/messenger/tasks.py @@ -21,10 +21,10 @@ def send_viber_message(messenger_id: Optional[int], account_id: int, message_tex sp = UserProfile.objects.get(pk=account_id) if messenger_id is None: for vm in ViberMessenger.objects.all().iterator(): - vm.send_message(sp, message_text) + vm.send_message_to_acc(sp, message_text) else: vm = ViberMessenger.objects.get(pk=messenger_id) - vm.send_message(sp, message_text) + vm.send_message_to_acc(sp, message_text) except ViberMessenger.DoesNotExist: return 'ERROR: Viber messanger with id=%d not found' % messenger_id except UserProfile.DoesNotExist: @@ -48,9 +48,9 @@ def multicast_viber_notify(messenger_id: Optional[int], account_id_list: Iterabl return 'No recipients found from ids: %s' % ','.join(str(i) for i in account_id_list) if messenger_id is None: for vm in ViberMessenger.objects.all().iterator(): - vm.send_messages(recipients, message_text) + vm.send_message_to_accs(recipients, message_text) else: vm = ViberMessenger.objects.filter(pk=messenger_id).first() if vm is None: return 'ERROR ViberMessenger with pk=%d does not exist' % messenger_id - vm.send_messages(recipients, message_text) + vm.send_message_to_accs(recipients, message_text) diff --git a/messenger/templates/messenger/messenger_list.html b/messenger/templates/messenger/messenger_list.html index 1495ae4..d51cfcb 100644 --- a/messenger/templates/messenger/messenger_list.html +++ b/messenger/templates/messenger/messenger_list.html @@ -30,14 +30,19 @@ {{ messenger.get_bot_type_display }} {{ messenger.slug }} - - - + {% empty %} - {% trans 'messengers was not found' %} + {% trans 'Messengers was not found' %} {% endfor %} diff --git a/messenger/templates/messenger/vibermessenger_form.html b/messenger/templates/messenger/vibermessenger_form.html index 888f1ce..aeab30b 100644 --- a/messenger/templates/messenger/vibermessenger_form.html +++ b/messenger/templates/messenger/vibermessenger_form.html @@ -7,10 +7,8 @@
  • {% trans 'Messengers' %}
  • {% if object %} -
  • {% trans 'Update messenger' %}
  • {% trans 'Change viber' %}
  • {% else %} -
  • {% trans 'Add messenger' %}
  • {% trans 'Add viber' %}
  • {% endif %} diff --git a/messenger/templates/messenger/vibersubscriber_list.html b/messenger/templates/messenger/vibersubscriber_list.html new file mode 100644 index 0000000..3562115 --- /dev/null +++ b/messenger/templates/messenger/vibersubscriber_list.html @@ -0,0 +1,41 @@ +{% extends 'base.html' %} +{% load dpagination i18n %} + +{% block breadcrumb %} + +{% endblock %} + +{% block page-header %} + {% trans 'Viber subscribers' %} +{% endblock %} + +{% block main %} +
    + + + + + + + + + + {% for subscriber in object_list %} + + + + + + {% empty %} + + + + {% endfor %} + +
    {% trans 'uid' %}{% trans 'Name' %}{% trans 'Account' %}
    {{ subscriber.uid }}{{ subscriber.name }}{{ subscriber.account.get_full_name }}
    {% trans 'Subscribers was not found' %}
    +
    +{% endblock %} diff --git a/messenger/urls.py b/messenger/urls.py index 46acab3..63fa53a 100644 --- a/messenger/urls.py +++ b/messenger/urls.py @@ -7,11 +7,12 @@ from messenger import views app_name = 'messenger' urlpatterns = [ - path('', views.messengerListView.as_view(), name='messengers_list'), - path('new/', views.AddmessengerCreateView.as_view(), name='add_messenger'), - path('viber/new/', views.AddmessengerViberCreateView.as_view(), name='add_viber_messenger'), - path('viber//update/', views.UpdateVibermessengerUpdateView.as_view(), name='update_viber_messenger'), - path('viber//delete/', views.RemoveVibermessengerDeleteView.as_view(), name='delete_viber_messenger'), + path('', views.MessengerListView.as_view(), name='messengers_list'), + path('new/', views.AddMessengerCreateView.as_view(), name='add_messenger'), + path('viber/new/', views.AddMessengerViberCreateView.as_view(), name='add_viber_messenger'), + path('viber//update/', views.UpdateViberMessengerUpdateView.as_view(), name='update_viber_messenger'), + path('viber//delete/', views.RemoveViberMessengerDeleteView.as_view(), name='delete_viber_messenger'), path('viber//listen/', csrf_exempt(views.ListenViberView.as_view()), name='listen_viber_bot'), path('viber//set_webhook/', views.SetWebhook.as_view(), name='webhook_viber_bot'), + path('viber//subscribers/', views.SubscribersListView.as_view(), name='subscribers'), ] diff --git a/messenger/views.py b/messenger/views.py index c5f6cf6..1283ea4 100644 --- a/messenger/views.py +++ b/messenger/views.py @@ -3,9 +3,7 @@ from django.contrib.auth.mixins import PermissionRequiredMixin from django.http import HttpResponseForbidden, HttpResponse, HttpResponseNotFound from django.shortcuts import resolve_url from django.urls import reverse_lazy -from django.utils.decorators import method_decorator from django.utils.translation import gettext_lazy as _, gettext -from django.views.decorators.csrf import csrf_exempt from django.views.generic import ListView, CreateView, UpdateView, DeleteView, FormView, View from django.views.generic.detail import SingleObjectMixin from viberbot.api.messages import KeyboardMessage, ContactMessage @@ -20,12 +18,12 @@ from messenger import forms, models from messenger.models import ViberMessage, ViberSubscriber -class messengerListView(LoginAdminPermissionMixin, ListView): +class MessengerListView(LoginAdminPermissionMixin, ListView): model = models.Messenger permission_required = 'messenger.view_messenger' -class AddmessengerCreateView(LoginAdminMixin, FormView): +class AddMessengerCreateView(LoginAdminMixin, FormView): template_name = 'messenger/add_messenger.html' form_class = forms.MessengerForm @@ -40,7 +38,7 @@ class AddmessengerCreateView(LoginAdminMixin, FormView): return super().form_valid(form) -class AddmessengerViberCreateView(LoginAdminMixin, PermissionRequiredMixin, CreateView): +class AddMessengerViberCreateView(LoginAdminMixin, PermissionRequiredMixin, CreateView): model = models.ViberMessenger form_class = forms.MessengerViberForm permission_required = 'messenger.add_vibermessenger' @@ -52,7 +50,7 @@ class AddmessengerViberCreateView(LoginAdminMixin, PermissionRequiredMixin, Crea return r -class UpdateVibermessengerUpdateView(LoginAdminPermissionMixin, UpdateView): +class UpdateViberMessengerUpdateView(LoginAdminPermissionMixin, UpdateView): model = models.ViberMessenger form_class = forms.MessengerViberForm permission_required = 'messenger.change_vibermessenger' @@ -63,7 +61,7 @@ class UpdateVibermessengerUpdateView(LoginAdminPermissionMixin, UpdateView): return r -class RemoveVibermessengerDeleteView(LoginAdminPermissionMixin, DeleteView): +class RemoveViberMessengerDeleteView(LoginAdminPermissionMixin, DeleteView): model = models.ViberMessenger permission_required = 'messenger.delete_vibermessenger' success_url = reverse_lazy('messenger:messengers_list') @@ -74,7 +72,6 @@ class RemoveVibermessengerDeleteView(LoginAdminPermissionMixin, DeleteView): return r -@method_decorator(csrf_exempt, name='post') class ListenViberView(SingleObjectMixin, View): http_method_names = 'post', model = models.ViberMessenger @@ -87,7 +84,6 @@ class ListenViberView(SingleObjectMixin, View): viber = obj.get_viber() if not viber.verify_signature(request.body, request.META.get('HTTP_X_VIBER_CONTENT_SIGNATURE')): return HttpResponseForbidden() - # this library supplies a simple way to receive a request object vr = viber.parse_request(request.body) if isinstance(vr, ViberMessageRequest): in_msg = vr.message @@ -131,22 +127,30 @@ class ListenViberView(SingleObjectMixin, View): },) }, min_api_version=3) viber = self.object.get_viber() - viber.send_messages(viber_user_profile.id, msg) + viber.send_message_to_id(viber_user_profile.id, msg) return subscriber, created def inbox_contact(self, msg, sender: ViberUserProfile): tel = msg.contact.phone_number accs = UserProfile.objects.filter(telephone__icontains=tel) - viber = self.object.get_viber() + viber = self.object if accs.exists(): + first_acc = accs.first() subs = ViberSubscriber.objects.filter(uid=sender.id) - if subs.exists(): - subs.update(account=accs.first()) - viber.send_messages(sender.id, gettext( + subs_len = subs.count() + if subs_len > 0: + first_sub = subs.first() + if subs_len > 1: + ViberSubscriber.objects.exclude(pk=first_sub.pk).delete() + first_sub.account = first_acc + first_sub.save(update_fields=('account',)) + viber.send_message_to_acc(first_acc, gettext( 'Your account is attached. Now you will be receive notifications from billing' )) else: - viber.send_messages(sender.id, gettext('Telephone not found, please specify telephone number in account in billing')) + viber.send_message_to_id(sender.id, gettext( + 'Telephone not found, please specify telephone number in account in billing' + )) class SetWebhook(LoginAdminMixin, SingleObjectMixin, View): @@ -159,3 +163,14 @@ class SetWebhook(LoginAdminMixin, SingleObjectMixin, View): return HttpResponseNotFound obj.send_webhook() return HttpResponse(b'ok', status=200) + + +class SubscribersListView(LoginAdminMixin, ListView): + model = models.ViberSubscriber + + def get_context_data(self, **kwargs): + context = { + 'messanger_slug': self.kwargs.get('slug') + } + context.update(kwargs) + return super().get_context_data(**context) diff --git a/taskapp/handle.py b/taskapp/handle.py index 2285258..18e8618 100644 --- a/taskapp/handle.py +++ b/taskapp/handle.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from django.template.loader import render_to_string from django.utils.translation import gettext as _ -from djing.tasks import send_email_notify, multicast_email_notify +from djing.tasks import send_email_notify # , multicast_email_notify from messenger.tasks import multicast_viber_notify, send_viber_message @@ -36,5 +36,5 @@ def handle(task, author, recipients): send_email_notify.delay(fulltext, author.pk) send_viber_message.delay(None, author.pk, fulltext) else: - multicast_email_notify.delay(fulltext, profile_ids) + #multicast_email_notify.delay(fulltext, profile_ids) multicast_viber_notify.delay(None, profile_ids, fulltext)