mirror of
				https://github.com/mealie-recipes/mealie.git
				synced 2025-10-30 17:53:31 -04:00 
			
		
		
		
	fix: Restore Webhook Test Functionality (#3857)
Co-authored-by: Kuchenpirat <24235032+Kuchenpirat@users.noreply.github.com>
This commit is contained in:
		| @@ -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, | ||||||
|   | |||||||
| @@ -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(); | ||||||
|   | |||||||
| @@ -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)}`, {}); | ||||||
|  |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -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 | ||||||
|   | |||||||
| @@ -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) | ||||||
|   | |||||||
| @@ -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 | ||||||
|   | |||||||
| @@ -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]) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user