File size: 3,556 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
import { Knex } from 'knex';

import { ChatwootMessageRepository } from './ChatwootMessageRepository';
import { MessageMappingRepository } from './MessageMappingRepository';
import {
  ChatWootCombinedKey,
  ChatwootMessage,
  MessageMapping,
  WhatsAppMessage,
} from './types';
import { WhatsAppMessageRepository } from './WhatsAppMessageRepository';

export class MessageMappingService {
  constructor(
    private readonly knex: Knex,
    private whatsAppMessageRepository: WhatsAppMessageRepository,
    private chatwootMessageRepository: ChatwootMessageRepository,
    private messageMappingRepository: MessageMappingRepository,
  ) {}

  /**
   * Cleans up messages older than the specified date
   * @param removeAfter Date before which messages should be removed
   * @returns Object containing the number of deleted WhatsApp and Chatwoot messages
   */
  async cleanup(removeAfter: Date): Promise<number> {
    const trx = await this.knex.transaction();
    try {
      // Delete WhatsApp messages older than removeAfter
      const whatsapp =
        await this.whatsAppMessageRepository.deleteMessagesOlderThan(
          trx,
          removeAfter,
        );
      const chatwoot =
        await this.chatwootMessageRepository.deleteMessagesOlderThan(
          trx,
          removeAfter,
        );
      await trx.commit();
      return whatsapp + chatwoot;
    } finally {
      await trx.commit();
    }
  }

  async map(
    chatwoot: ChatwootMessage,
    whatsapp: WhatsAppMessage,
    part?: number,
  ): Promise<MessageMapping> {
    const trx = await this.knex.transaction();
    try {
      const chatwootMessage =
        await this.chatwootMessageRepository.upsertWithTrx(trx, chatwoot);
      chatwoot.id = chatwootMessage.id;
      const whatsappMessage =
        await this.whatsAppMessageRepository.upsertWithTrx(trx, whatsapp);
      whatsapp.id = whatsappMessage.id;
      const mapping = await this.messageMappingRepository.upsertMappingWithTrx(
        trx,
        chatwootMessage,
        whatsappMessage,
        part ?? 1,
      );
      return mapping;
    } catch (e) {
      await trx.rollback();
      throw e;
    } finally {
      await trx.commit();
    }
  }

  async getChatWootMessage(
    whatsapp: Pick<WhatsAppMessage, 'chat_id' | 'message_id'>,
  ): Promise<ChatwootMessage | null> {
    const message = await this.whatsAppMessageRepository.getByMessageId(
      whatsapp.message_id,
    );
    if (!message) {
      return null;
    }
    const mapping = await this.messageMappingRepository.getByWhatsAppMessageId(
      message.id,
    );
    if (!mapping) {
      return null;
    }
    const chatwoot = await this.chatwootMessageRepository.getById(
      mapping.chatwoot_message_id,
    );
    if (!chatwoot) {
      return null;
    }
    return chatwoot;
  }

  async getWhatsAppMessage(
    chatwoot: ChatWootCombinedKey,
  ): Promise<WhatsAppMessage[]> {
    const messages =
      await this.chatwootMessageRepository.getByCombinedKey(chatwoot);
    if (!messages) {
      return [];
    }
    const mappings = [];
    for (const message of messages) {
      const mapping =
        await this.messageMappingRepository.getByChatwootMessageId(message.id);
      if (mapping) {
        mappings.push(mapping);
      }
    }
    const whatsapp = [];
    for (const mapping of mappings) {
      const message = await this.whatsAppMessageRepository.getById(
        mapping.whatsapp_message_id,
      );
      if (message) {
        whatsapp.push(message);
      }
    }
    return whatsapp;
  }
}