Rewrite TG integration, support for other webhooks

This commit is contained in:
Aarni Halinen
2022-01-13 00:05:02 +02:00
parent 6f316401f7
commit 4a530826a8
15 changed files with 461 additions and 258 deletions
+3 -1
View File
@@ -1,7 +1,7 @@
"""File containing webapp app admin registers."""
from django.contrib import admin
from webapp.models import Feed, Tag, Event, Signup, SignupForm, TemplateQuestion, JobAd
from webapp.models import Feed, Tag, Event, Signup, SignupForm, TemplateQuestion, JobAd, BaseWebhook, GenericWebhook, TelegramHook
from modeltranslation.admin import TranslationAdmin
from django.contrib.auth.models import Permission
# this is needed so that the models get registered for translation
@@ -16,3 +16,5 @@ admin.site.register(SignupForm, TranslationAdmin)
admin.site.register(Signup, TranslationAdmin)
admin.site.register(TemplateQuestion, TranslationAdmin)
admin.site.register(JobAd, TranslationAdmin)
admin.site.register(GenericWebhook, TranslationAdmin)
admin.site.register(TelegramHook, TranslationAdmin)
@@ -0,0 +1,59 @@
# Generated by Django 2.2.26 on 2022-01-12 21:32
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('contenttypes', '0002_remove_content_type_name'),
('webapp', '0077_templatequestion_deleted'),
]
operations = [
migrations.CreateModel(
name='BaseWebhook',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255)),
('url', models.URLField()),
('kaehmy_submit', models.BooleanField(default=False)),
('ohlhafv_submit', models.BooleanField(default=False)),
('feed_published', models.BooleanField(default=False)),
('jobad_published', models.BooleanField(default=False)),
('event_published', models.BooleanField(default=False)),
('signup_opened', models.BooleanField(default=False)),
('polymorphic_ctype', models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_webapp.basewebhook_set+', to='contenttypes.ContentType')),
],
options={
'abstract': False,
'base_manager_name': 'objects',
},
),
migrations.CreateModel(
name='TelegramHook',
fields=[
('basewebhook_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='webapp.BaseWebhook')),
('channel_id', models.CharField(max_length=255, unique=True)),
],
options={
'verbose_name': 'Telegram channel',
'verbose_name_plural': 'Telegram channels',
},
bases=('webapp.basewebhook',),
),
migrations.CreateModel(
name='GenericWebhook',
fields=[
],
options={
'verbose_name': 'Webhook',
'verbose_name_plural': 'Webhooks',
'proxy': True,
'indexes': [],
'constraints': [],
},
bases=('webapp.basewebhook',),
),
]
+72
View File
@@ -2,16 +2,19 @@
from django.conf import settings
from django.db import models
from django.db.models.fields import CharField
from django.utils import timezone
# from datetime import timedelta
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
import requests
from webapp.utils import month_from_now, send_signup_email
from django.utils.translation import ugettext_lazy as _
from auditlog.registry import auditlog
from phonenumber_field.modelfields import PhoneNumberField
from django.contrib.postgres.fields import JSONField
from polymorphic.models import PolymorphicModel
from uuid import uuid4
import logging
@@ -199,9 +202,78 @@ class JobAd(models.Model):
return f'{delete_str}{self.title}'
class BaseWebhook(PolymorphicModel):
"""Webhook base class instance"""
name = models.CharField(max_length=255)
url = models.URLField() # URL where webhook message is broadcast. For example Telegram webhook API
# "Plugs"; which notifications are sent to this specific webhook instance
kaehmy_submit = models.BooleanField(_("Hook Kaehmys"), default=False)
ohlhafv_submit = models.BooleanField(_("Hook Ohlhafv challenges"),default=False)
feed_published = models.BooleanField(_("Hook published news"),default=False)
jobad_published = models.BooleanField(_("Hook published Job Ads"),default=False)
event_published = models.BooleanField(_("Hook published events"),default=False)
signup_opened = models.BooleanField(_("Hook opened signups"),default=False)
@property
def plugs(self):
return {
"kaehmy": self.kaehmy_submit,
"ohlhafv": self.ohlhafv_submit,
"feed": self.feed_published,
"jobad": self.jobad_published,
"event": self.event_published,
"signup":self.signup_opened,
}
def parseData(self):
pass
def broadcast(self, message):
resp = requests.post(self.url, json=self.parseData(message))
logging.debug(f'Webhook API response: HTTP{resp.status_code}')
logging.debug(resp.content)
class GenericWebhook(BaseWebhook):
class Meta:
proxy = True
verbose_name = _('Webhook')
verbose_name_plural = _('Webhooks')
def __str__(self):
return 'Webhook "{}"'.format(self.name)
def parseData(self, message):
return {
"text": message
}
class TelegramHook(BaseWebhook):
"""Model containing the channel id of a Telegram chat"""
class Meta:
verbose_name = _('Telegram channel')
verbose_name_plural = _('Telegram channels')
channel_id = models.CharField(max_length=255, unique=True)
def __str__(self):
return 'Telegram channel: "{}"'.format(self.name)
def parseData(self, message):
return {
'text': message,
'chat_id': self.channel_id,
'parse_mode': 'Markdown'
}
auditlog.register(Tag)
auditlog.register(Feed)
auditlog.register(Event)
auditlog.register(SignupForm)
auditlog.register(Signup)
auditlog.register(JobAd)
auditlog.register(GenericWebhook)
auditlog.register(TelegramHook)
+15
View File
@@ -42,3 +42,18 @@ class TemplateQuestionTranslationOptions(TranslationOptions):
@register(JobAd)
class JobAdTranslationOptions(TranslationOptions):
fields = ('title', 'description', 'content',)
@register(BaseWebhook)
class BaseWebhookOptions(TranslationOptions):
fields = ()
@register(GenericWebhook)
class GenericWebhookOptions(TranslationOptions):
fields = ()
@register(TelegramHook)
class TelegramHookTranslationOptions(TranslationOptions):
fields = ()
+9
View File
@@ -0,0 +1,9 @@
from webapp.models import BaseWebhook
import logging
def processHooks(message: str, eventType: str):
allHooks = BaseWebhook.objects.all()
for hook in list(allHooks):
logging.debug(hook)
if (hook.plugs[eventType] == True):
hook.broadcast(message)