feat: init commint
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
from django.db import transaction
|
||||
from ninja import Router
|
||||
from ninja.errors import HttpError
|
||||
|
||||
@@ -18,6 +17,7 @@ from apps.channels.services import (
|
||||
ingest_inbound_message,
|
||||
queue_outbound_message,
|
||||
record_channel_receipt,
|
||||
retry_outbound_message,
|
||||
verify_webhook_signature,
|
||||
)
|
||||
from apps.modelhub.crypto import encrypt_secret
|
||||
@@ -182,18 +182,10 @@ def retry_channel_message(request, public_id: str):
|
||||
)
|
||||
if message is None:
|
||||
raise HttpError(404, "出站消息不存在")
|
||||
if message.status != "failed":
|
||||
raise HttpError(409, "仅失败消息可以重试")
|
||||
message.status = "queued"
|
||||
message.error_message = ""
|
||||
message.save(update_fields=["status", "error_message", "updated_at"])
|
||||
|
||||
def enqueue_delivery():
|
||||
from apps.channels.tasks import deliver_channel_message_task
|
||||
|
||||
deliver_channel_message_task.delay(message.id)
|
||||
|
||||
transaction.on_commit(enqueue_delivery)
|
||||
try:
|
||||
message = retry_outbound_message(message, actor=request.user)
|
||||
except ChannelError as error:
|
||||
raise HttpError(409, str(error)) from error
|
||||
return serialize_message(message)
|
||||
|
||||
|
||||
|
||||
@@ -96,6 +96,21 @@ def ingest_inbound_message(endpoint: ChannelEndpoint, payload: dict) -> ChannelM
|
||||
},
|
||||
result="success",
|
||||
)
|
||||
|
||||
if message.ticket_id:
|
||||
message_id = message.id
|
||||
|
||||
def process_ticket_feedback() -> None:
|
||||
from apps.tickets.automation import handle_customer_feedback
|
||||
|
||||
inbound = ChannelMessage.objects.get(id=message_id)
|
||||
handle_customer_feedback(
|
||||
inbound.ticket_id,
|
||||
inbound.text,
|
||||
channel_message_id=inbound.id,
|
||||
)
|
||||
|
||||
transaction.on_commit(process_ticket_feedback)
|
||||
return message
|
||||
|
||||
|
||||
@@ -185,6 +200,13 @@ def deliver_outbound_message(message_id: int) -> ChannelMessage:
|
||||
message.save()
|
||||
if message.status == "delivered":
|
||||
_confirm_delivered_reply(message)
|
||||
elif message.status == "failed" and message.customer_reply_task_id:
|
||||
from apps.tickets.automation import handle_customer_reply_delivery_failed
|
||||
|
||||
handle_customer_reply_delivery_failed(
|
||||
message.customer_reply_task_id,
|
||||
message.error_message,
|
||||
)
|
||||
OperationAuditLog.objects.create(
|
||||
user=message.created_by,
|
||||
module="channels",
|
||||
@@ -201,6 +223,35 @@ def deliver_outbound_message(message_id: int) -> ChannelMessage:
|
||||
return message
|
||||
|
||||
|
||||
@transaction.atomic
|
||||
def retry_outbound_message(message: ChannelMessage, *, actor=None) -> ChannelMessage:
|
||||
"""重新投递同一条失败消息,复用原幂等键和冻结回复版本。"""
|
||||
|
||||
message = ChannelMessage.objects.select_for_update(of=("self",)).get(id=message.id)
|
||||
if message.direction != "outbound" or message.status != "failed":
|
||||
raise ChannelError("仅失败的出站消息可以重试")
|
||||
message.status = "queued"
|
||||
message.error_message = ""
|
||||
message.save(update_fields=["status", "error_message", "updated_at"])
|
||||
OperationAuditLog.objects.create(
|
||||
user=actor,
|
||||
module="channels",
|
||||
action="message_delivery_retried",
|
||||
target_type="channel_message",
|
||||
target_id=str(message.public_id),
|
||||
request_snapshot={"idempotency_key": message.idempotency_key},
|
||||
result="success",
|
||||
)
|
||||
|
||||
def enqueue_delivery() -> None:
|
||||
from apps.channels.tasks import deliver_channel_message_task
|
||||
|
||||
deliver_channel_message_task.delay(message.id)
|
||||
|
||||
transaction.on_commit(enqueue_delivery)
|
||||
return message
|
||||
|
||||
|
||||
@transaction.atomic
|
||||
def queue_outbound_message(
|
||||
endpoint: ChannelEndpoint,
|
||||
@@ -372,4 +423,11 @@ def record_channel_receipt(endpoint: ChannelEndpoint, payload: dict) -> ChannelR
|
||||
message.save()
|
||||
if message.status == "delivered":
|
||||
_confirm_delivered_reply(message)
|
||||
elif message.status == "failed" and message.customer_reply_task_id:
|
||||
from apps.tickets.automation import handle_customer_reply_delivery_failed
|
||||
|
||||
handle_customer_reply_delivery_failed(
|
||||
message.customer_reply_task_id,
|
||||
message.error_message,
|
||||
)
|
||||
return receipt
|
||||
|
||||
Reference in New Issue
Block a user