@builderbot/provider-email 1.3.15-alpha.8 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -27,8 +27,13 @@ export declare class EmailCoreVendor extends EventEmitter {
27
27
  private handleDisconnect;
28
28
  /**
29
29
  * Start IMAP IDLE listener for real-time email notifications
30
+ * This runs in the background and doesn't block the initialization
30
31
  */
31
32
  private startIdleListener;
33
+ /**
34
+ * Run the IDLE loop in background without blocking
35
+ */
36
+ private runIdleLoop;
32
37
  /**
33
38
  * Fetch new emails from a sequence range
34
39
  */
@@ -1 +1 @@
1
- {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/email/core.ts"],"names":[],"mappings":"AAGA,OAAO,YAAY,MAAM,aAAa,CAAA;AAGtC,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,gBAAgB,EAAmB,MAAM,UAAU,CAAA;AAEtG;;;GAGG;AACH,qBAAa,eAAgB,SAAQ,YAAY;IAC7C,OAAO,CAAC,UAAU,CAAwB;IAC1C,OAAO,CAAC,eAAe,CAA2B;IAClD,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,WAAW,CAAiB;IACpC,OAAO,CAAC,iBAAiB,CAAY;IACrC,OAAO,CAAC,oBAAoB,CAAa;IACzC,OAAO,CAAC,cAAc,CAAe;gBAEzB,MAAM,EAAE,kBAAkB;IAMtC;;OAEG;IACH,OAAO,CAAC,cAAc;IAkBtB;;OAEG;IACU,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IA+CrC;;OAEG;YACW,gBAAgB;IAuB9B;;OAEG;YACW,iBAAiB;IAyC/B;;OAEG;YACW,cAAc;IAqC5B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAgE3B;;OAEG;IACH,OAAO,CAAC,cAAc;IAetB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAmBxB;;OAEG;IACU,SAAS,CAClB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,gBAAgB,GAC3B,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAuDjC;;OAEG;IACU,YAAY,CACrB,eAAe,EAAE,eAAe,EAChC,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,WAAW,GAAG,YAAY,CAAC,GAC7D,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAuBjC;;OAEG;IACU,kBAAkB,CAAC,GAAG,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAetG;;OAEG;IACU,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAoBxC;;OAEG;IACI,eAAe,IAAI,OAAO;IAIjC;;OAEG;IACU,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;CAU9C"}
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/email/core.ts"],"names":[],"mappings":"AAGA,OAAO,YAAY,MAAM,aAAa,CAAA;AAGtC,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,gBAAgB,EAAmB,MAAM,UAAU,CAAA;AAEtG;;;GAGG;AACH,qBAAa,eAAgB,SAAQ,YAAY;IAC7C,OAAO,CAAC,UAAU,CAAwB;IAC1C,OAAO,CAAC,eAAe,CAA2B;IAClD,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,WAAW,CAAiB;IACpC,OAAO,CAAC,iBAAiB,CAAY;IACrC,OAAO,CAAC,oBAAoB,CAAa;IACzC,OAAO,CAAC,cAAc,CAAe;gBAEzB,MAAM,EAAE,kBAAkB;IAMtC;;OAEG;IACH,OAAO,CAAC,cAAc;IAkBtB;;OAEG;IACU,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IA+CrC;;OAEG;YACW,gBAAgB;IAuB9B;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAiBzB;;OAEG;YACW,WAAW;IA2BzB;;OAEG;YACW,cAAc;IAoD5B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IA8F3B;;OAEG;IACH,OAAO,CAAC,cAAc;IAetB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAmBxB;;OAEG;IACU,SAAS,CAClB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,gBAAgB,GAC3B,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAuDjC;;OAEG;IACU,YAAY,CACrB,eAAe,EAAE,eAAe,EAChC,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,WAAW,GAAG,YAAY,CAAC,GAC7D,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAuBjC;;OAEG;IACU,kBAAkB,CAAC,GAAG,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAetG;;OAEG;IACU,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAoBxC;;OAEG;IACI,eAAe,IAAI,OAAO;IAIjC;;OAEG;IACU,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;CAU9C"}
@@ -9,6 +9,7 @@ import type { IEmailProviderArgs, EmailBotContext, EmailSendOptions } from '../t
9
9
  */
10
10
  declare class EmailProvider extends ProviderClass<EmailCoreVendor> {
11
11
  globalVendorArgs: IEmailProviderArgs;
12
+ private conversationContexts;
12
13
  constructor(args: IEmailProviderArgs);
13
14
  /**
14
15
  * Initialize the email vendor (IMAP/SMTP connections)
@@ -1 +1 @@
1
- {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/email/provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AAKzE,OAAO,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAA;AACxC,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAErF;;;;GAIG;AACH,cAAM,aAAc,SAAQ,aAAa,CAAC,eAAe,CAAC;IACtD,gBAAgB,EAAE,kBAAkB,CAAA;gBAExB,IAAI,EAAE,kBAAkB;IA2BpC;;OAEG;cACa,UAAU,IAAI,OAAO,CAAC,eAAe,CAAC;IAUtD;;OAEG;IACH,SAAS,CAAC,oBAAoB,IAAI,IAAI;IAUtC;;OAEG;IACH,SAAS,CAAC,mBAAmB,IAAI,IAAI;IAErC;;OAEG;IACH,OAAO,CAAC,SAAS,CAEhB;IAED;;OAEG;IACH,OAAO,CAAC,cAAc,CAKrB;IAED;;OAEG;IACH,SAAS,CAAC,SAAS;;wBAGK,GAAG;QAwB1B;IAED;;;;;OAKG;IACG,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,gBAAgB,GAAG,OAAO,CAAC,GAAG,CAAC;IAmBtG;;;;;;OAMG;IACG,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,GAAG,CAAC;IAgBzG;;;;;OAKG;IACG,KAAK,CACP,GAAG,EAAE,eAAe,EACpB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,WAAW,GAAG,YAAY,CAAC,GAC7D,OAAO,CAAC,GAAG,CAAC;IAIf;;;;OAIG;IACG,QAAQ,CACV,GAAG,EAAE,OAAO,CAAC,eAAe,GAAG,UAAU,CAAC,EAC1C,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,GACtD,OAAO,CAAC,MAAM,CAAC;IA+BlB;;;OAGG;IACH,cAAc,CAAC,GAAG,EAAE,eAAe;IAInC;;;OAGG;IACH,OAAO,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO;IAItC;;;OAGG;IACH,WAAW,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,GAAG,SAAS;IAIrD;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAKpC;AAED,OAAO,EAAE,aAAa,EAAE,CAAA"}
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/email/provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AAKzE,OAAO,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAA;AACxC,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAErF;;;;GAIG;AACH,cAAM,aAAc,SAAQ,aAAa,CAAC,eAAe,CAAC;IACtD,gBAAgB,EAAE,kBAAkB,CAAA;IAGpC,OAAO,CAAC,oBAAoB,CAA0C;gBAE1D,IAAI,EAAE,kBAAkB;IA4BpC;;OAEG;cACa,UAAU,IAAI,OAAO,CAAC,eAAe,CAAC;IAYtD;;OAEG;IACH,SAAS,CAAC,oBAAoB,IAAI,IAAI;IAUtC;;OAEG;IACH,SAAS,CAAC,mBAAmB,IAAI,IAAI;IAErC;;OAEG;IACH,OAAO,CAAC,SAAS,CAEhB;IAED;;OAEG;IACH,OAAO,CAAC,cAAc,CAKrB;IAED;;OAEG;IACH,SAAS,CAAC,SAAS;;wBAKS,GAAG;QAiC9B;IAED;;;;;OAKG;IACG,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,gBAAgB,GAAG,OAAO,CAAC,GAAG,CAAC;IA6BtG;;;;;;OAMG;IACG,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,GAAG,CAAC;IAgBzG;;;;;OAKG;IACG,KAAK,CACP,GAAG,EAAE,eAAe,EACpB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,WAAW,GAAG,YAAY,CAAC,GAC7D,OAAO,CAAC,GAAG,CAAC;IAIf;;;;OAIG;IACG,QAAQ,CACV,GAAG,EAAE,OAAO,CAAC,eAAe,GAAG,UAAU,CAAC,EAC1C,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,GACtD,OAAO,CAAC,MAAM,CAAC;IA+BlB;;;OAGG;IACH,cAAc,CAAC,GAAG,EAAE,eAAe;IAInC;;;OAGG;IACH,OAAO,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO;IAItC;;;OAGG;IACH,WAAW,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,GAAG,SAAS;IAIrD;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAKpC;AAED,OAAO,EAAE,aAAa,EAAE,CAAA"}
package/dist/index.cjs CHANGED
@@ -82,8 +82,8 @@ class EmailCoreVendor extends EventEmitter {
82
82
  };
83
83
  this.emit('host', host);
84
84
  this.emit('ready');
85
- // Start listening for new emails
86
- await this.startIdleListener();
85
+ // Start listening for new emails (non-blocking)
86
+ this.startIdleListener();
87
87
  }
88
88
  catch (error) {
89
89
  console.error('[EmailProvider] Failed to connect to IMAP:', error);
@@ -114,23 +114,29 @@ class EmailCoreVendor extends EventEmitter {
114
114
  }
115
115
  /**
116
116
  * Start IMAP IDLE listener for real-time email notifications
117
+ * This runs in the background and doesn't block the initialization
117
118
  */
118
- async startIdleListener() {
119
+ startIdleListener() {
119
120
  if (!this.imapClient || !this.isConnected)
120
121
  return;
121
122
  const mailbox = this.config.mailbox || 'INBOX';
123
+ // Listen for new messages using EXISTS event
124
+ this.imapClient.on('exists', async (data) => {
125
+ if (data.count > data.prevCount) {
126
+ console.log(`[EmailProvider] New email detected in ${data.path}`);
127
+ await this.fetchNewEmails(data.prevCount + 1, data.count);
128
+ }
129
+ });
130
+ // Start the IDLE loop in background
131
+ this.runIdleLoop(mailbox);
132
+ }
133
+ /**
134
+ * Run the IDLE loop in background without blocking
135
+ */
136
+ async runIdleLoop(mailbox) {
122
137
  try {
123
- // Select the mailbox
124
138
  const lock = await this.imapClient.getMailboxLock(mailbox);
125
139
  try {
126
- // Listen for new messages using EXISTS event
127
- this.imapClient.on('exists', async (data) => {
128
- if (data.count > data.prevCount) {
129
- console.log(`[EmailProvider] New email detected in ${data.path}`);
130
- await this.fetchNewEmails(data.prevCount + 1, data.count);
131
- }
132
- });
133
- // Start IDLE mode
134
140
  console.log(`[EmailProvider] Starting IDLE mode on ${mailbox}`);
135
141
  // Keep the connection alive with IDLE
136
142
  while (this.isConnected && this.imapClient) {
@@ -161,6 +167,7 @@ class EmailCoreVendor extends EventEmitter {
161
167
  if (!this.imapClient || !this.isConnected)
162
168
  return;
163
169
  const mailbox = this.config.mailbox || 'INBOX';
170
+ const processedEmails = [];
164
171
  try {
165
172
  const lock = await this.imapClient.getMailboxLock(mailbox);
166
173
  try {
@@ -172,21 +179,35 @@ class EmailCoreVendor extends EventEmitter {
172
179
  const parsed = await mailparser.simpleParser(message.source);
173
180
  const emailContext = this.parseEmailToContext(parsed, message.uid);
174
181
  if (emailContext) {
175
- // Mark as read if configured
176
- if (this.config.markAsRead !== false) {
177
- await this.imapClient.messageFlagsAdd({ uid: message.uid }, ['\\Seen']);
178
- }
179
- this.emit('message', emailContext);
182
+ processedEmails.push({ uid: message.uid, context: emailContext });
180
183
  }
181
184
  }
182
185
  catch (parseError) {
183
186
  console.error('[EmailProvider] Failed to parse email:', parseError);
184
187
  }
185
188
  }
189
+ // Mark emails as read after fetching (outside the fetch iterator)
190
+ if (this.config.markAsRead !== false && processedEmails.length > 0) {
191
+ const uids = processedEmails.map((e) => e.uid);
192
+ try {
193
+ await this.imapClient.messageFlagsAdd(uids, ['\\Seen']);
194
+ }
195
+ catch (flagError) {
196
+ console.error('[EmailProvider] Failed to mark emails as read:', flagError);
197
+ }
198
+ }
186
199
  }
187
200
  finally {
188
201
  lock.release();
189
202
  }
203
+ // Emit events after releasing the lock to avoid blocking
204
+ for (const { context } of processedEmails) {
205
+ console.log('[EmailProvider] About to emit message event');
206
+ console.log('[EmailProvider] Listener count for "message":', this.listenerCount('message'));
207
+ console.log('[EmailProvider] Listeners:', this.listeners('message').length);
208
+ this.emit('message', context);
209
+ console.log('[EmailProvider] Message event emitted');
210
+ }
190
211
  }
191
212
  catch (error) {
192
213
  console.error('[EmailProvider] Failed to fetch new emails:', error);
@@ -217,18 +238,49 @@ class EmailCoreVendor extends EventEmitter {
217
238
  ? parsed.references[0]
218
239
  : parsed.references
219
240
  : parsed.inReplyTo || parsed.messageId;
220
- // Build body - generate special events for attachments
221
- let body = parsed.text || '';
222
- if (attachments.length > 0 && !body.trim()) {
223
- // Email with only attachments
224
- const hasMedia = attachments.some((a) => a.contentType.startsWith('image/') || a.contentType.startsWith('video/'));
225
- const hasDocument = attachments.some((a) => a.contentType.startsWith('application/') || a.contentType.startsWith('text/'));
226
- if (hasMedia) {
227
- body = bot.utils.generateRefProvider('_event_media_');
228
- }
229
- else if (hasDocument) {
230
- body = bot.utils.generateRefProvider('_event_document_');
241
+ // Determine attachment types for event routing
242
+ const hasMedia = attachments.some((a) => a.contentType.startsWith('image/') || a.contentType.startsWith('video/'));
243
+ const hasAudio = attachments.some((a) => a.contentType.startsWith('audio/'));
244
+ const hasDocument = attachments.some((a) => {
245
+ // application/* are documents (pdf, msword, etc.)
246
+ if (a.contentType.startsWith('application/'))
247
+ return true;
248
+ // text/csv, text/calendar, etc. are documents, but NOT text/plain or text/html
249
+ if (a.contentType.startsWith('text/') &&
250
+ !a.contentType.includes('plain') &&
251
+ !a.contentType.includes('html')) {
252
+ return true;
231
253
  }
254
+ return false;
255
+ });
256
+ // Determine base body based on messageSource config
257
+ let body = '';
258
+ const messageSource = this.config.messageSource || 'body';
259
+ switch (messageSource) {
260
+ case 'subject':
261
+ body = parsed.subject || '';
262
+ break;
263
+ case 'both':
264
+ body = [parsed.subject, parsed.text].filter(Boolean).join('\n\n');
265
+ break;
266
+ case 'body':
267
+ default:
268
+ body = parsed.text || '';
269
+ break;
270
+ }
271
+ // Build body - generate special events for attachments
272
+ // Priority: MEDIA > VOICE_NOTE > DOCUMENT > text
273
+ if (hasMedia) {
274
+ // Media attachments always trigger MEDIA event
275
+ body = bot.utils.generateRefProvider('_event_media_');
276
+ }
277
+ else if (hasAudio) {
278
+ // Audio attachments trigger VOICE_NOTE event
279
+ body = bot.utils.generateRefProvider('_event_voice_note_');
280
+ }
281
+ else if (hasDocument && !body.trim()) {
282
+ // Documents only trigger event if no text body
283
+ body = bot.utils.generateRefProvider('_event_document_');
232
284
  }
233
285
  const context = {
234
286
  from: fromAddress.address,
@@ -424,6 +476,8 @@ class EmailCoreVendor extends EventEmitter {
424
476
  class EmailProvider extends bot.ProviderClass {
425
477
  constructor(args) {
426
478
  super();
479
+ // Map to store the last context of each conversation for thread replies
480
+ this.conversationContexts = new Map();
427
481
  /**
428
482
  * Index home endpoint
429
483
  */
@@ -442,34 +496,45 @@ class EmailProvider extends bot.ProviderClass {
442
496
  /**
443
497
  * Map vendor events to provider events
444
498
  */
445
- this.busEvents = () => [
446
- {
447
- event: 'auth_failure',
448
- func: (payload) => this.emit('auth_failure', payload),
449
- },
450
- {
451
- event: 'ready',
452
- func: () => this.emit('ready', true),
453
- },
454
- {
455
- event: 'message',
456
- func: (payload) => {
457
- this.emit('message', payload);
499
+ this.busEvents = () => {
500
+ console.log('[EmailProvider] busEvents() called - registering listeners');
501
+ return [
502
+ {
503
+ event: 'auth_failure',
504
+ func: (payload) => this.emit('auth_failure', payload),
458
505
  },
459
- },
460
- {
461
- event: 'host',
462
- func: (payload) => {
463
- this.emit('host', payload);
506
+ {
507
+ event: 'ready',
508
+ func: () => {
509
+ console.log('[EmailProvider] busEvents ready handler called');
510
+ this.emit('ready', true);
511
+ },
464
512
  },
465
- },
466
- {
467
- event: 'error',
468
- func: (payload) => {
469
- console.error('[EmailProvider] Error:', payload);
513
+ {
514
+ event: 'message',
515
+ func: (payload) => {
516
+ console.log('[EmailProvider] busEvents message handler called!');
517
+ console.log('[EmailProvider] Payload from:', payload.from, 'body:', payload.body?.substring(0, 50));
518
+ // Store context to enable thread replies
519
+ this.conversationContexts.set(payload.from, payload);
520
+ this.emit('message', payload);
521
+ console.log('[EmailProvider] Provider emitted message to bot');
522
+ },
470
523
  },
471
- },
472
- ];
524
+ {
525
+ event: 'host',
526
+ func: (payload) => {
527
+ this.emit('host', payload);
528
+ },
529
+ },
530
+ {
531
+ event: 'error',
532
+ func: (payload) => {
533
+ console.error('[EmailProvider] Error:', payload);
534
+ },
535
+ },
536
+ ];
537
+ };
473
538
  // Validate required configuration
474
539
  if (!args.imap) {
475
540
  throw new Error('IMAP configuration is required');
@@ -489,6 +554,7 @@ class EmailProvider extends bot.ProviderClass {
489
554
  writeMyself: 'none',
490
555
  mailbox: 'INBOX',
491
556
  markAsRead: true,
557
+ messageSource: 'body',
492
558
  ...args,
493
559
  };
494
560
  }
@@ -496,10 +562,12 @@ class EmailProvider extends bot.ProviderClass {
496
562
  * Initialize the email vendor (IMAP/SMTP connections)
497
563
  */
498
564
  async initVendor() {
565
+ console.log('[EmailProvider] initVendor() called');
499
566
  const vendor = new EmailCoreVendor(this.globalVendorArgs);
500
567
  this.vendor = vendor;
501
568
  // Connect to IMAP server
502
569
  await vendor.connect();
570
+ console.log('[EmailProvider] initVendor() returning vendor');
503
571
  return vendor;
504
572
  }
505
573
  /**
@@ -525,13 +593,20 @@ class EmailProvider extends bot.ProviderClass {
525
593
  * @param options - Send options (subject, attachments, etc.)
526
594
  */
527
595
  async sendMessage(to, message, options) {
528
- const emailOptions = options;
529
- // Default subject if not provided
530
- const subject = emailOptions?.subject || 'Message from Bot';
531
- // Check if we're replying to an existing thread
532
- if (emailOptions?.inReplyTo) {
533
- return this.vendor.sendEmail(to, subject, message, emailOptions);
534
- }
596
+ // Look up existing conversation context for thread replies
597
+ const conversationCtx = this.conversationContexts.get(to);
598
+ // Build email options with thread context if available
599
+ const baseSubject = options?.subject || (conversationCtx?.subject ? conversationCtx.subject : 'Message from Bot');
600
+ const subject = conversationCtx && !baseSubject.toLowerCase().startsWith('re:') ? `Re: ${baseSubject}` : baseSubject;
601
+ const emailOptions = {
602
+ ...options,
603
+ subject,
604
+ inReplyTo: options?.inReplyTo || conversationCtx?.messageId,
605
+ references: options?.references ||
606
+ (conversationCtx
607
+ ? [conversationCtx.threadId || conversationCtx.messageId].filter(Boolean)
608
+ : undefined),
609
+ };
535
610
  // Check for media/attachments
536
611
  if (options?.media) {
537
612
  return this.sendMedia(to, message, options.media, emailOptions);
package/dist/types.d.ts CHANGED
@@ -15,6 +15,13 @@ export interface ImapConfig {
15
15
  pass: string;
16
16
  };
17
17
  }
18
+ /**
19
+ * Source for the message body
20
+ * - 'body': Use email body only (default)
21
+ * - 'subject': Use email subject only
22
+ * - 'both': Use both subject and body (format: "subject\n\nbody")
23
+ */
24
+ export type MessageSource = 'body' | 'subject' | 'both';
18
25
  /**
19
26
  * SMTP server configuration
20
27
  */
@@ -47,6 +54,8 @@ export interface IEmailProviderArgs extends GlobalVendorArgs {
47
54
  fromEmail?: string;
48
55
  /** From name for outgoing emails */
49
56
  fromName?: string;
57
+ /** Source for message body: 'body', 'subject', or 'both' (default: 'body') */
58
+ messageSource?: MessageSource;
50
59
  }
51
60
  /**
52
61
  * Email attachment information
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@builderbot/provider-email",
3
- "version": "1.3.15-alpha.8",
3
+ "version": "1.4.1",
4
4
  "description": "Email provider for BuilderBot using IMAP/SMTP",
5
5
  "author": "Leifer Mendez <leifer33@gmail.com>",
6
6
  "homepage": "https://github.com/codigoencasa/bot-whatsapp#readme",
@@ -29,7 +29,7 @@
29
29
  "url": "https://github.com/codigoencasa/bot-whatsapp/issues"
30
30
  },
31
31
  "devDependencies": {
32
- "@builderbot/bot": "^1.3.15-alpha.8",
32
+ "@builderbot/bot": "^1.4.1",
33
33
  "@jest/globals": "^30.2.0",
34
34
  "@rollup/plugin-commonjs": "^29.0.0",
35
35
  "@rollup/plugin-json": "^6.1.0",
@@ -47,5 +47,6 @@
47
47
  "mailparser": "^3.7.2",
48
48
  "nodemailer": "^6.10.1",
49
49
  "polka": "^0.5.2"
50
- }
50
+ },
51
+ "gitHead": "f0a2e91d3f47339090483865d6c23a5875284b96"
51
52
  }