strapi-plugin-magic-mail 2.2.5 → 2.3.0

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.
@@ -4,6 +4,8 @@ import require$$1$1 from "os";
4
4
  import require$$0$3 from "mustache";
5
5
  import require$$1$2 from "html-to-text";
6
6
  import require$$2$2 from "decode-html";
7
+ import require$$0$4 from "path";
8
+ import require$$1$3 from "fs";
7
9
  var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
8
10
  function getDefaultExportFromCjs(x2) {
9
11
  return x2 && x2.__esModule && Object.prototype.hasOwnProperty.call(x2, "default") ? x2["default"] : x2;
@@ -257,7 +259,7 @@ const collectionName$5 = "magic_mail_routing_rules";
257
259
  const info$5 = { "singularName": "routing-rule", "pluralName": "routing-rules", "displayName": "Email Routing Rule", "description": "Rules for routing emails to specific accounts" };
258
260
  const options$5 = { "draftAndPublish": false };
259
261
  const pluginOptions$5 = { "content-manager": { "visible": false }, "content-type-builder": { "visible": false } };
260
- const attributes$5 = { "name": { "type": "string", "required": true, "unique": true }, "description": { "type": "text" }, "isActive": { "type": "boolean", "default": true, "required": true }, "priority": { "type": "integer", "default": 1, "min": 1 }, "matchType": { "type": "enumeration", "enum": ["emailType", "subject", "recipient", "template", "custom"], "required": true, "default": "emailType" }, "matchValue": { "type": "text", "required": true }, "accountName": { "type": "string", "required": true }, "fallbackAccountName": { "type": "string" } };
262
+ const attributes$5 = { "name": { "type": "string", "required": true, "unique": true }, "description": { "type": "text" }, "isActive": { "type": "boolean", "default": true, "required": true }, "priority": { "type": "integer", "default": 1, "min": 1 }, "matchType": { "type": "enumeration", "enum": ["emailType", "subject", "recipient", "template", "custom"], "required": true, "default": "emailType" }, "matchValue": { "type": "text", "required": true }, "accountName": { "type": "string", "required": true }, "fallbackAccountName": { "type": "string" }, "whatsappFallback": { "type": "boolean", "default": false }, "whatsappPhoneField": { "type": "string" } };
261
263
  const require$$1 = {
262
264
  kind: kind$5,
263
265
  collectionName: collectionName$5,
@@ -394,6 +396,88 @@ function requireController() {
394
396
  strapi.log.error("[magic-mail] Error sending email:", err);
395
397
  ctx.throw(500, err.message || "Failed to send email");
396
398
  }
399
+ },
400
+ /**
401
+ * Send message via Email or WhatsApp (unified API)
402
+ * POST /api/magic-mail/send-message
403
+ * Body: { channel: 'email' | 'whatsapp' | 'auto', to, phoneNumber, subject, message, ... }
404
+ */
405
+ async sendMessage(ctx) {
406
+ try {
407
+ const emailRouter2 = strapi.plugin("magic-mail").service("email-router");
408
+ const result = await emailRouter2.sendMessage(ctx.request.body);
409
+ ctx.body = {
410
+ success: true,
411
+ ...result
412
+ };
413
+ } catch (err) {
414
+ strapi.log.error("[magic-mail] Error sending message:", err);
415
+ ctx.throw(500, err.message || "Failed to send message");
416
+ }
417
+ },
418
+ /**
419
+ * Send WhatsApp message
420
+ * POST /api/magic-mail/send-whatsapp
421
+ * Body: { phoneNumber, message, templateId?, templateData? }
422
+ */
423
+ async sendWhatsApp(ctx) {
424
+ try {
425
+ const emailRouter2 = strapi.plugin("magic-mail").service("email-router");
426
+ const result = await emailRouter2.sendWhatsApp(ctx.request.body);
427
+ ctx.body = {
428
+ success: true,
429
+ ...result
430
+ };
431
+ } catch (err) {
432
+ strapi.log.error("[magic-mail] Error sending WhatsApp:", err);
433
+ ctx.throw(500, err.message || "Failed to send WhatsApp message");
434
+ }
435
+ },
436
+ /**
437
+ * Get WhatsApp connection status
438
+ * GET /api/magic-mail/whatsapp/status
439
+ */
440
+ async getWhatsAppStatus(ctx) {
441
+ try {
442
+ const emailRouter2 = strapi.plugin("magic-mail").service("email-router");
443
+ const status = emailRouter2.getWhatsAppStatus();
444
+ ctx.body = {
445
+ success: true,
446
+ data: status
447
+ };
448
+ } catch (err) {
449
+ strapi.log.error("[magic-mail] Error getting WhatsApp status:", err);
450
+ ctx.body = {
451
+ success: false,
452
+ data: {
453
+ isConnected: false,
454
+ status: "error",
455
+ error: err.message
456
+ }
457
+ };
458
+ }
459
+ },
460
+ /**
461
+ * Check if phone number is on WhatsApp
462
+ * GET /api/magic-mail/whatsapp/check/:phoneNumber
463
+ */
464
+ async checkWhatsAppNumber(ctx) {
465
+ try {
466
+ const { phoneNumber } = ctx.params;
467
+ if (!phoneNumber) {
468
+ ctx.throw(400, "Phone number is required");
469
+ return;
470
+ }
471
+ const emailRouter2 = strapi.plugin("magic-mail").service("email-router");
472
+ const result = await emailRouter2.checkWhatsAppNumber(phoneNumber);
473
+ ctx.body = {
474
+ success: true,
475
+ data: result
476
+ };
477
+ } catch (err) {
478
+ strapi.log.error("[magic-mail] Error checking WhatsApp number:", err);
479
+ ctx.throw(500, err.message || "Failed to check phone number");
480
+ }
397
481
  }
398
482
  };
399
483
  return controller;
@@ -2444,6 +2528,219 @@ function requireTest() {
2444
2528
  };
2445
2529
  return test;
2446
2530
  }
2531
+ var whatsapp$1;
2532
+ var hasRequiredWhatsapp$1;
2533
+ function requireWhatsapp$1() {
2534
+ if (hasRequiredWhatsapp$1) return whatsapp$1;
2535
+ hasRequiredWhatsapp$1 = 1;
2536
+ whatsapp$1 = {
2537
+ /**
2538
+ * Check if WhatsApp/Baileys is available
2539
+ * GET /magic-mail/whatsapp/available
2540
+ */
2541
+ async checkAvailable(ctx) {
2542
+ try {
2543
+ const whatsappService = strapi.plugin("magic-mail").service("whatsapp");
2544
+ const available = await whatsappService.isAvailable();
2545
+ ctx.body = {
2546
+ success: true,
2547
+ data: {
2548
+ available,
2549
+ message: available ? "WhatsApp integration is available" : "Baileys not installed. Run: npm install @whiskeysockets/baileys pino qrcode"
2550
+ }
2551
+ };
2552
+ } catch (error) {
2553
+ ctx.throw(500, error.message);
2554
+ }
2555
+ },
2556
+ /**
2557
+ * Get WhatsApp connection status
2558
+ * GET /magic-mail/whatsapp/status
2559
+ */
2560
+ async getStatus(ctx) {
2561
+ try {
2562
+ const whatsappService = strapi.plugin("magic-mail").service("whatsapp");
2563
+ const status = whatsappService.getStatus();
2564
+ const sessionInfo = await whatsappService.getSessionInfo();
2565
+ ctx.body = {
2566
+ success: true,
2567
+ data: {
2568
+ ...status,
2569
+ session: sessionInfo
2570
+ }
2571
+ };
2572
+ } catch (error) {
2573
+ ctx.throw(500, error.message);
2574
+ }
2575
+ },
2576
+ /**
2577
+ * Connect to WhatsApp (generates QR code if needed)
2578
+ * POST /magic-mail/whatsapp/connect
2579
+ */
2580
+ async connect(ctx) {
2581
+ try {
2582
+ const whatsappService = strapi.plugin("magic-mail").service("whatsapp");
2583
+ const result = await whatsappService.connect();
2584
+ ctx.body = {
2585
+ success: result.success,
2586
+ data: result
2587
+ };
2588
+ } catch (error) {
2589
+ ctx.throw(500, error.message);
2590
+ }
2591
+ },
2592
+ /**
2593
+ * Disconnect from WhatsApp
2594
+ * POST /magic-mail/whatsapp/disconnect
2595
+ */
2596
+ async disconnect(ctx) {
2597
+ try {
2598
+ const whatsappService = strapi.plugin("magic-mail").service("whatsapp");
2599
+ const result = await whatsappService.disconnect();
2600
+ ctx.body = {
2601
+ success: result.success,
2602
+ data: result
2603
+ };
2604
+ } catch (error) {
2605
+ ctx.throw(500, error.message);
2606
+ }
2607
+ },
2608
+ /**
2609
+ * Send a test message
2610
+ * POST /magic-mail/whatsapp/send-test
2611
+ */
2612
+ async sendTest(ctx) {
2613
+ try {
2614
+ const { phoneNumber, message } = ctx.request.body;
2615
+ if (!phoneNumber) {
2616
+ return ctx.badRequest("Phone number is required");
2617
+ }
2618
+ const whatsappService = strapi.plugin("magic-mail").service("whatsapp");
2619
+ const testMessage = message || `[MagicMail Test] This is a test message sent at ${(/* @__PURE__ */ new Date()).toLocaleString()}`;
2620
+ const result = await whatsappService.sendMessage(phoneNumber, testMessage);
2621
+ ctx.body = {
2622
+ success: result.success,
2623
+ data: result
2624
+ };
2625
+ } catch (error) {
2626
+ ctx.throw(500, error.message);
2627
+ }
2628
+ },
2629
+ /**
2630
+ * Send a message using a template
2631
+ * POST /magic-mail/whatsapp/send-template
2632
+ */
2633
+ async sendTemplateMessage(ctx) {
2634
+ try {
2635
+ const { phoneNumber, templateName, variables } = ctx.request.body;
2636
+ if (!phoneNumber || !templateName) {
2637
+ return ctx.badRequest("Phone number and template name are required");
2638
+ }
2639
+ const whatsappService = strapi.plugin("magic-mail").service("whatsapp");
2640
+ const result = await whatsappService.sendTemplateMessage(phoneNumber, templateName, variables || {});
2641
+ ctx.body = {
2642
+ success: result.success,
2643
+ data: result
2644
+ };
2645
+ } catch (error) {
2646
+ ctx.throw(500, error.message);
2647
+ }
2648
+ },
2649
+ /**
2650
+ * Check if a phone number is on WhatsApp
2651
+ * POST /magic-mail/whatsapp/check-number
2652
+ */
2653
+ async checkNumber(ctx) {
2654
+ try {
2655
+ const { phoneNumber } = ctx.request.body;
2656
+ if (!phoneNumber) {
2657
+ return ctx.badRequest("Phone number is required");
2658
+ }
2659
+ const whatsappService = strapi.plugin("magic-mail").service("whatsapp");
2660
+ const result = await whatsappService.checkNumber(phoneNumber);
2661
+ ctx.body = {
2662
+ success: result.success,
2663
+ data: result
2664
+ };
2665
+ } catch (error) {
2666
+ ctx.throw(500, error.message);
2667
+ }
2668
+ },
2669
+ /**
2670
+ * Get all WhatsApp templates
2671
+ * GET /magic-mail/whatsapp/templates
2672
+ */
2673
+ async getTemplates(ctx) {
2674
+ try {
2675
+ const whatsappService = strapi.plugin("magic-mail").service("whatsapp");
2676
+ const templates = await whatsappService.getTemplates();
2677
+ ctx.body = {
2678
+ success: true,
2679
+ data: templates
2680
+ };
2681
+ } catch (error) {
2682
+ ctx.throw(500, error.message);
2683
+ }
2684
+ },
2685
+ /**
2686
+ * Save a WhatsApp template
2687
+ * POST /magic-mail/whatsapp/templates
2688
+ */
2689
+ async saveTemplate(ctx) {
2690
+ try {
2691
+ const { templateName, templateContent } = ctx.request.body;
2692
+ if (!templateName || !templateContent) {
2693
+ return ctx.badRequest("Template name and content are required");
2694
+ }
2695
+ const whatsappService = strapi.plugin("magic-mail").service("whatsapp");
2696
+ const result = await whatsappService.saveTemplate(templateName, templateContent);
2697
+ ctx.body = {
2698
+ success: result.success,
2699
+ data: result
2700
+ };
2701
+ } catch (error) {
2702
+ ctx.throw(500, error.message);
2703
+ }
2704
+ },
2705
+ /**
2706
+ * Delete a WhatsApp template
2707
+ * DELETE /magic-mail/whatsapp/templates/:templateName
2708
+ */
2709
+ async deleteTemplate(ctx) {
2710
+ try {
2711
+ const { templateName } = ctx.params;
2712
+ if (!templateName) {
2713
+ return ctx.badRequest("Template name is required");
2714
+ }
2715
+ const whatsappService = strapi.plugin("magic-mail").service("whatsapp");
2716
+ const result = await whatsappService.deleteTemplate(templateName);
2717
+ ctx.body = {
2718
+ success: result.success,
2719
+ data: result
2720
+ };
2721
+ } catch (error) {
2722
+ ctx.throw(500, error.message);
2723
+ }
2724
+ },
2725
+ /**
2726
+ * Get session info
2727
+ * GET /magic-mail/whatsapp/session
2728
+ */
2729
+ async getSession(ctx) {
2730
+ try {
2731
+ const whatsappService = strapi.plugin("magic-mail").service("whatsapp");
2732
+ const sessionInfo = await whatsappService.getSessionInfo();
2733
+ ctx.body = {
2734
+ success: true,
2735
+ data: sessionInfo
2736
+ };
2737
+ } catch (error) {
2738
+ ctx.throw(500, error.message);
2739
+ }
2740
+ }
2741
+ };
2742
+ return whatsapp$1;
2743
+ }
2447
2744
  var controllers;
2448
2745
  var hasRequiredControllers;
2449
2746
  function requireControllers() {
@@ -2457,6 +2754,7 @@ function requireControllers() {
2457
2754
  const emailDesigner2 = requireEmailDesigner$1();
2458
2755
  const analytics2 = requireAnalytics$1();
2459
2756
  const test2 = requireTest();
2757
+ const whatsapp2 = requireWhatsapp$1();
2460
2758
  controllers = {
2461
2759
  controller: controller2,
2462
2760
  accounts: accounts2,
@@ -2465,7 +2763,8 @@ function requireControllers() {
2465
2763
  license: license2,
2466
2764
  emailDesigner: emailDesigner2,
2467
2765
  analytics: analytics2,
2468
- test: test2
2766
+ test: test2,
2767
+ whatsapp: whatsapp2
2469
2768
  };
2470
2769
  return controllers;
2471
2770
  }
@@ -2940,6 +3239,106 @@ function requireAdmin() {
2940
3239
  policies: ["admin::isAuthenticatedAdmin"],
2941
3240
  description: "Test template-version relations"
2942
3241
  }
3242
+ },
3243
+ // WhatsApp Routes
3244
+ {
3245
+ method: "GET",
3246
+ path: "/whatsapp/available",
3247
+ handler: "whatsapp.checkAvailable",
3248
+ config: {
3249
+ policies: ["admin::isAuthenticatedAdmin"],
3250
+ description: "Check if WhatsApp/Baileys is available"
3251
+ }
3252
+ },
3253
+ {
3254
+ method: "GET",
3255
+ path: "/whatsapp/status",
3256
+ handler: "whatsapp.getStatus",
3257
+ config: {
3258
+ policies: ["admin::isAuthenticatedAdmin"],
3259
+ description: "Get WhatsApp connection status"
3260
+ }
3261
+ },
3262
+ {
3263
+ method: "POST",
3264
+ path: "/whatsapp/connect",
3265
+ handler: "whatsapp.connect",
3266
+ config: {
3267
+ policies: ["admin::isAuthenticatedAdmin"],
3268
+ description: "Connect to WhatsApp (generates QR if needed)"
3269
+ }
3270
+ },
3271
+ {
3272
+ method: "POST",
3273
+ path: "/whatsapp/disconnect",
3274
+ handler: "whatsapp.disconnect",
3275
+ config: {
3276
+ policies: ["admin::isAuthenticatedAdmin"],
3277
+ description: "Disconnect from WhatsApp"
3278
+ }
3279
+ },
3280
+ {
3281
+ method: "POST",
3282
+ path: "/whatsapp/send-test",
3283
+ handler: "whatsapp.sendTest",
3284
+ config: {
3285
+ policies: ["admin::isAuthenticatedAdmin"],
3286
+ description: "Send a test WhatsApp message"
3287
+ }
3288
+ },
3289
+ {
3290
+ method: "POST",
3291
+ path: "/whatsapp/send-template",
3292
+ handler: "whatsapp.sendTemplateMessage",
3293
+ config: {
3294
+ policies: ["admin::isAuthenticatedAdmin"],
3295
+ description: "Send WhatsApp message using template"
3296
+ }
3297
+ },
3298
+ {
3299
+ method: "POST",
3300
+ path: "/whatsapp/check-number",
3301
+ handler: "whatsapp.checkNumber",
3302
+ config: {
3303
+ policies: ["admin::isAuthenticatedAdmin"],
3304
+ description: "Check if phone number is on WhatsApp"
3305
+ }
3306
+ },
3307
+ {
3308
+ method: "GET",
3309
+ path: "/whatsapp/templates",
3310
+ handler: "whatsapp.getTemplates",
3311
+ config: {
3312
+ policies: ["admin::isAuthenticatedAdmin"],
3313
+ description: "Get all WhatsApp message templates"
3314
+ }
3315
+ },
3316
+ {
3317
+ method: "POST",
3318
+ path: "/whatsapp/templates",
3319
+ handler: "whatsapp.saveTemplate",
3320
+ config: {
3321
+ policies: ["admin::isAuthenticatedAdmin"],
3322
+ description: "Save a WhatsApp message template"
3323
+ }
3324
+ },
3325
+ {
3326
+ method: "DELETE",
3327
+ path: "/whatsapp/templates/:templateName",
3328
+ handler: "whatsapp.deleteTemplate",
3329
+ config: {
3330
+ policies: ["admin::isAuthenticatedAdmin"],
3331
+ description: "Delete a WhatsApp message template"
3332
+ }
3333
+ },
3334
+ {
3335
+ method: "GET",
3336
+ path: "/whatsapp/session",
3337
+ handler: "whatsapp.getSession",
3338
+ config: {
3339
+ policies: ["admin::isAuthenticatedAdmin"],
3340
+ description: "Get WhatsApp session info"
3341
+ }
2943
3342
  }
2944
3343
  ]
2945
3344
  };
@@ -2953,6 +3352,7 @@ function requireContentApi() {
2953
3352
  contentApi = {
2954
3353
  type: "content-api",
2955
3354
  routes: [
3355
+ // ============= EMAIL ROUTES =============
2956
3356
  {
2957
3357
  method: "POST",
2958
3358
  path: "/send",
@@ -2963,7 +3363,45 @@ function requireContentApi() {
2963
3363
  description: "Send email via MagicMail router"
2964
3364
  }
2965
3365
  },
2966
- // Public tracking endpoints (no auth required!)
3366
+ // ============= UNIFIED MESSAGE ROUTE =============
3367
+ {
3368
+ method: "POST",
3369
+ path: "/send-message",
3370
+ handler: "controller.sendMessage",
3371
+ config: {
3372
+ auth: false,
3373
+ description: "Send message via Email or WhatsApp (unified API)"
3374
+ }
3375
+ },
3376
+ // ============= WHATSAPP ROUTES =============
3377
+ {
3378
+ method: "POST",
3379
+ path: "/send-whatsapp",
3380
+ handler: "controller.sendWhatsApp",
3381
+ config: {
3382
+ auth: false,
3383
+ description: "Send WhatsApp message"
3384
+ }
3385
+ },
3386
+ {
3387
+ method: "GET",
3388
+ path: "/whatsapp/status",
3389
+ handler: "controller.getWhatsAppStatus",
3390
+ config: {
3391
+ auth: false,
3392
+ description: "Get WhatsApp connection status"
3393
+ }
3394
+ },
3395
+ {
3396
+ method: "GET",
3397
+ path: "/whatsapp/check/:phoneNumber",
3398
+ handler: "controller.checkWhatsAppNumber",
3399
+ config: {
3400
+ auth: false,
3401
+ description: "Check if phone number is on WhatsApp"
3402
+ }
3403
+ },
3404
+ // ============= TRACKING ROUTES =============
2967
3405
  {
2968
3406
  method: "GET",
2969
3407
  path: "/track/open/:emailId/:recipientHash",
@@ -3208,6 +3646,39 @@ function requireEmailRouter() {
3208
3646
  emailData.html = html;
3209
3647
  emailData.text = text;
3210
3648
  emailData.subject = subject;
3649
+ let matchedRule = null;
3650
+ try {
3651
+ const allRules = await strapi2.documents("plugin::magic-mail.routing-rule").findMany({
3652
+ filters: { isActive: true },
3653
+ sort: [{ priority: "desc" }]
3654
+ });
3655
+ for (const rule of allRules) {
3656
+ let matches = false;
3657
+ switch (rule.matchType) {
3658
+ case "emailType":
3659
+ matches = rule.matchValue === type;
3660
+ break;
3661
+ case "recipient":
3662
+ matches = to && to.toLowerCase().includes(rule.matchValue.toLowerCase());
3663
+ break;
3664
+ case "subject":
3665
+ matches = subject && subject.toLowerCase().includes(rule.matchValue.toLowerCase());
3666
+ break;
3667
+ case "template":
3668
+ matches = emailData.template && emailData.template === rule.matchValue;
3669
+ break;
3670
+ case "custom":
3671
+ matches = emailData.customField && emailData.customField === rule.matchValue;
3672
+ break;
3673
+ }
3674
+ if (matches) {
3675
+ matchedRule = rule;
3676
+ break;
3677
+ }
3678
+ }
3679
+ } catch (ruleError) {
3680
+ strapi2.log.warn("[magic-mail] [WARNING] Failed to check routing rules for WhatsApp fallback:", ruleError.message);
3681
+ }
3211
3682
  try {
3212
3683
  const licenseGuard2 = strapi2.plugin("magic-mail").service("license-guard");
3213
3684
  if (priority === "high") {
@@ -3258,6 +3729,38 @@ function requireEmailRouter() {
3258
3729
  };
3259
3730
  } catch (error) {
3260
3731
  strapi2.log.error("[magic-mail] [ERROR] Email send failed:", error);
3732
+ if (matchedRule?.whatsappFallback) {
3733
+ strapi2.log.info("[magic-mail] [FALLBACK] Email failed, attempting WhatsApp fallback...");
3734
+ try {
3735
+ const whatsapp2 = strapi2.plugin("magic-mail").service("whatsapp");
3736
+ const whatsappStatus = whatsapp2.getStatus();
3737
+ if (whatsappStatus.isConnected) {
3738
+ const phoneNumber = emailData.phoneNumber || emailData.whatsappPhone;
3739
+ if (phoneNumber) {
3740
+ const whatsappMessage = `*${subject}*
3741
+
3742
+ ${text || "Email delivery failed. Please check your email settings."}`;
3743
+ const waResult = await whatsapp2.sendMessage(phoneNumber, whatsappMessage);
3744
+ if (waResult.success) {
3745
+ strapi2.log.info(`[magic-mail] [SUCCESS] WhatsApp fallback sent to ${phoneNumber}`);
3746
+ return {
3747
+ success: true,
3748
+ fallbackUsed: "whatsapp",
3749
+ phoneNumber
3750
+ };
3751
+ } else {
3752
+ strapi2.log.warn("[magic-mail] [WARNING] WhatsApp fallback failed:", waResult.error);
3753
+ }
3754
+ } else {
3755
+ strapi2.log.warn("[magic-mail] [WARNING] WhatsApp fallback enabled but no phone number provided");
3756
+ }
3757
+ } else {
3758
+ strapi2.log.warn("[magic-mail] [WARNING] WhatsApp fallback enabled but WhatsApp not connected");
3759
+ }
3760
+ } catch (waError) {
3761
+ strapi2.log.error("[magic-mail] [ERROR] WhatsApp fallback error:", waError.message);
3762
+ }
3763
+ }
3261
3764
  throw error;
3262
3765
  }
3263
3766
  },
@@ -4166,6 +4669,168 @@ function requireEmailRouter() {
4166
4669
  ...headers
4167
4670
  }
4168
4671
  };
4672
+ },
4673
+ // ============================================================================
4674
+ // UNIFIED MESSAGE API - Send via Email OR WhatsApp
4675
+ // ============================================================================
4676
+ /**
4677
+ * Send a message via WhatsApp
4678
+ * Same pattern as send() but for WhatsApp
4679
+ * @param {Object} messageData - { phoneNumber, message, templateId, templateData }
4680
+ * @returns {Promise<Object>} Send result
4681
+ */
4682
+ async sendWhatsApp(messageData) {
4683
+ const {
4684
+ phoneNumber,
4685
+ message,
4686
+ templateId = null,
4687
+ templateData = {}
4688
+ } = messageData;
4689
+ if (!phoneNumber) {
4690
+ throw new Error("Phone number is required for WhatsApp messages");
4691
+ }
4692
+ const cleanPhone = phoneNumber.replace(/[^\d]/g, "");
4693
+ if (cleanPhone.length < 10) {
4694
+ throw new Error("Invalid phone number format. Use format: 491234567890 (country code + number)");
4695
+ }
4696
+ const whatsapp2 = strapi2.plugin("magic-mail").service("whatsapp");
4697
+ const status = whatsapp2.getStatus();
4698
+ if (!status.isConnected) {
4699
+ throw new Error("WhatsApp is not connected. Please connect WhatsApp first in the admin panel.");
4700
+ }
4701
+ let finalMessage = message;
4702
+ if (templateId) {
4703
+ try {
4704
+ const template = await whatsapp2.getTemplate(templateId);
4705
+ if (template) {
4706
+ finalMessage = template.content;
4707
+ Object.keys(templateData).forEach((key) => {
4708
+ finalMessage = finalMessage.replace(new RegExp(`{{${key}}}`, "g"), templateData[key]);
4709
+ });
4710
+ }
4711
+ } catch (error) {
4712
+ strapi2.log.warn(`[magic-mail] WhatsApp template ${templateId} not found, using plain message`);
4713
+ }
4714
+ }
4715
+ if (!finalMessage) {
4716
+ throw new Error("Message content is required");
4717
+ }
4718
+ strapi2.log.info(`[magic-mail] [WHATSAPP] Sending message to ${cleanPhone}`);
4719
+ const result = await whatsapp2.sendMessage(cleanPhone, finalMessage);
4720
+ if (result.success) {
4721
+ strapi2.log.info(`[magic-mail] [SUCCESS] WhatsApp message sent to ${cleanPhone}`);
4722
+ return {
4723
+ success: true,
4724
+ channel: "whatsapp",
4725
+ phoneNumber: cleanPhone,
4726
+ jid: result.jid
4727
+ };
4728
+ } else {
4729
+ strapi2.log.error(`[magic-mail] [ERROR] WhatsApp send failed: ${result.error}`);
4730
+ throw new Error(result.error || "Failed to send WhatsApp message");
4731
+ }
4732
+ },
4733
+ /**
4734
+ * Unified send method - automatically chooses Email or WhatsApp
4735
+ * @param {Object} messageData - Combined email and WhatsApp data
4736
+ * @param {string} messageData.channel - 'email' | 'whatsapp' | 'auto' (default: 'auto')
4737
+ * @param {string} messageData.to - Email address (for email channel)
4738
+ * @param {string} messageData.phoneNumber - Phone number (for whatsapp channel)
4739
+ * @param {string} messageData.subject - Email subject
4740
+ * @param {string} messageData.message - Plain text message (used for WhatsApp, or as email text)
4741
+ * @param {string} messageData.html - HTML content (email only)
4742
+ * @param {string} messageData.templateId - Template ID (works for both channels)
4743
+ * @param {Object} messageData.templateData - Template variables
4744
+ * @returns {Promise<Object>} Send result with channel info
4745
+ */
4746
+ async sendMessage(messageData) {
4747
+ const {
4748
+ channel = "auto",
4749
+ to,
4750
+ phoneNumber,
4751
+ subject,
4752
+ message,
4753
+ text,
4754
+ html,
4755
+ templateId,
4756
+ templateData,
4757
+ ...rest
4758
+ } = messageData;
4759
+ let useChannel = channel;
4760
+ if (channel === "auto") {
4761
+ if (to && to.includes("@")) {
4762
+ useChannel = "email";
4763
+ } else if (phoneNumber) {
4764
+ useChannel = "whatsapp";
4765
+ } else {
4766
+ throw new Error("Either email (to) or phoneNumber is required");
4767
+ }
4768
+ }
4769
+ strapi2.log.info(`[magic-mail] [SEND] Channel: ${useChannel}, to: ${to || phoneNumber}`);
4770
+ if (useChannel === "whatsapp") {
4771
+ if (!phoneNumber) {
4772
+ throw new Error("Phone number is required for WhatsApp channel");
4773
+ }
4774
+ return await this.sendWhatsApp({
4775
+ phoneNumber,
4776
+ message: message || text || subject,
4777
+ // Use message, fallback to text or subject
4778
+ templateId,
4779
+ templateData
4780
+ });
4781
+ } else {
4782
+ if (!to) {
4783
+ throw new Error("Email address (to) is required for email channel");
4784
+ }
4785
+ const result = await this.send({
4786
+ to,
4787
+ subject,
4788
+ text: text || message,
4789
+ html,
4790
+ templateId,
4791
+ templateData,
4792
+ phoneNumber,
4793
+ // Pass for WhatsApp fallback
4794
+ ...rest
4795
+ });
4796
+ return {
4797
+ ...result,
4798
+ channel: "email"
4799
+ };
4800
+ }
4801
+ },
4802
+ /**
4803
+ * Check WhatsApp connection status
4804
+ * @returns {Object} Connection status
4805
+ */
4806
+ getWhatsAppStatus() {
4807
+ try {
4808
+ const whatsapp2 = strapi2.plugin("magic-mail").service("whatsapp");
4809
+ return whatsapp2.getStatus();
4810
+ } catch (error) {
4811
+ return {
4812
+ isConnected: false,
4813
+ status: "unavailable",
4814
+ error: error.message
4815
+ };
4816
+ }
4817
+ },
4818
+ /**
4819
+ * Check if a phone number is registered on WhatsApp
4820
+ * @param {string} phoneNumber - Phone number to check
4821
+ * @returns {Promise<Object>} Check result
4822
+ */
4823
+ async checkWhatsAppNumber(phoneNumber) {
4824
+ try {
4825
+ const whatsapp2 = strapi2.plugin("magic-mail").service("whatsapp");
4826
+ return await whatsapp2.checkNumber(phoneNumber);
4827
+ } catch (error) {
4828
+ return {
4829
+ success: false,
4830
+ exists: false,
4831
+ error: error.message
4832
+ };
4833
+ }
4169
4834
  }
4170
4835
  });
4171
4836
  return emailRouter;
@@ -4862,7 +5527,7 @@ function requireOauth() {
4862
5527
  });
4863
5528
  return oauth;
4864
5529
  }
4865
- const version = "2.2.4";
5530
+ const version = "2.4.0";
4866
5531
  const require$$2 = {
4867
5532
  version
4868
5533
  };
@@ -6166,6 +6831,434 @@ function requireAnalytics() {
6166
6831
  });
6167
6832
  return analytics;
6168
6833
  }
6834
+ var whatsapp;
6835
+ var hasRequiredWhatsapp;
6836
+ function requireWhatsapp() {
6837
+ if (hasRequiredWhatsapp) return whatsapp;
6838
+ hasRequiredWhatsapp = 1;
6839
+ const path = require$$0$4;
6840
+ const fs = require$$1$3;
6841
+ let baileys = null;
6842
+ const loadBaileys = async () => {
6843
+ if (!baileys) {
6844
+ try {
6845
+ baileys = require("@whiskeysockets/baileys");
6846
+ if (process.env.DEBUG) {
6847
+ console.log("[MagicMail WhatsApp] Baileys loaded successfully");
6848
+ }
6849
+ return true;
6850
+ } catch (error) {
6851
+ console.warn("[MagicMail WhatsApp] Baileys not installed. WhatsApp features disabled.");
6852
+ console.warn("[MagicMail WhatsApp] Install with: npm install @whiskeysockets/baileys pino qrcode");
6853
+ return false;
6854
+ }
6855
+ }
6856
+ return true;
6857
+ };
6858
+ whatsapp = ({ strapi: strapi2 }) => {
6859
+ let sock = null;
6860
+ let qrCode = null;
6861
+ let connectionStatus = "disconnected";
6862
+ let lastError = null;
6863
+ let eventListeners = [];
6864
+ let wasConnectedBefore = false;
6865
+ let reconnectAttempts = 0;
6866
+ const MAX_RECONNECT_ATTEMPTS = 3;
6867
+ const isDebugEnabled = async () => {
6868
+ try {
6869
+ const pluginStore = strapi2.store({ type: "plugin", name: "magic-mail" });
6870
+ const settings = await pluginStore.get({ key: "settings" });
6871
+ return settings?.whatsapp_debug === true;
6872
+ } catch {
6873
+ return false;
6874
+ }
6875
+ };
6876
+ const debugLog = async (message) => {
6877
+ if (await isDebugEnabled()) {
6878
+ strapi2.log.info(message);
6879
+ }
6880
+ };
6881
+ const getAuthPath = () => {
6882
+ const strapiRoot = strapi2.dirs?.app?.root || process.cwd();
6883
+ return path.join(strapiRoot, ".magicmail-whatsapp-auth");
6884
+ };
6885
+ const emit = (event, data) => {
6886
+ eventListeners.forEach((listener) => {
6887
+ try {
6888
+ listener(event, data);
6889
+ } catch (e) {
6890
+ console.error("[MagicMail WhatsApp] Event listener error:", e);
6891
+ }
6892
+ });
6893
+ };
6894
+ const service = {
6895
+ /**
6896
+ * Check if Baileys is available
6897
+ * @returns {Promise<boolean>} True if Baileys is installed
6898
+ */
6899
+ async isAvailable() {
6900
+ return await loadBaileys();
6901
+ },
6902
+ /**
6903
+ * Get current connection status
6904
+ * @returns {object} Status object with status, qrCode, lastError, isConnected
6905
+ */
6906
+ getStatus() {
6907
+ return {
6908
+ status: connectionStatus,
6909
+ qrCode,
6910
+ lastError,
6911
+ isConnected: connectionStatus === "connected"
6912
+ };
6913
+ },
6914
+ /**
6915
+ * Add event listener for WhatsApp events
6916
+ * @param {function} callback - Callback function(event, data)
6917
+ * @returns {function} Unsubscribe function
6918
+ */
6919
+ on(callback) {
6920
+ eventListeners.push(callback);
6921
+ return () => {
6922
+ eventListeners = eventListeners.filter((l) => l !== callback);
6923
+ };
6924
+ },
6925
+ /**
6926
+ * Initialize WhatsApp connection
6927
+ * @returns {Promise<object>} Connection result with success status
6928
+ */
6929
+ async connect() {
6930
+ const available = await loadBaileys();
6931
+ if (!available) {
6932
+ lastError = "Baileys not installed. Run: npm install @whiskeysockets/baileys pino qrcode";
6933
+ strapi2.log.error("[MagicMail WhatsApp] [ERROR] Baileys library not available");
6934
+ return { success: false, error: lastError };
6935
+ }
6936
+ if (sock && connectionStatus === "connected") {
6937
+ await debugLog("[MagicMail WhatsApp] Already connected");
6938
+ return { success: true, status: "already_connected" };
6939
+ }
6940
+ if (sock) {
6941
+ try {
6942
+ sock.end();
6943
+ } catch (e) {
6944
+ }
6945
+ sock = null;
6946
+ }
6947
+ return new Promise(async (resolve) => {
6948
+ try {
6949
+ connectionStatus = "connecting";
6950
+ emit("status", { status: connectionStatus });
6951
+ await debugLog("[MagicMail WhatsApp] Starting connection...");
6952
+ const authPath = getAuthPath();
6953
+ if (!fs.existsSync(authPath)) {
6954
+ fs.mkdirSync(authPath, { recursive: true });
6955
+ }
6956
+ await debugLog(`[MagicMail WhatsApp] Auth path: ${authPath}`);
6957
+ const { state, saveCreds } = await baileys.useMultiFileAuthState(authPath);
6958
+ await debugLog("[MagicMail WhatsApp] Auth state loaded");
6959
+ const pino = require("pino");
6960
+ const logger2 = pino({ level: "silent" });
6961
+ await debugLog("[MagicMail WhatsApp] Creating WhatsApp socket...");
6962
+ const makeSocket = baileys.default || baileys.makeWASocket;
6963
+ const browserConfig = baileys.Browsers.ubuntu("Chrome");
6964
+ await debugLog(`[MagicMail WhatsApp] Browser config: ${JSON.stringify(browserConfig)}`);
6965
+ sock = makeSocket({
6966
+ auth: state,
6967
+ logger: logger2,
6968
+ browser: browserConfig,
6969
+ syncFullHistory: false,
6970
+ markOnlineOnConnect: false,
6971
+ generateHighQualityLinkPreview: false,
6972
+ getMessage: async (key) => {
6973
+ return { conversation: "" };
6974
+ }
6975
+ });
6976
+ await debugLog("[MagicMail WhatsApp] Socket created, registering event handlers...");
6977
+ let resolved = false;
6978
+ const resolveOnce = (result) => {
6979
+ if (!resolved) {
6980
+ resolved = true;
6981
+ resolve(result);
6982
+ }
6983
+ };
6984
+ setTimeout(() => {
6985
+ if (!resolved) {
6986
+ strapi2.log.warn("[MagicMail WhatsApp] Connection timeout - no QR or connection");
6987
+ resolveOnce({ success: true, status: connectionStatus, qrCode });
6988
+ }
6989
+ }, 3e4);
6990
+ sock.ev.on("connection.update", async (update) => {
6991
+ await debugLog(`[MagicMail WhatsApp] connection.update: ${JSON.stringify(update)}`);
6992
+ const { connection, lastDisconnect, qr } = update;
6993
+ if (qr) {
6994
+ await debugLog("[MagicMail WhatsApp] QR code received");
6995
+ try {
6996
+ const QRCode = require("qrcode");
6997
+ qrCode = await QRCode.toDataURL(qr);
6998
+ connectionStatus = "qr_pending";
6999
+ emit("qr", { qrCode });
7000
+ emit("status", { status: connectionStatus });
7001
+ strapi2.log.info("[MagicMail WhatsApp] [SUCCESS] QR Code generated - scan with WhatsApp");
7002
+ resolveOnce({ success: true, status: connectionStatus, qrCode });
7003
+ } catch (qrError) {
7004
+ strapi2.log.error("[MagicMail WhatsApp] QR generation error:", qrError.message);
7005
+ }
7006
+ }
7007
+ if (connection === "close") {
7008
+ const statusCode = lastDisconnect?.error?.output?.statusCode;
7009
+ const isLoggedOut = statusCode === baileys.DisconnectReason.loggedOut;
7010
+ const isRestartRequired = statusCode === baileys.DisconnectReason.restartRequired;
7011
+ const isConnectionFailure = statusCode === 405;
7012
+ await debugLog(`[MagicMail WhatsApp] Connection closed - statusCode: ${statusCode}`);
7013
+ if (isLoggedOut) {
7014
+ connectionStatus = "disconnected";
7015
+ lastError = "Logged out from WhatsApp";
7016
+ qrCode = null;
7017
+ wasConnectedBefore = false;
7018
+ reconnectAttempts = 0;
7019
+ try {
7020
+ fs.rmSync(authPath, { recursive: true, force: true });
7021
+ } catch (e) {
7022
+ }
7023
+ strapi2.log.warn("[MagicMail WhatsApp] Logged out - auth cleared");
7024
+ } else if (isRestartRequired) {
7025
+ await debugLog("[MagicMail WhatsApp] Restart required - reconnecting...");
7026
+ connectionStatus = "connecting";
7027
+ setTimeout(() => {
7028
+ service.connect();
7029
+ }, 1e3);
7030
+ } else if (isConnectionFailure && reconnectAttempts < 2) {
7031
+ reconnectAttempts++;
7032
+ await debugLog(`[MagicMail WhatsApp] Connection rejected (405) - retrying (${reconnectAttempts}/2)`);
7033
+ try {
7034
+ fs.rmSync(authPath, { recursive: true, force: true });
7035
+ } catch (e) {
7036
+ }
7037
+ connectionStatus = "disconnected";
7038
+ qrCode = null;
7039
+ setTimeout(() => {
7040
+ service.connect();
7041
+ }, 3e3);
7042
+ } else if (isConnectionFailure) {
7043
+ connectionStatus = "disconnected";
7044
+ lastError = "WhatsApp connection rejected (405). Please try again later.";
7045
+ strapi2.log.error("[MagicMail WhatsApp] [ERROR] Connection rejected after retries.");
7046
+ resolveOnce({ success: false, status: connectionStatus, error: lastError });
7047
+ } else if (wasConnectedBefore && reconnectAttempts < MAX_RECONNECT_ATTEMPTS) {
7048
+ reconnectAttempts++;
7049
+ connectionStatus = "connecting";
7050
+ await debugLog(`[MagicMail WhatsApp] Reconnecting (${reconnectAttempts}/${MAX_RECONNECT_ATTEMPTS})...`);
7051
+ setTimeout(() => {
7052
+ service.connect();
7053
+ }, 3e3 * reconnectAttempts);
7054
+ } else if (!wasConnectedBefore) {
7055
+ connectionStatus = "disconnected";
7056
+ qrCode = null;
7057
+ await debugLog("[MagicMail WhatsApp] Connection closed - waiting for QR scan");
7058
+ } else {
7059
+ connectionStatus = "disconnected";
7060
+ lastError = "Max reconnect attempts reached";
7061
+ strapi2.log.warn("[MagicMail WhatsApp] Max reconnect attempts reached");
7062
+ }
7063
+ emit("status", { status: connectionStatus, error: lastError });
7064
+ }
7065
+ if (connection === "open") {
7066
+ connectionStatus = "connected";
7067
+ qrCode = null;
7068
+ lastError = null;
7069
+ wasConnectedBefore = true;
7070
+ reconnectAttempts = 0;
7071
+ emit("status", { status: connectionStatus });
7072
+ strapi2.log.info("[MagicMail WhatsApp] [SUCCESS] Connected successfully!");
7073
+ resolveOnce({ success: true, status: connectionStatus });
7074
+ }
7075
+ });
7076
+ sock.ev.on("creds.update", saveCreds);
7077
+ } catch (error) {
7078
+ lastError = error.message;
7079
+ connectionStatus = "disconnected";
7080
+ strapi2.log.error("[MagicMail WhatsApp] Connection error:", error);
7081
+ resolve({ success: false, error: error.message });
7082
+ }
7083
+ });
7084
+ },
7085
+ /**
7086
+ * Disconnect WhatsApp and clear session
7087
+ * @returns {Promise<object>} Result with success status
7088
+ */
7089
+ async disconnect() {
7090
+ if (sock) {
7091
+ try {
7092
+ await sock.logout();
7093
+ } catch (e) {
7094
+ }
7095
+ sock = null;
7096
+ }
7097
+ connectionStatus = "disconnected";
7098
+ qrCode = null;
7099
+ emit("status", { status: connectionStatus });
7100
+ strapi2.log.info("[MagicMail WhatsApp] Disconnected");
7101
+ return { success: true };
7102
+ },
7103
+ /**
7104
+ * Send a text message to a phone number
7105
+ * @param {string} phoneNumber - Phone number with country code (e.g., "491234567890")
7106
+ * @param {string} message - Message text
7107
+ * @returns {Promise<object>} Result with success status
7108
+ */
7109
+ async sendMessage(phoneNumber, message) {
7110
+ if (connectionStatus !== "connected" || !sock) {
7111
+ return {
7112
+ success: false,
7113
+ error: "WhatsApp not connected. Please connect first."
7114
+ };
7115
+ }
7116
+ try {
7117
+ const formattedNumber = phoneNumber.replace(/[^\d]/g, "");
7118
+ const jid = `${formattedNumber}@s.whatsapp.net`;
7119
+ const [exists] = await sock.onWhatsApp(formattedNumber);
7120
+ if (!exists?.exists) {
7121
+ return {
7122
+ success: false,
7123
+ error: `Phone number ${phoneNumber} is not registered on WhatsApp`
7124
+ };
7125
+ }
7126
+ await sock.sendMessage(jid, { text: message });
7127
+ await debugLog(`[MagicMail WhatsApp] Message sent to ${formattedNumber}`);
7128
+ return { success: true, jid };
7129
+ } catch (error) {
7130
+ strapi2.log.error("[MagicMail WhatsApp] Send error:", error);
7131
+ return { success: false, error: error.message };
7132
+ }
7133
+ },
7134
+ /**
7135
+ * Send message using a template
7136
+ * @param {string} phoneNumber - Phone number
7137
+ * @param {string} templateName - Template identifier
7138
+ * @param {object} variables - Template variables to replace
7139
+ * @returns {Promise<object>} Result with success status
7140
+ */
7141
+ async sendTemplateMessage(phoneNumber, templateName, variables = {}) {
7142
+ try {
7143
+ const pluginStore = strapi2.store({ type: "plugin", name: "magic-mail" });
7144
+ const templates = await pluginStore.get({ key: "whatsapp_templates" }) || {};
7145
+ let template = templates[templateName];
7146
+ if (!template) {
7147
+ template = `*{{subject}}*
7148
+
7149
+ {{body}}`;
7150
+ }
7151
+ let message = template;
7152
+ for (const [key, value] of Object.entries(variables)) {
7153
+ message = message.replace(new RegExp(`{{${key}}}`, "g"), value);
7154
+ }
7155
+ return this.sendMessage(phoneNumber, message);
7156
+ } catch (error) {
7157
+ return { success: false, error: error.message };
7158
+ }
7159
+ },
7160
+ /**
7161
+ * Check if a phone number is on WhatsApp
7162
+ * @param {string} phoneNumber - Phone number to check
7163
+ * @returns {Promise<object>} Result with exists boolean
7164
+ */
7165
+ async checkNumber(phoneNumber) {
7166
+ if (connectionStatus !== "connected" || !sock) {
7167
+ return { success: false, error: "WhatsApp not connected" };
7168
+ }
7169
+ try {
7170
+ const formattedNumber = phoneNumber.replace(/[^\d]/g, "");
7171
+ const [result] = await sock.onWhatsApp(formattedNumber);
7172
+ return {
7173
+ success: true,
7174
+ exists: result?.exists || false,
7175
+ jid: result?.jid
7176
+ };
7177
+ } catch (error) {
7178
+ return { success: false, error: error.message };
7179
+ }
7180
+ },
7181
+ /**
7182
+ * Get session info
7183
+ * @returns {Promise<object|null>} Session info or null if not connected
7184
+ */
7185
+ async getSessionInfo() {
7186
+ if (connectionStatus !== "connected" || !sock) {
7187
+ return null;
7188
+ }
7189
+ try {
7190
+ const user = sock.user;
7191
+ return {
7192
+ phoneNumber: user?.id?.split(":")[0] || user?.id?.split("@")[0],
7193
+ name: user?.name,
7194
+ platform: "WhatsApp Web"
7195
+ };
7196
+ } catch (error) {
7197
+ return null;
7198
+ }
7199
+ },
7200
+ /**
7201
+ * Reset connection state (for manual cleanup)
7202
+ */
7203
+ reset() {
7204
+ sock = null;
7205
+ qrCode = null;
7206
+ connectionStatus = "disconnected";
7207
+ lastError = null;
7208
+ wasConnectedBefore = false;
7209
+ reconnectAttempts = 0;
7210
+ },
7211
+ /**
7212
+ * Save WhatsApp template
7213
+ * @param {string} templateName - Template identifier
7214
+ * @param {string} templateContent - Template content with {{variables}}
7215
+ * @returns {Promise<object>} Result with success status
7216
+ */
7217
+ async saveTemplate(templateName, templateContent) {
7218
+ try {
7219
+ const pluginStore = strapi2.store({ type: "plugin", name: "magic-mail" });
7220
+ const templates = await pluginStore.get({ key: "whatsapp_templates" }) || {};
7221
+ templates[templateName] = templateContent;
7222
+ await pluginStore.set({ key: "whatsapp_templates", value: templates });
7223
+ return { success: true };
7224
+ } catch (error) {
7225
+ return { success: false, error: error.message };
7226
+ }
7227
+ },
7228
+ /**
7229
+ * Get all WhatsApp templates
7230
+ * @returns {Promise<object>} Templates object
7231
+ */
7232
+ async getTemplates() {
7233
+ try {
7234
+ const pluginStore = strapi2.store({ type: "plugin", name: "magic-mail" });
7235
+ const templates = await pluginStore.get({ key: "whatsapp_templates" }) || {};
7236
+ return templates;
7237
+ } catch (error) {
7238
+ return {};
7239
+ }
7240
+ },
7241
+ /**
7242
+ * Delete a WhatsApp template
7243
+ * @param {string} templateName - Template identifier
7244
+ * @returns {Promise<object>} Result with success status
7245
+ */
7246
+ async deleteTemplate(templateName) {
7247
+ try {
7248
+ const pluginStore = strapi2.store({ type: "plugin", name: "magic-mail" });
7249
+ const templates = await pluginStore.get({ key: "whatsapp_templates" }) || {};
7250
+ delete templates[templateName];
7251
+ await pluginStore.set({ key: "whatsapp_templates", value: templates });
7252
+ return { success: true };
7253
+ } catch (error) {
7254
+ return { success: false, error: error.message };
7255
+ }
7256
+ }
7257
+ };
7258
+ return service;
7259
+ };
7260
+ return whatsapp;
7261
+ }
6169
7262
  var services;
6170
7263
  var hasRequiredServices;
6171
7264
  function requireServices() {
@@ -6177,13 +7270,15 @@ function requireServices() {
6177
7270
  const licenseGuard2 = requireLicenseGuard();
6178
7271
  const emailDesigner2 = requireEmailDesigner();
6179
7272
  const analytics2 = requireAnalytics();
7273
+ const whatsapp2 = requireWhatsapp();
6180
7274
  services = {
6181
7275
  "email-router": emailRouter2,
6182
7276
  "account-manager": accountManager2,
6183
7277
  oauth: oauth2,
6184
7278
  "license-guard": licenseGuard2,
6185
7279
  "email-designer": emailDesigner2,
6186
- analytics: analytics2
7280
+ analytics: analytics2,
7281
+ whatsapp: whatsapp2
6187
7282
  };
6188
7283
  return services;
6189
7284
  }