Skip to content

Commit

Permalink
Merge branch 'main' into DEVEXP-339_oneOf-with-XOR
Browse files Browse the repository at this point in the history
  • Loading branch information
asein-sinch authored Mar 18, 2024
2 parents 2709896 + 7c7e0bd commit 5ed2591
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 48 deletions.
97 changes: 54 additions & 43 deletions examples/webhooks/src/services/conversation.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,35 +24,39 @@ export class ConversationService {
};

private buildTextMessage(contactMessage: ContactMessage) {
if ('text_message' in contactMessage) {
if ('text_message' in contactMessage && contactMessage.text_message) {
return messageBuilder.text({
text: `Parrot mode 🦜: ${contactMessage.text_message.text}`,
});
}
if ('media_message' in contactMessage) {
if ('media_message' in contactMessage && contactMessage.media_message) {
return messageBuilder.media({
url: contactMessage.media_message.url,
});
}
if ('fallback_message' in contactMessage) {
if ('fallback_message' in contactMessage && contactMessage.fallback_message && contactMessage.fallback_message.reason) {
return messageBuilder.text({
text: `Error: ${contactMessage.fallback_message.reason.code} (${contactMessage.fallback_message.reason.sub_code})\n${contactMessage.fallback_message.reason.description}`
});
}
return messageBuilder.text({
text: `Impossible to handle the incoming message`,
});
}

handleEvent(event: ConversationWebhookEventParsed): void {
switch (event.trigger) {
case 'MESSAGE_INBOUND':
console.log('\n## MESSAGE_INBOUND');
const contactMessage = event.message.contact_message;
const channelIdentityTo = event.message.channel_identity;
console.log(`A new message has been received on the channel '${channelIdentityTo.channel}' (identity: ${channelIdentityTo.identity}) from the contact ID '${event.message.contact_id}':\n${JSON.stringify(contactMessage, null, 2)}`);
const message = event.message!;
const contactMessage = message.contact_message!;
const channelIdentityTo = message.channel_identity!;
console.log(`A new message has been received on the channel '${channelIdentityTo.channel}' (identity: ${channelIdentityTo.identity}) from the contact ID '${message.contact_id}':\n${JSON.stringify(contactMessage, null, 2)}`);
const requestData: SendMessageRequestData = {
sendMessageRequestBody: {
app_id: event.app_id,
app_id: event.app_id!,
recipient: {
contact_id: event.message.contact_id,
contact_id: message.contact_id,
},
message: this.buildTextMessage(contactMessage),
ttl: '5s',
Expand All @@ -67,24 +71,26 @@ export class ConversationService {
break;
case 'MESSAGE_INBOUND_SMART_CONVERSATION_REDACTION':
console.log('\n## MESSAGE_INBOUND_SMART_CONVERSATION_REDACTION');
if ('text_message' in event.message_redaction.contact_message) {
console.log(`A.I. analyzed and redacted message:\n${event.message_redaction.contact_message.text_message.text}`);
const messageRedaction = event.message_redaction!;
if ('text_message' in messageRedaction.contact_message!) {
console.log(`A.I. analyzed and redacted message:\n${messageRedaction.contact_message.text_message!.text}`);
}
break;
case 'MESSAGE_SUBMIT':
console.log('\n## MESSAGE_SUBMIT');
const submittedMessage = event.message_submit_notification.submitted_message;
const channelIdentityFrom = event.message_submit_notification.channel_identity;
console.log(`The following message has been submitted on the channel '${channelIdentityFrom.channel}' (identity: ${channelIdentityFrom.identity}) to the contact ID '${event.message_submit_notification.contact_id}':\n${JSON.stringify(submittedMessage, null, 2)}`);
const messageSubmitNotification = event.message_submit_notification!;
const submittedMessage = messageSubmitNotification.submitted_message!;
const channelIdentityFrom = messageSubmitNotification.channel_identity!;
console.log(`The following message has been submitted on the channel '${channelIdentityFrom.channel}' (identity: ${channelIdentityFrom.identity}) to the contact ID '${messageSubmitNotification.contact_id}':\n${JSON.stringify(submittedMessage, null, 2)}`);
break;
case 'SMART_CONVERSATIONS':
console.log('\n## SMART_CONVERSATIONS');
const analysisResult = event.smart_conversation_notification.analysis_results;
const analysisResult = event.smart_conversation_notification!.analysis_results!;
if (analysisResult.ml_sentiment_result) {
console.log(`The sentiment of the message is '${analysisResult.ml_sentiment_result[0].sentiment}' with a score of ${analysisResult.ml_sentiment_result[0].score}`);
}
if (analysisResult.ml_nlu_result) {
console.log(`The intent of the message is '${analysisResult.ml_nlu_result[0].intent}' with a score of ${analysisResult.ml_nlu_result[0].score}. Other intents are:\n${analysisResult.ml_nlu_result[0].results.map((result) => '- ' + result.intent + ': ' + result.score).join('\n')}`);
console.log(`The intent of the message is '${analysisResult.ml_nlu_result[0].intent}' with a score of ${analysisResult.ml_nlu_result[0].score}. Other intents are:\n${analysisResult.ml_nlu_result[0].results?.map((result) => '- ' + result.intent + ': ' + result.score).join('\n')}`);
}
if (analysisResult.ml_pii_result) {
console.log(`Message with masked PII:\n${analysisResult.ml_pii_result[0].masked}`);
Expand All @@ -98,100 +104,105 @@ export class ConversationService {
break;
case 'MESSAGE_DELIVERY':
console.log('\n## MESSAGE_DELIVERY');
const messageDeliveryStatus = event.message_delivery_report.status;
const messageDelivery = event.message_delivery_report!;
const messageDeliveryStatus = messageDelivery.status;
console.log(`Message delivery status: '${messageDeliveryStatus}'`);
if ('FAILED' === messageDeliveryStatus) {
const failedDeliveryReason = event.message_delivery_report.reason;
const failedDeliveryReason = messageDelivery.reason!;
console.log(`Reason: ${failedDeliveryReason.code} (${failedDeliveryReason.sub_code})`);
console.log(`Description: ${failedDeliveryReason.description}`);
}
break;
case 'EVENT_INBOUND':
console.log('\n## EVENT_INBOUND');
if ('contact_event' in event.event) {
console.log(`A new contact event has been received on the channel '${event.event.channel_identity.channel}' (${event.event.channel_identity.identity}) from the contact ID '${event.event.contact_id}'`);
const inboundEvent = event.event!;
if ('contact_event' in inboundEvent) {
console.log(`A new contact event has been received on the channel '${inboundEvent.channel_identity?.channel}' (${inboundEvent.channel_identity?.identity}) from the contact ID '${inboundEvent.contact_id}'`);
}
if ('contact_message_event' in event.event) {
const contactMessageEvent = event.event.contact_message_event;
console.log(`A new contact message event has been received on the channel '${event.event.channel_identity.channel}' (${event.event.channel_identity.identity}) from the contact ID '${event.event.contact_id}'`);
console.log(`Payment status: ${contactMessageEvent.payment_status_update_event.payment_status}`);
if ('contact_message_event' in inboundEvent) {
const contactMessageEvent = inboundEvent.contact_message_event!;
console.log(`A new contact message event has been received on the channel '${inboundEvent.channel_identity?.channel}' (${inboundEvent.channel_identity?.identity}) from the contact ID '${inboundEvent.contact_id}'`);
console.log(`Payment status: ${contactMessageEvent.payment_status_update_event?.payment_status}`);
}
break;
case 'EVENT_DELIVERY':
console.log('\n## EVENT_DELIVERY');
const eventDeliveryStatus = event.event_delivery_report.status;
const eventDeliveryReport = event.event_delivery_report!;
const eventDeliveryStatus = eventDeliveryReport.status;
console.log(`Event delivery status: '${eventDeliveryStatus}'`);
if ('FAILED' === eventDeliveryStatus) {
const failedDeliveryReason = event.event_delivery_report.reason;
const failedDeliveryReason = eventDeliveryReport.reason!;
console.log(`Reason: ${failedDeliveryReason.code} (${failedDeliveryReason.sub_code})`);
console.log(`Description: ${failedDeliveryReason.description}`);
}
break;
case 'CONVERSATION_START':
console.log('\n## CONVERSATION_START');
const conversationStart = event.conversation_start_notification.conversation;
const conversationStart = event.conversation_start_notification!.conversation!;
console.log(`The conversation '${conversationStart.id}' has started on the channel ${conversationStart.active_channel}`);
break;
case 'CONVERSATION_STOP':
console.log('\n## CONVERSATION_STOP');
const conversationStop = event.conversation_stop_notification.conversation;
const conversationStop = event.conversation_stop_notification!.conversation!;
console.log(`The conversation '${conversationStop.id}' has been stopped.\nThe last message was sent at '${conversationStop.last_received}' on the channel '${conversationStop.active_channel}'`);
break;
case 'CONVERSATION_DELETE':
console.log('\n## CONVERSATION_DELETE');
const conversationDelete = event.conversation_delete_notification.conversation;
const conversationDelete = event.conversation_delete_notification!.conversation!;
console.log(`The conversation '${conversationDelete.id}' has been deleted.\nThe last message was sent at '${conversationDelete.last_received}' on the channel '${conversationDelete.active_channel}'`);
break;
case 'CONTACT_CREATE':
console.log('\n## CONTACT_CREATE');
console.log(`A new contact has been created: '${event.contact_create_notification.contact.display_name}'`);
console.log(`List of channels:\n${event.contact_create_notification.contact.channel_identities.map((channelIdentity) => channelIdentity.channel).join('\n')}`);
const createNotificationContact = event.contact_create_notification!.contact!;
console.log(`A new contact has been created: '${createNotificationContact.display_name}'`);
console.log(`List of channels:\n${createNotificationContact.channel_identities?.map((channelIdentity) => channelIdentity.channel).join('\n')}`);
break;
case 'CONTACT_DELETE':
console.log('\n## CONTACT_DELETE');
console.log(`A contact has been deleted: '${event.contact_delete_notification.contact.display_name}'`);
console.log(`A contact has been deleted: '${event.contact_delete_notification!.contact!.display_name}'`);
break;
case 'CONTACT_MERGE':
console.log('\n## CONTACT_MERGE');
const deletedContact = event.contact_merge_notification.deleted_contact;
const preservedContact = event.contact_merge_notification.preserved_contact;
const mergeNotification = event.contact_merge_notification!
const deletedContact = mergeNotification.deleted_contact!;
const preservedContact = mergeNotification.preserved_contact!;
console.log(`The contact ID '${deletedContact.id}' (${deletedContact.display_name}) has been merged into the contact ID '${preservedContact.id}' (${preservedContact.display_name})`);
break;
case 'CONTACT_UPDATE':
console.log('\n## CONTACT_UPDATE');
console.log(`A contact has been updated: '${event.contact_update_notification.contact.display_name}'`);
console.log(`A contact has been updated: '${event.contact_update_notification!.contact?.display_name}'`);
break;
case 'CONTACT_IDENTITIES_DUPLICATION':
console.log('\n## CONTACT_IDENTITIES_DUPLICATION');
const duplicatedEntities = event.duplicated_contact_identities_notification.duplicated_identities;
const duplicatedEntities = event.duplicated_contact_identities_notification.duplicated_identities!;
for(const duplication of duplicatedEntities) {
console.log(`The channel ${duplication.channel} contains the following duplicated contact IDs: ${duplication.contact_ids.join(', ')}`);
console.log(`The channel ${duplication.channel} contains the following duplicated contact IDs: ${duplication.contact_ids?.join(', ')}`);
}
break;
case 'CAPABILITY':
console.log('\n## CAPABILITY');
const capabilityNotification = event.capability_notification;
const capabilityNotification = event.capability_notification!;
console.log(`Capability for the contact ID '${capabilityNotification.contact_id}':`)
console.log(`Channel: '${capabilityNotification.channel}' - Identity: ${capabilityNotification.identity}`);
if ('reason' in event.capability_notification) {
const capabilityUnknownReason = event.capability_notification.reason;
if ('reason' in capabilityNotification) {
const capabilityUnknownReason = capabilityNotification.reason!;
console.log(`Reason: ${capabilityUnknownReason.code} (${capabilityUnknownReason.sub_code})`);
console.log(`Description: ${capabilityUnknownReason.description}`);
}
break;
case 'OPT_IN':
console.log('\n## OPT_IN')
const optIn = event.opt_in_notification;
const optIn = event.opt_in_notification!;
console.log(`Status of the opt-in registration for the identity '${optIn.identity}' on the channel '${optIn.channel}': '${optIn.status}'`);
break;
case 'OPT_OUT':
console.log('\n## OPT_OUT')
const optOut = event.opt_out_notification;
const optOut = event.opt_out_notification!;
console.log(`Status of the opt-out registration for the identity '${optOut.identity}' on the channel '${optOut.channel}': '${optOut.status}'`);
break;
case 'CHANNEL_EVENT':
console.log('\n## CHANNEL_EVENT')
const channelEvent = event.channel_event_notification;
const channelEvent = event.channel_event_notification!;
console.log(`The event '${channelEvent.channel_event.event_type}' occurred on the channel '${channelEvent.channel_event.channel}'.`);
if ('additional_data' in channelEvent) {
console.log(`Additional data:\n${JSON.stringify(channelEvent.additional_data, null, 2)}`);
Expand All @@ -202,7 +213,7 @@ export class ConversationService {
break;
case 'UNSUPPORTED':
console.log('\n## UNSUPPORTED')
const unsupportedCallback = event.unsupported_callback;
const unsupportedCallback = event.unsupported_callback!;
console.log(`The channel ${unsupportedCallback.channel} has received an unsupported payload:\n${unsupportedCallback.payload}`);
break;
default:
Expand Down
7 changes: 3 additions & 4 deletions examples/webhooks/src/services/voice.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { Injectable } from '@nestjs/common';
import { Response } from 'express';
import {
aceActionHelper,
aceInstructionHelper,
AceRequest,
AceSvamletBuilder,
DiceRequest,
Expand Down Expand Up @@ -45,7 +44,7 @@ export class VoiceService {
}

private handleIceRequest(event: IceRequest, res: Response) {
console.log(`ICE request: CLI = ${event.cli} - To = ${event.to.endpoint} (${event.to.type})`)
console.log(`ICE request: CLI = ${event.cli} - To = ${event.to?.endpoint} (${event.to?.type})`)
const iceResponse = new IceSvamletBuilder()
.setAction(iceActionHelper.hangup())
.addInstruction(iceInstructionHelper.say('Thank you for calling Sinch! This call will now end.', 'en-US'))
Expand All @@ -54,7 +53,7 @@ export class VoiceService {
}

private handleAceRequest(event: AceRequest, res: Response) {
console.log(`ACE request: Call answered at '${event.timestamp.toISOString()}'`);
console.log(`ACE request: Call answered at '${event.timestamp?.toISOString()}'`);
const aceResponse = new AceSvamletBuilder()
.setAction(aceActionHelper.runMenu({
barge: true,
Expand Down Expand Up @@ -87,7 +86,7 @@ export class VoiceService {
}

private handleDiceRequest(event: DiceRequest, res: Response) {
console.log(`DICE request: Call disconnected at '${event.timestamp.toISOString()}' with the reason '${event.reason}'.`);
console.log(`DICE request: Call disconnected at '${event.timestamp?.toISOString()}' with the reason '${event.reason}'.`);
res.status(200).send();
}

Expand Down
2 changes: 1 addition & 1 deletion examples/webhooks/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"baseUrl": "./",
"incremental": true,
"skipLibCheck": true,
"strictNullChecks": false,
"strictNullChecks": true,
"noImplicitAny": false,
"strictBindCallApply": false,
"forceConsistentCasingInFileNames": false,
Expand Down

0 comments on commit 5ed2591

Please sign in to comment.