41 changed files with 886 additions and 610 deletions
-
6chatbot/admin.py
-
5chatbot/apps.py
-
112chatbot/locale/ru/LC_MESSAGES/django.po
-
64chatbot/migrations/0001_initial.py
-
27chatbot/migrations/0002_auto_20180808_1236.py
-
0chatbot/migrations/__init__.py
-
73chatbot/models.py
-
149chatbot/telebot.py
-
3chatbot/views.py
-
2devapp/locale/ru/LC_MESSAGES/django.po
-
16devapp/views.py
-
20djing/lib/decorators.py
-
3djing/local_settings.py.template
-
7djing/settings.py
-
1djing/urls.py
-
1messenger/__init__.py
-
7messenger/admin.py
-
5messenger/apps.py
-
28messenger/forms.py
-
190messenger/locale/ru/LC_MESSAGES/django.po
-
88messenger/migrations/0001_initial.py
-
0messenger/migrations/__init__.py
-
129messenger/models.py
-
56messenger/tasks.py
-
15messenger/templates/messenger/add_messenger.html
-
57messenger/templates/messenger/messenger_list.html
-
49messenger/templates/messenger/vibermessenger_form.html
-
3messenger/tests.py
-
17messenger/urls.py
-
161messenger/views.py
-
4msg_app/models.py
-
3msg_app/urls.py
-
22msg_app/views.py
-
7requirements.txt
-
4static/js/my.js
-
15systemd_units/djing_telebot.service
-
23taskapp/handle.py
-
3taskapp/urls.py
-
21taskapp/views.py
-
29telebot.py
-
9templates/base.html
@ -1,6 +0,0 @@ |
|||
from django.contrib import admin |
|||
from . import models |
|||
|
|||
admin.site.register(models.MessageHistory) |
|||
admin.site.register(models.TelegramBot) |
|||
admin.site.register(models.MessageQueue) |
|||
@ -1,5 +0,0 @@ |
|||
from django.apps import AppConfig |
|||
|
|||
|
|||
class ChatbotConfig(AppConfig): |
|||
name = 'chatbot' |
|||
@ -1,112 +0,0 @@ |
|||
# SOME DESCRIPTIVE TITLE. |
|||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
|||
# This file is distributed under the same license as the PACKAGE package. |
|||
# Dmitry Novikov <nerosketch@gmail.com>, 2017. |
|||
# |
|||
#, fuzzy |
|||
msgid "" |
|||
msgstr "" |
|||
"Project-Id-Version: PACKAGE VERSION\n" |
|||
"Report-Msgid-Bugs-To: \n" |
|||
"POT-Creation-Date: 2018-08-09 14:57+0300\n" |
|||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" |
|||
"Last-Translator: Dmitry Novikov <nerosketch@gmail.com>\n" |
|||
"Language-Team: LANGUAGE <LL@li.org>\n" |
|||
"Language: \n" |
|||
"MIME-Version: 1.0\n" |
|||
"Content-Type: text/plain; charset=UTF-8\n" |
|||
"Content-Transfer-Encoding: 8bit\n" |
|||
"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" |
|||
"%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:13 |
|||
msgid "Employee" |
|||
msgstr "Сотрудник" |
|||
|
|||
#: models.py:14 |
|||
msgid "Telegram chat id" |
|||
msgstr "Номер чата из telegram" |
|||
|
|||
#: models.py:21 |
|||
msgid "Telegram bot" |
|||
msgstr "Telegram бот" |
|||
|
|||
#: models.py:22 |
|||
msgid "Telegram bots" |
|||
msgstr "Telegram боты" |
|||
|
|||
#: models.py:36 |
|||
msgid "Message history" |
|||
msgstr "История собщений" |
|||
|
|||
#: models.py:37 |
|||
msgid "Message histories" |
|||
msgstr "Истории собщений" |
|||
|
|||
#: models.py:54 |
|||
msgid "Target employee" |
|||
msgstr "Сотрудник" |
|||
|
|||
#: models.py:55 |
|||
msgid "Message" |
|||
msgstr "Сообщение" |
|||
|
|||
#: models.py:60 |
|||
msgid "Status of message" |
|||
msgstr "Статус сообщения" |
|||
|
|||
#: models.py:62 |
|||
msgid "App tag" |
|||
msgstr "Тэг приложения" |
|||
|
|||
#: models.py:71 models.py:72 |
|||
msgid "Message queue" |
|||
msgstr "Очередь оповещений" |
|||
|
|||
#: telebot.py:64 |
|||
msgid "Let's get acquainted, what is your name? Write your login from billing." |
|||
msgstr "Давай знакомиться, как тебя зовут? Напиши свой логин из биллинга." |
|||
|
|||
#: telebot.py:85 |
|||
msgid "I do not know the answer to this yet." |
|||
msgstr "Я пока не знаю ответа на это" |
|||
|
|||
#: telebot.py:106 |
|||
msgid "" |
|||
"You are not found in the database, check that it correctly pointed out its " |
|||
"LOGIN. Try again" |
|||
msgstr "" |
|||
"Ты не найден в базе, проверь что правильно указал именно свой ЛОГИН. " |
|||
"Попробуй ещё" |
|||
|
|||
#: telebot.py:110 |
|||
#, python-format |
|||
msgid "" |
|||
"Yes, it's nice to meet %(username)s, I will notify you about events in " |
|||
"billing. Successful work ;)" |
|||
msgstr "" |
|||
"Да, приятно познакомиться %(username)s, я буду оповещать тебя о событиях в " |
|||
"биллинге. Удачной работы ;)" |
|||
|
|||
#: telebot.py:122 |
|||
msgid "Let's ping, write ip. It will be necessary to wait 10 seconds" |
|||
msgstr "Давай пинганём, напиши ip. Нужно будет подождать 10 сек" |
|||
|
|||
#: telebot.py:129 |
|||
msgid "It's not like ip address, try again" |
|||
msgstr "Это не похоже на ip адрес, попробуй ещё" |
|||
|
|||
#: telebot.py:132 |
|||
#, python-format |
|||
msgid "You're '%s', right?" |
|||
msgstr "Ты ведь %s ?" |
|||
|
|||
#: telebot.py:140 |
|||
msgid "Telegram bot token not found" |
|||
msgstr "Токен для бота Telegram не найден" |
|||
|
|||
#: telebot.py:145 |
|||
#, python-format |
|||
msgid "Recipient '%s' does not subscribed on notifications" |
|||
msgstr "%s не подписан на оповещения" |
|||
@ -1,64 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Generated by Django 1.11 on 2018-02-26 00:20 |
|||
from __future__ import unicode_literals |
|||
|
|||
from django.conf import settings |
|||
from django.db import migrations, models |
|||
import django.db.models.deletion |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
initial = True |
|||
|
|||
dependencies = [ |
|||
migrations.swappable_dependency(settings.AUTH_USER_MODEL), |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.CreateModel( |
|||
name='MessageHistory', |
|||
fields=[ |
|||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
|||
('message', models.CharField(max_length=255)), |
|||
('date_sent', models.DateTimeField(auto_now_add=True)), |
|||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), |
|||
], |
|||
options={ |
|||
'verbose_name': 'Message history', |
|||
'verbose_name_plural': 'Message histories', |
|||
'db_table': 'chat_message_history', |
|||
}, |
|||
), |
|||
migrations.CreateModel( |
|||
name='MessageQueue', |
|||
fields=[ |
|||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
|||
('message', models.CharField(max_length=255, verbose_name='Message')), |
|||
('status', models.CharField(choices=[('n', 'New'), ('r', 'Read')], default='n', max_length=1, |
|||
verbose_name='Status of message')), |
|||
('tag', models.CharField(default='none', max_length=6, verbose_name='App tag')), |
|||
('target_employee', |
|||
models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, |
|||
verbose_name='Target employee')), |
|||
], |
|||
options={ |
|||
'verbose_name': 'Message queue', |
|||
'verbose_name_plural': 'Message queue', |
|||
'db_table': 'chat_message_queue', |
|||
}, |
|||
), |
|||
migrations.CreateModel( |
|||
name='TelegramBot', |
|||
fields=[ |
|||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
|||
('chat_id', models.PositiveIntegerField(default=0, verbose_name='Telegram chat id')), |
|||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, |
|||
verbose_name='Employee')), |
|||
], |
|||
options={ |
|||
'verbose_name': 'Telegram bot', |
|||
'verbose_name_plural': 'Telegram bots', |
|||
'db_table': 'chat_telegram_bot', |
|||
}, |
|||
), |
|||
] |
|||
@ -1,27 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Generated by Django 1.11 on 2018-08-08 12:36 |
|||
from __future__ import unicode_literals |
|||
|
|||
from django.db import migrations |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
|
|||
dependencies = [ |
|||
('chatbot', '0001_initial'), |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.AlterModelOptions( |
|||
name='messagehistory', |
|||
options={'ordering': ('-date_sent',), 'verbose_name': 'Message history', 'verbose_name_plural': 'Message histories'}, |
|||
), |
|||
migrations.AlterModelOptions( |
|||
name='messagequeue', |
|||
options={'ordering': ('target_employee__username',), 'verbose_name': 'Message queue', 'verbose_name_plural': 'Message queue'}, |
|||
), |
|||
migrations.AlterModelOptions( |
|||
name='telegrambot', |
|||
options={'ordering': ('chat_id',), 'verbose_name': 'Telegram bot', 'verbose_name_plural': 'Telegram bots'}, |
|||
), |
|||
] |
|||
@ -1,73 +0,0 @@ |
|||
from django.utils.translation import gettext_lazy as _ |
|||
from django.db import models |
|||
from django.conf import settings |
|||
|
|||
AUTH_USER_MODEL = getattr(settings, 'AUTH_USER_MODEL') |
|||
|
|||
|
|||
class ChatException(Exception): |
|||
pass |
|||
|
|||
|
|||
class TelegramBot(models.Model): |
|||
user = models.ForeignKey(AUTH_USER_MODEL, on_delete=models.CASCADE, verbose_name=_('Employee')) |
|||
chat_id = models.PositiveIntegerField(_('Telegram chat id'), default=0) |
|||
|
|||
def __str__(self): |
|||
return "%s - %d" % (self.user.get_full_name(), self.chat_id) |
|||
|
|||
class Meta: |
|||
db_table = 'chat_telegram_bot' |
|||
verbose_name = _('Telegram bot') |
|||
verbose_name_plural = _('Telegram bots') |
|||
ordering = ('chat_id',) |
|||
|
|||
|
|||
class MessageHistory(models.Model): |
|||
user = models.ForeignKey(AUTH_USER_MODEL, on_delete=models.CASCADE) |
|||
message = models.CharField(max_length=255) |
|||
date_sent = models.DateTimeField(auto_now_add=True) |
|||
|
|||
def __str__(self): |
|||
return self.message |
|||
|
|||
class Meta: |
|||
db_table = 'chat_message_history' |
|||
verbose_name = _('Message history') |
|||
verbose_name_plural = _('Message histories') |
|||
ordering = ('-date_sent',) |
|||
|
|||
|
|||
class MessageQueueManager(models.Manager): |
|||
def pop(self, user, tag='none'): |
|||
msgs = self.filter(target_employee=user, status='n', tag=tag)[:1].only('message').values('id', 'message') |
|||
if len(msgs) > 0: |
|||
self.filter(id=msgs[0]['id']).delete() |
|||
return msgs[0]['message'] |
|||
|
|||
def push(self, msg, user, tag='none'): |
|||
msg = self.create(target_employee=user, message=msg, tag=tag) |
|||
return msg |
|||
|
|||
|
|||
class MessageQueue(models.Model): |
|||
target_employee = models.ForeignKey(AUTH_USER_MODEL, on_delete=models.CASCADE, verbose_name=_('Target employee')) |
|||
message = models.CharField(_('Message'), max_length=255) |
|||
STATUSES = ( |
|||
('n', 'New'), |
|||
('r', 'Read') |
|||
) |
|||
status = models.CharField(_('Status of message'), max_length=1, choices=STATUSES, default='n') |
|||
# tag: each application puts its own to separate messages between these applications |
|||
tag = models.CharField(_('App tag'), max_length=6, default='none') |
|||
|
|||
objects = MessageQueueManager() |
|||
|
|||
def __str__(self): |
|||
return self.message |
|||
|
|||
class Meta: |
|||
db_table = 'chat_message_queue' |
|||
verbose_name = _('Message queue') |
|||
verbose_name_plural = _('Message queue') |
|||
ordering = ('target_employee__username',) |
|||
@ -1,149 +0,0 @@ |
|||
# -*- coding: utf-8 -*- |
|||
from telepot import helper, glance, Bot |
|||
from telepot.exception import TelegramError |
|||
import os |
|||
import socket |
|||
import collections |
|||
from django.utils.translation import ugettext as _ |
|||
from urllib3.exceptions import ProtocolError |
|||
from .models import TelegramBot, ChatException, MessageQueue |
|||
from chatbot.models import MessageHistory |
|||
from accounts_app.models import UserProfile |
|||
from django.conf import settings |
|||
|
|||
token = getattr(settings, 'TELEGRAM_BOT_TOKEN') |
|||
|
|||
|
|||
class DjingTelebot(helper.ChatHandler): |
|||
_current_user = None |
|||
_dialog_fn = None |
|||
_chat_id = 0 |
|||
|
|||
def __init__(self, seed_tuple, **kwargs): |
|||
super(DjingTelebot, self).__init__(seed_tuple, **kwargs) |
|||
self.cmds = { |
|||
'ping': self.ping, |
|||
'iam': self.say_me |
|||
} |
|||
|
|||
# отвечаем пользователю |
|||
def _sent_reply(self, text): |
|||
self.sender.sendMessage(text) |
|||
|
|||
# задаём вопрос пользователю, и ожидаем ответ в fn |
|||
def _question(self, text, fn): |
|||
if not isinstance(fn, collections.Callable): |
|||
raise TypeError |
|||
self._dialog_fn = fn |
|||
if text is not None: |
|||
self._sent_reply(text) |
|||
|
|||
# сохраняем сообщение в базе |
|||
def _message_log(self, msg): |
|||
if self._current_user is None: |
|||
self._question(None, self.question_name) |
|||
return False |
|||
MessageHistory.objects.create( |
|||
user=self._current_user, |
|||
message=msg |
|||
) |
|||
return True |
|||
|
|||
# Начинаем диалог |
|||
# @seed - chat_id |
|||
def open(self, initial_msg, seed): |
|||
content_type, chat_type, chat_id = glance(initial_msg) |
|||
if content_type != 'text': |
|||
return True |
|||
self._chat_id = chat_id |
|||
try: |
|||
tbot = TelegramBot.objects.get(chat_id=seed) |
|||
self._current_user = tbot.user |
|||
self._message_log(initial_msg['text']) |
|||
except TelegramBot.DoesNotExist: |
|||
self._question(_("Let's get acquainted, what is your name? Write your login from billing."), |
|||
self.question_name) |
|||
return True # prevent on_message() from being called on the initial message |
|||
|
|||
# получаем сообщение |
|||
def on_chat_message(self, msg): |
|||
content_type, chat_type, chat_id = glance(msg) |
|||
if content_type != 'text': |
|||
return |
|||
self._chat_id = chat_id |
|||
text = msg['text'].lower() |
|||
|
|||
# выполняем комманды если они есть |
|||
if text in self.cmds.keys(): |
|||
self.cmds[text]() |
|||
elif self._dialog_fn is not None: |
|||
if not callable(self._dialog_fn): |
|||
raise TypeError |
|||
self._dialog_fn(text) |
|||
self._dialog_fn = None |
|||
else: |
|||
self._sent_reply(_('I do not know the answer to this yet.')) |
|||
|
|||
if not self._message_log(text): |
|||
return |
|||
|
|||
# спрашиваем имя пользователя |
|||
def question_name(self, username): |
|||
try: |
|||
profile = UserProfile.objects.get(username=username) |
|||
self._current_user = profile |
|||
try: |
|||
TelegramBot.objects.get(user=profile) |
|||
except TelegramBot.DoesNotExist: |
|||
if self._chat_id == 0: |
|||
raise ChatException('telebot.py. def question_name: Chat id is empty') |
|||
TelegramBot.objects.create( |
|||
user=profile, |
|||
chat_id=self._chat_id |
|||
) |
|||
except UserProfile.DoesNotExist: |
|||
self._question( |
|||
_("You are not found in the database, check that it correctly pointed out its LOGIN. Try again"), |
|||
self.question_name) |
|||
return |
|||
self._sent_reply( |
|||
_("Yes, it's nice to meet %(username)s, I will notify you about events in billing. Successful work ;)") |
|||
% {'username': profile.get_full_name()}) |
|||
|
|||
# заканчивается время диалога |
|||
# ex - время ожидания (timeout=ex в pave_event_space) |
|||
def on_close(self, ex): |
|||
self._current_user = None |
|||
self._dialog_fn = None |
|||
self._chat_id = 0 |
|||
|
|||
def ping(self, ip=None): |
|||
if ip is None: |
|||
self._question(_("Let's ping, write ip. It will be necessary to wait 10 seconds"), self.ping) |
|||
return |
|||
try: |
|||
socket.inet_aton(ip) |
|||
ret = os.popen('`which ping` -c 10 %s' % ip).read() |
|||
self._sent_reply(ret) |
|||
except socket.error: |
|||
self._question(_("It's not like ip address, try again"), self.ping) |
|||
|
|||
def say_me(self): |
|||
self._sent_reply(_("You're '%s', right?") % self._current_user.get_full_name()) |
|||
|
|||
|
|||
# Just sending text to specified account |
|||
def send_notify(msg_text, account, tag='none'): |
|||
try: |
|||
MessageQueue.objects.push(msg=msg_text, user=account, tag=tag) |
|||
if token is None: |
|||
raise ChatException(_('Telegram bot token not found')) |
|||
tb = TelegramBot.objects.get(user=account) |
|||
tbot = Bot(token) |
|||
tbot.sendMessage(tb.chat_id, msg_text) |
|||
except TelegramBot.DoesNotExist: |
|||
raise ChatException(_("Recipient '%s' does not subscribed on notifications") % account.get_full_name()) |
|||
except ProtocolError as e: |
|||
raise ChatException('ProtocolError: %s' % e) |
|||
except TelegramError as e: |
|||
raise ChatException('Telegram error: %s' % e) |
|||
@ -1,3 +0,0 @@ |
|||
from django.shortcuts import render |
|||
|
|||
# Create your views here. |
|||
@ -0,0 +1 @@ |
|||
default_app_config = 'messenger.apps.messengerConfig' |
|||
@ -0,0 +1,7 @@ |
|||
from django.contrib import admin |
|||
from messenger import models |
|||
|
|||
admin.site.register(models.Messenger) |
|||
admin.site.register(models.ViberMessenger) |
|||
admin.site.register(models.ViberSubscriber) |
|||
admin.site.register(models.ViberMessage) |
|||
@ -0,0 +1,5 @@ |
|||
from django.apps import AppConfig |
|||
|
|||
|
|||
class messengerConfig(AppConfig): |
|||
name = 'messenger' |
|||
@ -0,0 +1,28 @@ |
|||
from django import forms |
|||
from messenger import models |
|||
|
|||
|
|||
class MessengerForm(forms.ModelForm): |
|||
class Meta: |
|||
model = models.Messenger |
|||
fields = ('bot_type',) |
|||
|
|||
|
|||
class MessengerViberForm(forms.ModelForm): |
|||
def __init__(self, *args, **kwargs): |
|||
kwargs['initial']['bot_type'] = 1 |
|||
super().__init__(*args, **kwargs) |
|||
inst = getattr(self, 'instance') |
|||
if inst: |
|||
self.fields['bot_type'].disabled = True |
|||
#self.fields['bot_type'].widget.attrs['disabled'] = True |
|||
|
|||
class Meta: |
|||
model = models.ViberMessenger |
|||
fields = '__all__' |
|||
|
|||
|
|||
class MessengerViberMessageForm(forms.ModelForm): |
|||
class Meta: |
|||
model = models.ViberMessage |
|||
fields = '__all__' |
|||
@ -0,0 +1,190 @@ |
|||
# SOME DESCRIPTIVE TITLE. |
|||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
|||
# This file is distributed under the same license as the PACKAGE package. |
|||
# Dmitry Novikov nerosketch@gmail.com, 2019. |
|||
# |
|||
#, fuzzy |
|||
msgid "" |
|||
msgstr "" |
|||
"Report-Msgid-Bugs-To: \n" |
|||
"POT-Creation-Date: 2019-02-06 13:45+0300\n" |
|||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" |
|||
"Last-Translator: Dmitry Novikov nerosketch@gmail.com\n" |
|||
"Language: ru\n" |
|||
"MIME-Version: 1.0\n" |
|||
"Content-Type: text/plain; charset=UTF-8\n" |
|||
"Content-Transfer-Encoding: 8bit\n" |
|||
"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" |
|||
"%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 |
|||
msgid "Title" |
|||
msgstr "Название" |
|||
|
|||
#: models.py:18 |
|||
msgid "Viber" |
|||
msgstr "Вайбер" |
|||
|
|||
#: models.py:20 |
|||
msgid "Bot type" |
|||
msgstr "Тип бота" |
|||
|
|||
#: models.py:21 templates/messenger/messenger_list.html:22 |
|||
msgid "Slug" |
|||
msgstr "Ссыль" |
|||
|
|||
#: models.py:28 models.py:92 |
|||
msgid "messenger" |
|||
msgstr "Мэссенджер" |
|||
|
|||
#: models.py:29 templates/messenger/messenger_list.html:7 |
|||
#: templates/messenger/messenger_list.html:12 |
|||
#: templates/messenger/vibermessenger_form.html:8 |
|||
msgid "messengers" |
|||
msgstr "Мэссенджэры" |
|||
|
|||
#: models.py:48 |
|||
msgid "Bot secret token" |
|||
msgstr "Секретный токен viber" |
|||
|
|||
#: models.py:49 models.py:108 |
|||
msgid "Avatar" |
|||
msgstr "Аватар" |
|||
|
|||
#: models.py:83 |
|||
msgid "Viber messenger" |
|||
msgstr "Viber мэссенджэр" |
|||
|
|||
#: models.py:84 |
|||
msgid "Viber messengers" |
|||
msgstr "Viber мэссенджэры" |
|||
|
|||
#: models.py:89 |
|||
msgid "Message" |
|||
msgstr "Сообщение" |
|||
|
|||
#: models.py:90 |
|||
msgid "Date" |
|||
msgstr "Дата" |
|||
|
|||
#: models.py:91 |
|||
msgid "Sender" |
|||
msgstr "Отправитель" |
|||
|
|||
#: models.py:93 |
|||
msgid "Subscriber" |
|||
msgstr "Подписчик" |
|||
|
|||
#: models.py:100 |
|||
msgid "Viber message" |
|||
msgstr "Сообщение viber" |
|||
|
|||
#: models.py:101 |
|||
msgid "Viber messages" |
|||
msgstr "Сообщения viber" |
|||
|
|||
#: models.py:106 |
|||
msgid "User unique id in viber" |
|||
msgstr "Уникальный id viber" |
|||
|
|||
#: models.py:107 |
|||
msgid "Name" |
|||
msgstr "Имя" |
|||
|
|||
#: models.py:109 |
|||
msgid "System account" |
|||
msgstr "Системная учётная запись" |
|||
|
|||
#: models.py:116 |
|||
msgid "Viber subscriber" |
|||
msgstr "Подписчик viber" |
|||
|
|||
#: models.py:117 |
|||
msgid "Viber subscribers" |
|||
msgstr "Подписчики viber" |
|||
|
|||
#: templates/messenger/add_messenger.html:5 |
|||
msgid "Select bot type" |
|||
msgstr "Выберите тип бота" |
|||
|
|||
#: templates/messenger/add_messenger.html:11 |
|||
msgid "Add" |
|||
msgstr "Добавить" |
|||
|
|||
#: templates/messenger/messenger_list.html:21 |
|||
msgid "Type" |
|||
msgstr "Тип" |
|||
|
|||
#: templates/messenger/messenger_list.html:33 |
|||
msgid "Edit" |
|||
msgstr "Изменить" |
|||
|
|||
#: templates/messenger/messenger_list.html:40 |
|||
msgid "messengers was not found" |
|||
msgstr "Мэссенджеры не найдены" |
|||
|
|||
#: templates/messenger/messenger_list.html:49 |
|||
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 |
|||
msgid "Add viber" |
|||
msgstr "Добавить viber" |
|||
|
|||
#: templates/messenger/vibermessenger_form.html:25 |
|||
msgid "Change messenger" |
|||
msgstr "Изменить мэссенджэр" |
|||
|
|||
#: templates/messenger/vibermessenger_form.html:28 |
|||
msgid "Add new messenger" |
|||
msgstr "Добавить мэссенджэр" |
|||
|
|||
#: templates/messenger/vibermessenger_form.html:39 |
|||
msgid "Save" |
|||
msgstr "Сохранить" |
|||
|
|||
#: templates/messenger/vibermessenger_form.html:43 |
|||
msgid "Send webhook" |
|||
msgstr "Отправить webhook" |
|||
|
|||
#: views.py:38 |
|||
msgid "Unexpected bot type" |
|||
msgstr "Не известный тип бота" |
|||
|
|||
#: views.py:51 |
|||
msgid "New viber messenger successfully created" |
|||
msgstr "Новый viber мэссенджэр успешно создан" |
|||
|
|||
#: views.py:62 |
|||
msgid "Viber messenger successfully updated" |
|||
msgstr "viber мэссенджэр успешно обновлён" |
|||
|
|||
#: views.py:73 |
|||
msgid "Viber messenger successfully deleted" |
|||
msgstr "viber мэссенджэр успешно удалён" |
|||
|
|||
#: views.py:132 |
|||
msgid "My telephone number" |
|||
msgstr "Мой номер телефона" |
|||
|
|||
#: views.py:150 |
|||
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 "Ваша учётка из биллинга привязана. Теперь вы будете получать оповещения из биллинга." |
|||
@ -0,0 +1,88 @@ |
|||
# Generated by Django 2.1.3 on 2019-02-07 12:31 |
|||
|
|||
from django.conf import settings |
|||
from django.db import migrations, models |
|||
import django.db.models.deletion |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
|
|||
initial = True |
|||
|
|||
dependencies = [ |
|||
migrations.swappable_dependency(settings.AUTH_USER_MODEL), |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.CreateModel( |
|||
name='Messenger', |
|||
fields=[ |
|||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
|||
('title', models.CharField(max_length=64, verbose_name='Title')), |
|||
('bot_type', models.PositiveSmallIntegerField(blank=True, choices=[(1, 'Viber')], verbose_name='Bot type')), |
|||
('slug', models.SlugField(verbose_name='Slug')), |
|||
], |
|||
options={ |
|||
'verbose_name': 'messenger', |
|||
'verbose_name_plural': 'messengers', |
|||
'db_table': 'messengers', |
|||
'ordering': ('title',), |
|||
}, |
|||
), |
|||
migrations.CreateModel( |
|||
name='ViberMessage', |
|||
fields=[ |
|||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
|||
('msg', models.TextField(verbose_name='Message')), |
|||
('date', models.DateTimeField(auto_now_add=True, verbose_name='Date')), |
|||
('sender', models.CharField(max_length=32, verbose_name='Sender')), |
|||
], |
|||
options={ |
|||
'verbose_name': 'Viber message', |
|||
'verbose_name_plural': 'Viber messages', |
|||
'db_table': 'viber_messages_notifications', |
|||
'ordering': ('-date',), |
|||
}, |
|||
), |
|||
migrations.CreateModel( |
|||
name='ViberSubscriber', |
|||
fields=[ |
|||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
|||
('uid', models.CharField(max_length=32, verbose_name='User unique id in viber')), |
|||
('name', models.CharField(blank=True, max_length=32, null=True, verbose_name='Name')), |
|||
('avatar', models.URLField(blank=True, max_length=250, null=True, verbose_name='Avatar')), |
|||
('account', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='System account')), |
|||
], |
|||
options={ |
|||
'verbose_name': 'Viber subscriber', |
|||
'verbose_name_plural': 'Viber subscribers', |
|||
'db_table': 'viber_subscriber', |
|||
'ordering': ('name',), |
|||
}, |
|||
), |
|||
migrations.CreateModel( |
|||
name='ViberMessenger', |
|||
fields=[ |
|||
('messenger_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='messenger.Messenger')), |
|||
('token', models.CharField(max_length=64, verbose_name='Bot secret token')), |
|||
('avatar', models.ImageField(null=True, upload_to='viber_avatar', verbose_name='Avatar')), |
|||
], |
|||
options={ |
|||
'verbose_name': 'Viber messenger', |
|||
'verbose_name_plural': 'Viber messengers', |
|||
'db_table': 'viber_messenger_notifications', |
|||
'ordering': ('title',), |
|||
}, |
|||
bases=('messenger.messenger',), |
|||
), |
|||
migrations.AddField( |
|||
model_name='vibermessage', |
|||
name='subscriber', |
|||
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='messenger.ViberSubscriber', verbose_name='Subscriber'), |
|||
), |
|||
migrations.AddField( |
|||
model_name='vibermessage', |
|||
name='messenger', |
|||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='messenger.ViberMessenger', verbose_name='messenger'), |
|||
), |
|||
] |
|||
@ -0,0 +1,129 @@ |
|||
from typing import Iterable |
|||
from urllib.parse import urljoin |
|||
|
|||
from django.conf import settings |
|||
from django.shortcuts import resolve_url |
|||
from django.utils.translation import gettext_lazy as _ |
|||
from django.db import models |
|||
from viberbot import Api, BotConfiguration |
|||
from viberbot.api.messages import TextMessage |
|||
from viberbot.api.messages.message import Message |
|||
|
|||
from accounts_app.models import UserProfile |
|||
|
|||
|
|||
class Messenger(models.Model): |
|||
title = models.CharField(_('Title'), max_length=64) |
|||
CHAT_TYPES = ( |
|||
(1, _('Viber')), |
|||
) |
|||
bot_type = models.PositiveSmallIntegerField(_('Bot type'), choices=CHAT_TYPES, blank=True) |
|||
slug = models.SlugField(_('Slug')) |
|||
|
|||
def __str__(self): |
|||
return self.title |
|||
|
|||
class Meta: |
|||
db_table = 'messengers' |
|||
verbose_name = _('messenger') |
|||
verbose_name_plural = _('messengers') |
|||
ordering = ('title',) |
|||
|
|||
def get_absolute_url(self): |
|||
if self.bot_type == 1: |
|||
return resolve_url('messenger:update_viber_messenger', self.slug) |
|||
|
|||
def get_next_url(self): |
|||
if self.bot_type == 1: # Viber |
|||
return resolve_url('messenger:update_viber_messenger', self.slug) |
|||
else: |
|||
return resolve_url('messenger:messengers_list') |
|||
|
|||
|
|||
class ViberMessenger(Messenger): |
|||
def __init__(self, *args, **kwargs): |
|||
super().__init__(*args, **kwargs) |
|||
self._viber_cache = None |
|||
|
|||
token = models.CharField(_('Bot secret token'), max_length=64) |
|||
avatar = models.ImageField(_('Avatar'), upload_to='viber_avatar', null=True) |
|||
|
|||
def get_viber(self): |
|||
if self._viber_cache is None: |
|||
self._viber_cache = Api(BotConfiguration( |
|||
name=str(self.slug), |
|||
avatar=self.avatar.url, |
|||
auth_token=str(self.token) |
|||
)) |
|||
return self._viber_cache |
|||
|
|||
def send_message(self, to: UserProfile, msg): |
|||
try: |
|||
viber = self.get_viber() |
|||
vs = to.vibersubscriber |
|||
if issubclass(msg.__class__, Message): |
|||
viber.send_messages(str(vs.uid), msg) |
|||
else: |
|||
viber.send_messages(str(vs.uid), TextMessage(text=msg)) |
|||
except ViberSubscriber.DoesNotExist: |
|||
pass |
|||
|
|||
def send_messages(self, receivers, msg_text: str): |
|||
""" |
|||
:param receivers: QuerySet of accounts_app.UserProfile |
|||
:param msg_text: text message |
|||
:return: nothing |
|||
""" |
|||
viber = self.get_viber() |
|||
msg = TextMessage(text=msg_text) |
|||
for vs in ViberSubscriber.objects.filter(account__in=receivers).iterator(): |
|||
viber.send_messages(str(vs.uid), msg) |
|||
|
|||
def send_webhook(self): |
|||
pub_url = getattr(settings, 'VIBER_BOT_PUBLIC_URL') |
|||
listen_url = resolve_url('messenger:listen_viber_bot', self.slug) |
|||
public_url = urljoin(pub_url, listen_url) |
|||
viber = self.get_viber() |
|||
viber.set_webhook(public_url, ['failed', 'subscribed', 'unsubscribed', 'conversation_started']) |
|||
|
|||
def __str__(self): |
|||
return self.title |
|||
|
|||
class Meta: |
|||
db_table = 'viber_messenger_notifications' |
|||
verbose_name = _('Viber messenger') |
|||
verbose_name_plural = _('Viber messengers') |
|||
ordering = ('title',) |
|||
|
|||
|
|||
class ViberMessage(models.Model): |
|||
msg = models.TextField(_('Message')) |
|||
date = models.DateTimeField(_('Date'), auto_now_add=True) |
|||
sender = models.CharField(_('Sender'), max_length=32) |
|||
messenger = models.ForeignKey(ViberMessenger, verbose_name=_('messenger'), on_delete=models.CASCADE) |
|||
subscriber = models.ForeignKey('ViberSubscriber', on_delete=models.SET_NULL, verbose_name=_('Subscriber'), null=True) |
|||
|
|||
def __str__(self): |
|||
return self.msg |
|||
|
|||
class Meta: |
|||
db_table = 'viber_messages_notifications' |
|||
verbose_name = _('Viber message') |
|||
verbose_name_plural = _('Viber messages') |
|||
ordering = ('-date',) |
|||
|
|||
|
|||
class ViberSubscriber(models.Model): |
|||
uid = models.CharField(_('User unique id in viber'), max_length=32) |
|||
name = models.CharField(_('Name'), max_length=32, null=True, blank=True) |
|||
avatar = models.URLField(_('Avatar'), max_length=250, null=True, blank=True) |
|||
account = models.OneToOneField(UserProfile, on_delete=models.CASCADE, verbose_name=_('System account'), blank=True, null=True) |
|||
|
|||
def __str__(self): |
|||
return self.name or 'no' |
|||
|
|||
class Meta: |
|||
db_table = 'viber_subscriber' |
|||
verbose_name = _('Viber subscriber') |
|||
verbose_name_plural = _('Viber subscribers') |
|||
ordering = ('name',) |
|||
@ -0,0 +1,56 @@ |
|||
from typing import Optional, Iterable |
|||
|
|||
from celery import shared_task |
|||
|
|||
from accounts_app.models import UserProfile |
|||
from messenger.models import ViberMessenger |
|||
|
|||
|
|||
@shared_task |
|||
def send_viber_message(messenger_id: Optional[int], account_id: int, message_text: str) -> Optional[str]: |
|||
""" |
|||
Send text message via viber |
|||
:param messenger_id: Primary key UID for messanger.ViberMessenger |
|||
:param account_id: User id from accounts_app.UserProfile |
|||
:param message_text: |
|||
:return: Optional text for log |
|||
""" |
|||
if not message_text: |
|||
return 'ERROR: empty message text' |
|||
try: |
|||
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) |
|||
else: |
|||
vm = ViberMessenger.objects.get(pk=messenger_id) |
|||
vm.send_message(sp, message_text) |
|||
except ViberMessenger.DoesNotExist: |
|||
return 'ERROR: Viber messanger with id=%d not found' % messenger_id |
|||
except UserProfile.DoesNotExist: |
|||
return 'ERROR: accounts_app.UserProfile with pk=%d does not exist' % account_id |
|||
|
|||
|
|||
@shared_task |
|||
def multicast_viber_notify(messenger_id: Optional[int], account_id_list: Iterable[int], message_text: str): |
|||
""" |
|||
Send multiple message via Viber to several addresses |
|||
:param messenger_id: Primary key UID for messanger.ViberMessenger |
|||
:param account_id_list: list of account ids from accounts_app.UserProfile |
|||
:param message_text: |
|||
:return: Optional text for log |
|||
""" |
|||
if not message_text: |
|||
return 'ERROR: empty message text' |
|||
account_id_list = tuple(account_id_list) |
|||
recipients = UserProfile.objects.filter(pk__in=account_id_list) |
|||
if not recipients.exists(): |
|||
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) |
|||
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) |
|||
@ -0,0 +1,15 @@ |
|||
{% load i18n bootstrap3 %} |
|||
<form role="form" action="{% url 'messenger:add_messenger' %}" method="post">{% csrf_token %} |
|||
<div class="modal-header primary"> |
|||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> |
|||
<h4 class="modal-title"><span class="glyphicon glyphicon-blackboard"></span>{% trans 'Select bot type' %}</h4> |
|||
</div> |
|||
|
|||
<div class="modal-body"> |
|||
{% bootstrap_form form %} |
|||
<button type="submit" class="btn btn-success"> |
|||
<span class="glyphicon glyphicon-plus"></span> {% trans 'Add' %} |
|||
</button> |
|||
</div> |
|||
|
|||
</form> |
|||
@ -0,0 +1,57 @@ |
|||
{% extends 'base.html' %} |
|||
{% load dpagination i18n %} |
|||
|
|||
{% block breadcrumb %} |
|||
<ol class="breadcrumb"> |
|||
<li><span class="glyphicon glyphicon-home"></span></li> |
|||
<li class="active">{% trans 'messengers' %}</li> |
|||
</ol> |
|||
{% endblock %} |
|||
|
|||
{% block page-header %} |
|||
{% trans 'messengers' %} |
|||
{% endblock %} |
|||
|
|||
{% block main %} |
|||
<div class="table-responsive"> |
|||
<table class="table table-striped table-bordered"> |
|||
<thead> |
|||
<tr> |
|||
<th class="col-sm-4">{% trans 'Title' %}</th> |
|||
<th class="col-sm-3">{% trans 'Type' %}</th> |
|||
<th class="col-sm-4">{% trans 'Slug' %}</th> |
|||
<th class="col-sm-1">#</th> |
|||
</tr> |
|||
</thead> |
|||
<tbody> |
|||
{% for messenger in object_list %} |
|||
<tr> |
|||
<td>{{ messenger.title }}</td> |
|||
<td>{{ messenger.get_bot_type_display }}</td> |
|||
<td>{{ messenger.slug }}</td> |
|||
<td> |
|||
<a href="{{ messenger.get_absolute_url }}" class="btn btn-sm btn-default" title="{% trans 'Edit' %}"> |
|||
<span class="glyphicon glyphicon-edit"></span> |
|||
</a> |
|||
</td> |
|||
</tr> |
|||
{% empty %} |
|||
<tr> |
|||
<td colspan="4"><a href="#">{% trans 'messengers was not found' %}</a></td> |
|||
</tr> |
|||
{% endfor %} |
|||
</tbody> |
|||
{% if perms.messenger.add_messenger %} |
|||
<tfoot> |
|||
<tr> |
|||
<td colspan="4" class="btn-group btn-group-sm"> |
|||
<a href="{% url 'messenger:add_messenger' %}" class="btn btn-default btn-modal"> |
|||
<span class="glyphicon glyphicon-plus"></span> <span class="hidden-xs">{% trans 'New' %}</span> |
|||
</a> |
|||
</td> |
|||
</tr> |
|||
</tfoot> |
|||
{% endif %} |
|||
</table> |
|||
</div> |
|||
{% endblock %} |
|||
@ -0,0 +1,49 @@ |
|||
{% extends request.is_ajax|yesno:'bajax.html,base.html' %} |
|||
{% load i18n bootstrap3 %} |
|||
|
|||
|
|||
{% block breadcrumb %} |
|||
<ol class="breadcrumb"> |
|||
<li><span class="glyphicon glyphicon-home"></span></li> |
|||
<li><a href="{% url 'messenger:messengers_list' %}">{% trans 'messengers' %}</a></li> |
|||
{% if object %} |
|||
<li><a href="{{ object.get_absolute_url }}">{% trans 'Update messenger' %}</a></li> |
|||
<li class="active">{% trans 'Change viber' %}</li> |
|||
{% else %} |
|||
<li><a href="{% url 'messenger:add_messenger' %}">{% trans 'Add messenger' %}</a></li> |
|||
<li class="active">{% trans 'Add viber' %}</li> |
|||
{% endif %} |
|||
|
|||
</ol> |
|||
{% endblock %} |
|||
|
|||
|
|||
{% block main %} |
|||
|
|||
{% if object %} |
|||
{% url 'messenger:update_viber_messenger' object.slug as form_url %} |
|||
{% trans 'Change messenger' as panel_title %} |
|||
{% else %} |
|||
{% url 'messenger:add_viber_messenger' as form_url %} |
|||
{% trans 'Add new messenger' as panel_title %} |
|||
{% endif %} |
|||
|
|||
<div class="panel panel-default"> |
|||
<div class="panel-heading"> |
|||
<h3 class="panel-title">{{ panel_title }}</h3> |
|||
</div> |
|||
<div class="panel-body"> |
|||
<form role="form" action="{{ form_url }}" method="post" enctype="multipart/form-data">{% csrf_token %} |
|||
{% bootstrap_form form %} |
|||
<button type="submit" class="btn btn-sm btn-default"> |
|||
<span class="glyphicon glyphicon-save"></span> {% trans 'Save' %} |
|||
</button> |
|||
{% if object %} |
|||
<a href="{% url 'messenger:webhook_viber_bot' object.slug %}" class="btn btn-default btn-sm btn-modal"> |
|||
<span class="glyphicon glyphicon-share"></span> {% trans 'Send webhook' %} |
|||
</a> |
|||
{% endif %} |
|||
</form> |
|||
</div> |
|||
</div> |
|||
{% endblock %} |
|||
@ -0,0 +1,3 @@ |
|||
from django.test import TestCase |
|||
|
|||
# Create your tests here. |
|||
@ -0,0 +1,17 @@ |
|||
from django.urls import path |
|||
from django.views.decorators.csrf import csrf_exempt |
|||
|
|||
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/<slug:slug>/update/', views.UpdateVibermessengerUpdateView.as_view(), name='update_viber_messenger'), |
|||
path('viber/<slug:slug>/delete/', views.RemoveVibermessengerDeleteView.as_view(), name='delete_viber_messenger'), |
|||
path('viber/<slug:slug>/listen/', csrf_exempt(views.ListenViberView.as_view()), name='listen_viber_bot'), |
|||
path('viber/<slug:slug>/set_webhook/', views.SetWebhook.as_view(), name='webhook_viber_bot'), |
|||
] |
|||
@ -0,0 +1,161 @@ |
|||
from django.contrib import messages |
|||
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 |
|||
from viberbot.api.user_profile import UserProfile as ViberUserProfile |
|||
from viberbot.api.viber_requests import ViberMessageRequest, ViberSubscribedRequest, ViberFailedRequest, \ |
|||
ViberUnsubscribedRequest |
|||
|
|||
from accounts_app.models import UserProfile |
|||
from djing.lib.mixins import LoginAdminPermissionMixin, LoginAdminMixin |
|||
from messenger import forms, models |
|||
|
|||
from messenger.models import ViberMessage, ViberSubscriber |
|||
|
|||
|
|||
class messengerListView(LoginAdminPermissionMixin, ListView): |
|||
model = models.Messenger |
|||
permission_required = 'messenger.view_messenger' |
|||
|
|||
|
|||
class AddmessengerCreateView(LoginAdminMixin, FormView): |
|||
template_name = 'messenger/add_messenger.html' |
|||
form_class = forms.MessengerForm |
|||
|
|||
def form_valid(self, form): |
|||
bot_type = form.cleaned_data.get('bot_type') |
|||
if isinstance(bot_type, int) and bot_type > 0: |
|||
if bot_type == 1: |
|||
self.success_url = resolve_url('messenger:add_viber_messenger') |
|||
return super().form_valid(form) |
|||
messages.info(self.request, _('Unexpected bot type')) |
|||
self.success_url = resolve_url('messenger:messengers_list') |
|||
return super().form_valid(form) |
|||
|
|||
|
|||
class AddmessengerViberCreateView(LoginAdminMixin, PermissionRequiredMixin, CreateView): |
|||
model = models.ViberMessenger |
|||
form_class = forms.MessengerViberForm |
|||
permission_required = 'messenger.add_vibermessenger' |
|||
success_url = reverse_lazy('messenger:messengers_list') |
|||
|
|||
def form_valid(self, form): |
|||
r = super().form_valid(form) |
|||
messages.success(self.request, _('New viber messenger successfully created')) |
|||
return r |
|||
|
|||
|
|||
class UpdateVibermessengerUpdateView(LoginAdminPermissionMixin, UpdateView): |
|||
model = models.ViberMessenger |
|||
form_class = forms.MessengerViberForm |
|||
permission_required = 'messenger.change_vibermessenger' |
|||
|
|||
def form_valid(self, form): |
|||
r = super().form_valid(form) |
|||
messages.success(self.request, _('Viber messenger successfully updated')) |
|||
return r |
|||
|
|||
|
|||
class RemoveVibermessengerDeleteView(LoginAdminPermissionMixin, DeleteView): |
|||
model = models.ViberMessenger |
|||
permission_required = 'messenger.delete_vibermessenger' |
|||
success_url = reverse_lazy('messenger:messengers_list') |
|||
|
|||
def delete(self, request, *args, **kwargs): |
|||
r = super().delete(request, *args, **kwargs) |
|||
messages.success(request, _('Viber messenger successfully deleted')) |
|||
return r |
|||
|
|||
|
|||
@method_decorator(csrf_exempt, name='post') |
|||
class ListenViberView(SingleObjectMixin, View): |
|||
http_method_names = 'post', |
|||
model = models.ViberMessenger |
|||
|
|||
def post(self, request, *args, **kwargs): |
|||
obj = self.get_object() |
|||
if not obj: |
|||
return HttpResponseNotFound() |
|||
self.object = obj |
|||
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 |
|||
if isinstance(in_msg, ContactMessage): |
|||
self.inbox_contact(in_msg, vr.sender) |
|||
subscriber, created = self.make_subscriber(vr.sender) |
|||
if not created: |
|||
ViberMessage.objects.create( |
|||
msg=vr.message, |
|||
sender=vr.sender.id, |
|||
messenger=obj, |
|||
subscriber=subscriber |
|||
) |
|||
elif isinstance(vr, ViberSubscribedRequest): |
|||
self.make_subscriber(vr.user) |
|||
elif isinstance(vr, ViberFailedRequest): |
|||
print("client failed receiving message. failure: {0}".format(vr)) |
|||
elif isinstance(vr, ViberUnsubscribedRequest): |
|||
ViberSubscriber.objects.filter( |
|||
uid=vr.user_id |
|||
).delete() |
|||
return HttpResponse(status=200) |
|||
|
|||
def make_subscriber(self, viber_user_profile: ViberUserProfile): |
|||
subscriber, created = ViberSubscriber.objects.get_or_create( |
|||
uid=viber_user_profile.id, |
|||
defaults={ |
|||
'name': viber_user_profile.name, |
|||
'avatar': viber_user_profile.avatar |
|||
} |
|||
) |
|||
if created and hasattr(self, 'object'): |
|||
msg = KeyboardMessage(keyboard={ |
|||
'Type': 'keyboard', |
|||
'DefaultHeight': True, |
|||
'Buttons': ({ |
|||
'ActionType': 'share-phone', |
|||
'ActionBody': 'reply to me', |
|||
"Text": gettext('My telephone number'), |
|||
"TextSize": "medium" |
|||
},) |
|||
}, min_api_version=3) |
|||
viber = self.object.get_viber() |
|||
viber.send_messages(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() |
|||
if accs.exists(): |
|||
subs = ViberSubscriber.objects.filter(uid=sender.id) |
|||
if subs.exists(): |
|||
subs.update(account=accs.first()) |
|||
viber.send_messages(sender.id, 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')) |
|||
|
|||
|
|||
class SetWebhook(LoginAdminMixin, SingleObjectMixin, View): |
|||
http_method_names = 'get', |
|||
model = models.ViberMessenger |
|||
|
|||
def get(self, request, *args, **kwargs): |
|||
obj = self.get_object() |
|||
if not obj: |
|||
return HttpResponseNotFound |
|||
obj.send_webhook() |
|||
return HttpResponse(b'ok', status=200) |
|||
@ -1,15 +0,0 @@ |
|||
[Unit] |
|||
Description=Djing telegram bot |
|||
|
|||
[Service] |
|||
Type=simple |
|||
ExecStart=/usr/bin/python3 ./telebot.py |
|||
PIDFile=/run/djing_telebot.pid |
|||
WorkingDirectory=/var/www/djing |
|||
TimeoutSec=9 |
|||
Restart=always |
|||
User=www-data |
|||
Group=www-data |
|||
|
|||
[Install] |
|||
WantedBy=multi-user.target |
|||
@ -1,29 +0,0 @@ |
|||
#!/usr/bin/python3 |
|||
# -*- coding: utf-8 -*- |
|||
import os |
|||
from pid.decorator import pidfile |
|||
import django |
|||
from telepot import DelegatorBot |
|||
from telepot.exception import BadHTTPResponse |
|||
from telepot.delegate import per_chat_id, create_open, pave_event_space |
|||
|
|||
|
|||
@pidfile(pidname='djing_telebot.pid', piddir='/run') |
|||
def main(): |
|||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djing.settings") |
|||
django.setup() |
|||
from chatbot.telebot import token, DjingTelebot |
|||
while True: |
|||
try: |
|||
bot = DelegatorBot(token, [ |
|||
pave_event_space()( |
|||
per_chat_id(), create_open, DjingTelebot, timeout=300 |
|||
), |
|||
]) |
|||
bot.message_loop(run_forever='Listening ...') |
|||
except BadHTTPResponse as e: |
|||
print(e) |
|||
|
|||
|
|||
if __name__ == '__main__': |
|||
main() |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue