@blinkdotnew/sdk 0.10.2 → 0.10.3

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.
Files changed (2) hide show
  1. package/README.md +190 -24
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -520,51 +520,217 @@ await blink.storage.remove('file1.jpg', 'file2.jpg')
520
520
  ### Notifications Operations
521
521
 
522
522
  ```typescript
523
- // Send a simple email
524
- const { success, messageId } = await blink.notifications.email({
523
+ // 🔥 Email Notifications (NEW!) - Send emails with attachments, custom branding, and delivery tracking
524
+
525
+ // Send a simple email - returns success status and message ID
526
+ const result = await blink.notifications.email({
525
527
  to: 'customer@example.com',
526
528
  subject: 'Your order has shipped!',
527
529
  html: '<h1>Order Confirmation</h1><p>Your order #12345 is on its way.</p>'
528
530
  })
529
531
 
530
- // Send an email with attachments and custom sender
531
- const { success } = await blink.notifications.email({
532
+ console.log(result.success) // true/false - whether email was sent
533
+ console.log(result.messageId) // "msg_abc123..." - unique message identifier
534
+
535
+ // Send with plain text fallback (recommended for better deliverability)
536
+ const { success, messageId } = await blink.notifications.email({
537
+ to: 'customer@example.com',
538
+ subject: 'Welcome to our platform!',
539
+ html: '<h1>Welcome!</h1><p>Thanks for joining us.</p>',
540
+ text: 'Welcome!\n\nThanks for joining us.' // Plain text version
541
+ })
542
+
543
+ // Send an email with attachments and custom branding
544
+ const result = await blink.notifications.email({
532
545
  to: ['team@example.com', 'manager@example.com'],
533
- from: 'Blink Invoicing', // Custom sender name
534
- replyTo: 'support@example.com',
535
- subject: 'New Invoice',
536
- html: '<p>Please find the invoice attached.</p>',
537
- text: 'Please find the invoice attached.', // Plain text fallback
538
- cc: 'manager@example.com',
539
- bcc: 'archive@example.com',
546
+ from: 'invoices@mycompany.com', // Must be valid email address
547
+ replyTo: 'support@mycompany.com',
548
+ subject: 'New Invoice #12345',
549
+ html: `
550
+ <div style="font-family: Arial, sans-serif;">
551
+ <h2>Invoice Ready</h2>
552
+ <p>Please find the invoice attached.</p>
553
+ </div>
554
+ `,
555
+ text: 'Invoice Ready\n\nPlease find the invoice attached.',
556
+ cc: 'accounting@mycompany.com',
557
+ bcc: 'archive@mycompany.com',
540
558
  attachments: [
541
559
  {
542
- url: 'https://example.com/invoice.pdf',
543
- filename: 'invoice.pdf',
544
- type: 'application/pdf'
560
+ url: 'https://mycompany.com/invoices/12345.pdf',
561
+ filename: 'Invoice-12345.pdf', // Custom filename
562
+ type: 'application/pdf' // MIME type (optional)
563
+ },
564
+ {
565
+ url: 'https://mycompany.com/terms.pdf',
566
+ filename: 'Terms-of-Service.pdf'
545
567
  }
546
568
  ]
547
569
  })
548
570
 
549
- // Send to multiple recipients
550
- const { success } = await blink.notifications.email({
551
- to: ['user1@example.com', 'user2@example.com'],
552
- subject: 'Team Update',
553
- html: '<h2>Weekly Update</h2><p>Here are this week\'s highlights...</p>'
571
+ console.log(`Email ${result.success ? 'sent' : 'failed'}`)
572
+ console.log(`Message ID: ${result.messageId}`)
573
+
574
+ // Send to multiple recipients with different recipient types
575
+ const { success, messageId } = await blink.notifications.email({
576
+ to: ['customer1@example.com', 'customer2@example.com'],
577
+ cc: ['manager@example.com'],
578
+ bcc: ['audit@example.com', 'backup@example.com'],
579
+ from: 'notifications@mycompany.com',
580
+ subject: 'Monthly Newsletter',
581
+ html: '<h2>This Month\'s Updates</h2><p>Here are the highlights...</p>'
554
582
  })
555
583
 
556
- // Error handling
584
+ // Dynamic email content with user data
585
+ const user = await blink.auth.me()
586
+ const welcomeEmail = await blink.notifications.email({
587
+ to: user.email,
588
+ from: 'welcome@mycompany.com',
589
+ subject: `Welcome ${user.displayName}!`,
590
+ html: `
591
+ <h1>Hi ${user.displayName}!</h1>
592
+ <p>Welcome to our platform. Your account is now active.</p>
593
+ <p>Account ID: ${user.id}</p>
594
+ <a href="https://myapp.com/dashboard">Get Started</a>
595
+ `,
596
+ text: `Hi ${user.displayName}!\n\nWelcome to our platform. Your account is now active.\nAccount ID: ${user.id}\n\nGet Started: https://myapp.com/dashboard`
597
+ })
598
+
599
+ // Comprehensive error handling with detailed error information
557
600
  try {
558
- await blink.notifications.email({
601
+ const result = await blink.notifications.email({
559
602
  to: 'customer@example.com',
560
- subject: 'Welcome!',
561
- html: '<p>Welcome to our service!</p>'
603
+ subject: 'Important Update',
604
+ html: '<p>This is an important update about your account.</p>'
562
605
  })
606
+
607
+ if (result.success) {
608
+ console.log('✅ Email sent successfully!')
609
+ console.log('📧 Message ID:', result.messageId)
610
+ } else {
611
+ console.error('❌ Email failed to send')
612
+ // Handle failed send (retry logic, fallback notification, etc.)
613
+ }
614
+
563
615
  } catch (error) {
564
616
  if (error instanceof BlinkNotificationsError) {
565
- console.error('Failed to send email:', error.message)
617
+ console.error(' Email error:', error.message)
618
+
619
+ // Common error scenarios:
620
+ // - "The 'to', 'subject', and either 'html' or 'text' fields are required."
621
+ // - "Invalid email address format"
622
+ // - "Attachment URL must be accessible"
623
+ // - "Failed to send email: Rate limit exceeded"
624
+
625
+ // Handle specific error types
626
+ if (error.message.includes('Rate limit')) {
627
+ // Implement retry with backoff
628
+ console.log('⏳ Rate limited, will retry later')
629
+ } else if (error.message.includes('Invalid email')) {
630
+ // Log invalid email for cleanup
631
+ console.log('📧 Invalid email address, removing from list')
632
+ }
633
+ } else {
634
+ console.error('❌ Unexpected error:', error)
566
635
  }
567
636
  }
637
+
638
+ // Email validation and best practices
639
+ const validateAndSendEmail = async (recipient: string, subject: string, content: string) => {
640
+ // Basic validation
641
+ if (!recipient.includes('@') || !subject.trim() || !content.trim()) {
642
+ throw new Error('Invalid email parameters')
643
+ }
644
+
645
+ try {
646
+ const result = await blink.notifications.email({
647
+ to: recipient,
648
+ from: 'noreply@mycompany.com',
649
+ subject: subject,
650
+ html: `
651
+ <div style="max-width: 600px; margin: 0 auto; font-family: Arial, sans-serif;">
652
+ <div style="background: #f8f9fa; padding: 20px; text-align: center;">
653
+ <h1 style="color: #333; margin: 0;">My Company</h1>
654
+ </div>
655
+ <div style="padding: 20px;">
656
+ ${content}
657
+ </div>
658
+ <div style="background: #f8f9fa; padding: 15px; text-align: center; font-size: 12px; color: #666;">
659
+ <p>© 2024 My Company. All rights reserved.</p>
660
+ <p><a href="https://mycompany.com/unsubscribe">Unsubscribe</a></p>
661
+ </div>
662
+ </div>
663
+ `,
664
+ text: content.replace(/<[^>]*>/g, '') // Strip HTML for text version
665
+ })
666
+
667
+ return result
668
+ } catch (error) {
669
+ console.error(`Failed to send email to ${recipient}:`, error)
670
+ throw error
671
+ }
672
+ }
673
+
674
+ // Usage with validation
675
+ try {
676
+ const result = await validateAndSendEmail(
677
+ 'customer@example.com',
678
+ 'Account Verification Required',
679
+ '<p>Please verify your account by clicking the link below.</p><a href="https://myapp.com/verify">Verify Account</a>'
680
+ )
681
+ console.log('Email sent with ID:', result.messageId)
682
+ } catch (error) {
683
+ console.error('Email validation or sending failed:', error.message)
684
+ }
685
+
686
+ // Bulk email sending with error handling
687
+ const sendBulkEmails = async (recipients: string[], subject: string, htmlContent: string) => {
688
+ const results = []
689
+
690
+ for (const recipient of recipients) {
691
+ try {
692
+ const result = await blink.notifications.email({
693
+ to: recipient,
694
+ from: 'newsletter@mycompany.com',
695
+ subject,
696
+ html: htmlContent,
697
+ text: htmlContent.replace(/<[^>]*>/g, '')
698
+ })
699
+
700
+ results.push({
701
+ recipient,
702
+ success: result.success,
703
+ messageId: result.messageId
704
+ })
705
+
706
+ // Rate limiting: wait between sends
707
+ await new Promise(resolve => setTimeout(resolve, 100))
708
+
709
+ } catch (error) {
710
+ results.push({
711
+ recipient,
712
+ success: false,
713
+ error: error.message
714
+ })
715
+ }
716
+ }
717
+
718
+ return results
719
+ }
720
+
721
+ // Response format details:
722
+ // ✅ Success response: { success: true, messageId: "msg_abc123..." }
723
+ // ❌ The method throws BlinkNotificationsError on failure
724
+ // 🔍 Error types: validation errors, rate limits, network issues, invalid attachments
725
+
726
+ // Best practices:
727
+ // 1. Always include both HTML and text versions for better deliverability
728
+ // 2. Use valid email addresses for 'from' field (not display names)
729
+ // 3. Keep HTML simple with inline CSS for email client compatibility
730
+ // 4. Handle rate limits with retry logic
731
+ // 5. Validate email addresses before sending
732
+ // 6. Use message IDs for tracking and debugging
733
+ // 7. Include unsubscribe links for compliance
568
734
  ```
569
735
 
570
736
  ### Analytics Operations
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blinkdotnew/sdk",
3
- "version": "0.10.2",
3
+ "version": "0.10.3",
4
4
  "description": "Blink TypeScript SDK for client-side applications - Zero-boilerplate CRUD + auth + AI + analytics + notifications for modern SaaS/AI apps",
5
5
  "keywords": [
6
6
  "blink",