Spaces:
Runtime error
Runtime error
File size: 3,992 Bytes
4327358 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
import ChatwootClient, {
ApiError,
public_contact_create_update_payload,
public_conversation,
} from '@figuro/chatwoot-sdk';
import { ILogger } from '@waha/apps/app_sdk/ILogger';
import { ContactAPI } from '@waha/apps/chatwoot/client/ContactAPI';
import { Conversation } from '@waha/apps/chatwoot/client/Conversation';
import { ConversationAPI } from '@waha/apps/chatwoot/client/ConversationAPI';
import { ChatWootAPIConfig } from '@waha/apps/chatwoot/client/interfaces';
import { InboxContactInfo } from '@waha/apps/chatwoot/contacts/InboxContactInfo';
import { Locale } from '@waha/apps/chatwoot/locale';
import { CacheForConfig } from '../cache/ConversationCache';
import { IConversationCache } from '../cache/IConversationCache';
export interface ContactInfo {
ChatId(): string;
AvatarUrl(): Promise<string | null>;
Attributes(): Promise<any>;
PublicContactCreate(): Promise<public_contact_create_update_payload>;
}
export class ContactConversationService {
private cache: IConversationCache;
constructor(
private config: ChatWootAPIConfig,
private contactAPI: ContactAPI,
private conversationAPI: ConversationAPI,
private accountAPI: ChatwootClient,
private logger: ILogger,
private l: Locale,
) {
this.cache = CacheForConfig(config);
}
private async upsertByContactInfo(
contactInfo: ContactInfo,
): Promise<public_conversation> {
const chatId = contactInfo.ChatId();
// Check cache for chat id
if (this.cache.has(chatId)) {
return this.cache.get(chatId);
}
//
// Find or create contact
//
let contact = await this.contactAPI.searchByAnyID(chatId);
if (!contact) {
const request = await contactInfo.PublicContactCreate();
contact = await this.contactAPI.create(chatId, request);
}
// Update custom attributes - always
const attributes = await contactInfo.Attributes();
this.logger.info(
`Updating contact custom attributes for chat.id: ${chatId}, contact.id: ${contact.data.id}`,
);
await this.contactAPI.updateCustomAttributes(contact.data, attributes);
// Update Avatar if nothing, but keep the original one if any
if (!contact.data.thumbnail) {
const avatarUrl = await contactInfo.AvatarUrl();
if (avatarUrl) {
this.contactAPI.updateAvatarUrlSafe(contact.data.id, avatarUrl);
}
}
this.logger.info(
`Using contact for chat.id: ${chatId}, contact.id: ${contact.sourceId}`,
);
//
// Get or create a conversation for this inbox
//
const conversation = await this.conversationAPI.upsert(contact.sourceId);
this.logger.info(
`Using conversation for chat.id: ${chatId}, conversation.id: ${conversation.id}, contact.id: ${contact.sourceId}`,
);
// Save to cache
this.cache.set(chatId, conversation);
return conversation;
}
public async ConversationByContact(
contactInfo: ContactInfo,
): Promise<Conversation> {
const chatId = contactInfo.ChatId();
const publicConversation = await this.upsertByContactInfo(contactInfo);
const conversation = new Conversation(
this.accountAPI,
this.config.accountId,
publicConversation.id,
);
conversation.onError = (err) => {
if (err instanceof ApiError) {
// invalidate cache
this.cache.delete(chatId);
this.logger.error(`ApiError: ${err.message}`);
this.logger.error(
`ApiError occurred, invalidating cache for chat.id: ${chatId}, conversation.id: ${publicConversation.id}`,
);
}
};
return conversation;
}
public ConversationById(conversationId: number): Conversation {
return new Conversation(
this.accountAPI,
this.config.accountId,
conversationId,
);
}
/**
* Build specific contact for inbox notifications
* @constructor
*/
public async InboxNotifications() {
return this.ConversationByContact(new InboxContactInfo(this.l));
}
}
|