fix: Restore Webhook Test Functionality (#3857)

Co-authored-by: Kuchenpirat <24235032+Kuchenpirat@users.noreply.github.com>
This commit is contained in:
Michael Genson 2024-07-06 14:10:01 -05:00 committed by GitHub
parent aa6e109162
commit 6e6ae80c46
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 50 additions and 9 deletions

View File

@ -18,8 +18,6 @@
icon: $globals.icons.testTube, icon: $globals.icons.testTube,
text: $tc('general.test'), text: $tc('general.test'),
event: 'test', event: 'test',
// TODO: There is no functionality hooked up to this. Enable it when there is
disabled: true,
}, },
{ {
icon: $globals.icons.save, icon: $globals.icons.save,

View File

@ -64,7 +64,6 @@ export const useGroupWebhooks = function () {
newDt.setMinutes(Number(minutes)); newDt.setMinutes(Number(minutes));
updateData.scheduledTime = `${pad(newDt.getUTCHours(), 2)}:${pad(newDt.getUTCMinutes(), 2)}`; updateData.scheduledTime = `${pad(newDt.getUTCHours(), 2)}:${pad(newDt.getUTCMinutes(), 2)}`;
console.log(updateData.scheduledTime);
const payload = { const payload = {
...updateData, ...updateData,
@ -85,7 +84,14 @@ export const useGroupWebhooks = function () {
if (data) { if (data) {
this.refreshAll(); this.refreshAll();
} }
loading.value = false;
}, },
async testOne(id: string | number) {
loading.value = true;
await api.groupWebhooks.testOne(id);
loading.value = false;
}
}; };
const webhooks = actions.getAll(); const webhooks = actions.getAll();

View File

@ -6,9 +6,15 @@ const prefix = "/api";
const routes = { const routes = {
webhooks: `${prefix}/groups/webhooks`, webhooks: `${prefix}/groups/webhooks`,
webhooksId: (id: string | number) => `${prefix}/groups/webhooks/${id}`, webhooksId: (id: string | number) => `${prefix}/groups/webhooks/${id}`,
webhooksIdTest: (id: string | number) => `${prefix}/groups/webhooks/${id}/test`,
}; };
export class WebhooksAPI extends BaseCRUDAPI<CreateWebhook, ReadWebhook> { export class WebhooksAPI extends BaseCRUDAPI<CreateWebhook, ReadWebhook> {
baseRoute = routes.webhooks; baseRoute = routes.webhooks;
itemRoute = routes.webhooksId; itemRoute = routes.webhooksId;
itemTestRoute = routes.webhooksIdTest;
async testOne(itemId: string | number) {
return await this.requests.post<null>(`${this.itemTestRoute(itemId)}`, {});
}
} }

View File

@ -10,8 +10,6 @@
</v-card-text> </v-card-text>
</BasePageTitle> </BasePageTitle>
<BannerExperimental />
<BaseButton create @click="actions.createOne()" /> <BaseButton create @click="actions.createOne()" />
<v-expansion-panels class="mt-2"> <v-expansion-panels class="mt-2">
<v-expansion-panel v-for="(webhook, index) in webhooks" :key="index" class="my-2 left-border rounded"> <v-expansion-panel v-for="(webhook, index) in webhooks" :key="index" class="my-2 left-border rounded">
@ -36,6 +34,7 @@
:webhook="webhook" :webhook="webhook"
@save="actions.updateOne($event)" @save="actions.updateOne($event)"
@delete="actions.deleteOne($event)" @delete="actions.deleteOne($event)"
@test="actions.testOne($event).then(() => alert.success($tc('events.test-message-sent')))"
/> />
</v-expansion-panel-content> </v-expansion-panel-content>
</v-expansion-panel> </v-expansion-panel>
@ -47,6 +46,7 @@
import { defineComponent } from "@nuxtjs/composition-api"; import { defineComponent } from "@nuxtjs/composition-api";
import { useGroupWebhooks, timeUTC } from "~/composables/use-group-webhooks"; import { useGroupWebhooks, timeUTC } from "~/composables/use-group-webhooks";
import GroupWebhookEditor from "~/components/Domain/Group/GroupWebhookEditor.vue"; import GroupWebhookEditor from "~/components/Domain/Group/GroupWebhookEditor.vue";
import { alert } from "~/composables/use-toast";
export default defineComponent({ export default defineComponent({
components: { GroupWebhookEditor }, components: { GroupWebhookEditor },
@ -55,6 +55,7 @@ export default defineComponent({
const { actions, webhooks } = useGroupWebhooks(); const { actions, webhooks } = useGroupWebhooks();
return { return {
alert,
webhooks, webhooks,
actions, actions,
timeUTC timeUTC

View File

@ -1,7 +1,7 @@
from datetime import datetime from datetime import datetime
from functools import cached_property from functools import cached_property
from fastapi import APIRouter, Depends from fastapi import APIRouter, BackgroundTasks, Depends
from pydantic import UUID4 from pydantic import UUID4
from mealie.routes._base.base_controllers import BaseUserController from mealie.routes._base.base_controllers import BaseUserController
@ -10,7 +10,7 @@ from mealie.routes._base.mixins import HttpRepo
from mealie.schema import mapper from mealie.schema import mapper
from mealie.schema.group.webhook import CreateWebhook, ReadWebhook, SaveWebhook, WebhookPagination from mealie.schema.group.webhook import CreateWebhook, ReadWebhook, SaveWebhook, WebhookPagination
from mealie.schema.response.pagination import PaginationQuery from mealie.schema.response.pagination import PaginationQuery
from mealie.services.scheduler.tasks.post_webhooks import post_group_webhooks from mealie.services.scheduler.tasks.post_webhooks import post_group_webhooks, post_single_webhook
router = APIRouter(prefix="/groups/webhooks", tags=["Groups: Webhooks"]) router = APIRouter(prefix="/groups/webhooks", tags=["Groups: Webhooks"])
@ -52,6 +52,11 @@ class ReadWebhookController(BaseUserController):
def get_one(self, item_id: UUID4): def get_one(self, item_id: UUID4):
return self.mixins.get_one(item_id) return self.mixins.get_one(item_id)
@router.post("/{item_id}/test")
def test_one(self, item_id: UUID4, bg_tasks: BackgroundTasks):
webhook = self.mixins.get_one(item_id)
bg_tasks.add_task(post_single_webhook, webhook, "Test Webhook")
@router.put("/{item_id}", response_model=ReadWebhook) @router.put("/{item_id}", response_model=ReadWebhook)
def update_one(self, item_id: UUID4, data: CreateWebhook): def update_one(self, item_id: UUID4, data: CreateWebhook):
return self.mixins.update_one(data, item_id) return self.mixins.update_one(data, item_id)

View File

@ -3,7 +3,7 @@ from datetime import date, datetime
from enum import Enum, auto from enum import Enum, auto
from typing import Any from typing import Any
from pydantic import UUID4, field_validator from pydantic import UUID4, SerializeAsAny, field_validator
from ...schema._mealie.mealie_model import MealieModel from ...schema._mealie.mealie_model import MealieModel
@ -179,7 +179,7 @@ class Event(MealieModel):
message: EventBusMessage message: EventBusMessage
event_type: EventTypes event_type: EventTypes
integration_id: str integration_id: str
document_data: EventDocumentDataBase document_data: SerializeAsAny[EventDocumentDataBase]
# set at instantiation # set at instantiation
event_id: UUID4 | None = None event_id: UUID4 | None = None

View File

@ -4,10 +4,14 @@ from pydantic import UUID4
from mealie.db.db_setup import session_context from mealie.db.db_setup import session_context
from mealie.repos.all_repositories import get_repositories from mealie.repos.all_repositories import get_repositories
from mealie.schema.group.webhook import ReadWebhook
from mealie.schema.response.pagination import PaginationQuery from mealie.schema.response.pagination import PaginationQuery
from mealie.services.event_bus_service.event_bus_listeners import WebhookEventListener
from mealie.services.event_bus_service.event_bus_service import EventBusService from mealie.services.event_bus_service.event_bus_service import EventBusService
from mealie.services.event_bus_service.event_types import ( from mealie.services.event_bus_service.event_types import (
INTERNAL_INTEGRATION_ID, INTERNAL_INTEGRATION_ID,
Event,
EventBusMessage,
EventDocumentType, EventDocumentType,
EventOperation, EventOperation,
EventTypes, EventTypes,
@ -61,3 +65,24 @@ def post_group_webhooks(start_dt: datetime | None = None, group_id: UUID4 | None
event_type=event_type, event_type=event_type,
document_data=event_document_data, document_data=event_document_data,
) )
def post_single_webhook(webhook: ReadWebhook, message: str = "") -> None:
dt = datetime.min.replace(tzinfo=timezone.utc)
event_type = EventTypes.webhook_task
event_document_data = EventWebhookData(
document_type=EventDocumentType.mealplan,
operation=EventOperation.info,
webhook_start_dt=dt,
webhook_end_dt=dt,
)
event = Event(
message=EventBusMessage.from_type(event_type, body=message),
event_type=event_type,
integration_id=INTERNAL_INTEGRATION_ID,
document_data=event_document_data,
)
listener = WebhookEventListener(webhook.group_id)
listener.publish_to_subscribers(event, [webhook])