@metigan/angular 1.0.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.
- package/LICENSE +22 -0
- package/README.md +581 -0
- package/dist/LICENSE +22 -0
- package/dist/README.md +581 -0
- package/dist/esm2022/metigan-angular.mjs +5 -0
- package/dist/esm2022/public-api.mjs +21 -0
- package/dist/esm2022/src/lib/audiences.service.mjs +157 -0
- package/dist/esm2022/src/lib/config.mjs +30 -0
- package/dist/esm2022/src/lib/contacts.service.mjs +267 -0
- package/dist/esm2022/src/lib/email.service.mjs +267 -0
- package/dist/esm2022/src/lib/errors.mjs +40 -0
- package/dist/esm2022/src/lib/forms.service.mjs +180 -0
- package/dist/esm2022/src/lib/http-client.service.mjs +111 -0
- package/dist/esm2022/src/lib/metigan.module.mjs +67 -0
- package/dist/esm2022/src/lib/metigan.service.mjs +72 -0
- package/dist/esm2022/src/lib/templates.service.mjs +85 -0
- package/dist/esm2022/src/lib/types.mjs +6 -0
- package/dist/fesm2022/metigan-angular.mjs +1241 -0
- package/dist/fesm2022/metigan-angular.mjs.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/public-api.d.ts +15 -0
- package/dist/src/lib/audiences.service.d.ts +62 -0
- package/dist/src/lib/config.d.ts +28 -0
- package/dist/src/lib/contacts.service.d.ts +80 -0
- package/dist/src/lib/email.service.d.ts +44 -0
- package/dist/src/lib/errors.d.ts +24 -0
- package/dist/src/lib/forms.service.d.ts +67 -0
- package/dist/src/lib/http-client.service.d.ts +46 -0
- package/dist/src/lib/metigan.module.d.ts +27 -0
- package/dist/src/lib/metigan.service.d.ts +27 -0
- package/dist/src/lib/templates.service.d.ts +36 -0
- package/dist/src/lib/types.d.ts +329 -0
- package/examples/basic.component.ts +113 -0
- package/ng-package.json +8 -0
- package/package.json +68 -0
- package/public-api.ts +26 -0
- package/src/lib/audiences.service.ts +230 -0
- package/src/lib/config.ts +35 -0
- package/src/lib/contacts.service.ts +377 -0
- package/src/lib/email.service.ts +286 -0
- package/src/lib/errors.ts +45 -0
- package/src/lib/forms.service.ts +263 -0
- package/src/lib/http-client.service.ts +156 -0
- package/src/lib/metigan.module.ts +55 -0
- package/src/lib/metigan.service.ts +80 -0
- package/src/lib/templates.service.ts +103 -0
- package/src/lib/types.ts +398 -0
- package/tsconfig.json +38 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Metigan
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
package/README.md
ADDED
|
@@ -0,0 +1,581 @@
|
|
|
1
|
+
# Metigan Angular SDK
|
|
2
|
+
|
|
3
|
+
Official Metigan SDK for Angular. Send emails, manage forms, contacts, and audiences with ease in your Angular applications.
|
|
4
|
+
|
|
5
|
+
## 📦 Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @metigan/angular
|
|
9
|
+
# or
|
|
10
|
+
yarn add @metigan/angular
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## 🚀 Quick Start
|
|
14
|
+
|
|
15
|
+
### 1. Import the Module
|
|
16
|
+
|
|
17
|
+
In your `app.module.ts`:
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { NgModule } from '@angular/core';
|
|
21
|
+
import { MetiganModule } from '@metigan/angular';
|
|
22
|
+
|
|
23
|
+
@NgModule({
|
|
24
|
+
imports: [
|
|
25
|
+
MetiganModule.forRoot({
|
|
26
|
+
apiKey: 'your-api-key'
|
|
27
|
+
})
|
|
28
|
+
]
|
|
29
|
+
})
|
|
30
|
+
export class AppModule { }
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### 2. Use in Components
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
import { Component, OnInit } from '@angular/core';
|
|
37
|
+
import { MetiganService } from '@metigan/angular';
|
|
38
|
+
|
|
39
|
+
@Component({
|
|
40
|
+
selector: 'app-my-component',
|
|
41
|
+
template: '<button (click)="sendEmail()">Send Email</button>'
|
|
42
|
+
})
|
|
43
|
+
export class MyComponent implements OnInit {
|
|
44
|
+
constructor(private metigan: MetiganService) {}
|
|
45
|
+
|
|
46
|
+
sendEmail() {
|
|
47
|
+
this.metigan.email.sendEmail({
|
|
48
|
+
from: 'Your Company <noreply@yourcompany.com>',
|
|
49
|
+
recipients: ['customer@email.com'],
|
|
50
|
+
subject: 'Welcome!',
|
|
51
|
+
content: '<h1>Hello!</h1><p>Thank you for signing up.</p>'
|
|
52
|
+
}).subscribe({
|
|
53
|
+
next: (response) => {
|
|
54
|
+
console.log('Email sent:', response.message);
|
|
55
|
+
console.log('Emails remaining:', response.emailsRemaining);
|
|
56
|
+
},
|
|
57
|
+
error: (error) => {
|
|
58
|
+
console.error('Error sending email:', error);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Alternative: Manual Initialization
|
|
66
|
+
|
|
67
|
+
If you prefer to initialize manually (useful for dynamic API keys):
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
import { Component, OnInit } from '@angular/core';
|
|
71
|
+
import { MetiganService } from '@metigan/angular';
|
|
72
|
+
|
|
73
|
+
@Component({
|
|
74
|
+
selector: 'app-my-component',
|
|
75
|
+
template: ''
|
|
76
|
+
})
|
|
77
|
+
export class MyComponent implements OnInit {
|
|
78
|
+
constructor(private metigan: MetiganService) {}
|
|
79
|
+
|
|
80
|
+
ngOnInit() {
|
|
81
|
+
// Initialize with your API key
|
|
82
|
+
this.metigan.initialize({
|
|
83
|
+
apiKey: 'your-api-key',
|
|
84
|
+
timeout: 30000,
|
|
85
|
+
retryCount: 3
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## 📧 Email Module
|
|
92
|
+
|
|
93
|
+
### Send Email
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
this.metigan.email.sendEmail({
|
|
97
|
+
from: 'sender@example.com',
|
|
98
|
+
recipients: ['recipient@example.com'],
|
|
99
|
+
subject: 'Email Subject',
|
|
100
|
+
content: '<h1>HTML Content</h1>'
|
|
101
|
+
}).subscribe({
|
|
102
|
+
next: (response) => console.log('Sent:', response),
|
|
103
|
+
error: (error) => console.error('Error:', error)
|
|
104
|
+
});
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Send Email with Attachments
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
|
|
111
|
+
const files = Array.from(fileInput.files || []);
|
|
112
|
+
|
|
113
|
+
this.metigan.email.sendEmail({
|
|
114
|
+
from: 'company@email.com',
|
|
115
|
+
recipients: ['customer@email.com'],
|
|
116
|
+
subject: 'Important Document',
|
|
117
|
+
content: 'Please find the document attached.',
|
|
118
|
+
attachments: files
|
|
119
|
+
}).subscribe({
|
|
120
|
+
next: (response) => console.log('Sent with attachments'),
|
|
121
|
+
error: (error) => console.error('Error:', error)
|
|
122
|
+
});
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Send Email with CC and BCC
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
this.metigan.email.sendEmail({
|
|
129
|
+
from: 'company@email.com',
|
|
130
|
+
recipients: ['main@email.com'],
|
|
131
|
+
subject: 'Meeting',
|
|
132
|
+
content: 'Email content',
|
|
133
|
+
cc: ['copy@email.com'],
|
|
134
|
+
bcc: ['hidden-copy@email.com'],
|
|
135
|
+
replyTo: 'reply-here@email.com'
|
|
136
|
+
}).subscribe({
|
|
137
|
+
next: (response) => console.log('Sent'),
|
|
138
|
+
error: (error) => console.error('Error:', error)
|
|
139
|
+
});
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Send Email with Template
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
this.metigan.email.sendEmail({
|
|
146
|
+
from: 'sender@example.com',
|
|
147
|
+
recipients: ['recipient@example.com'],
|
|
148
|
+
subject: 'Welcome Email',
|
|
149
|
+
templateId: 'template-123'
|
|
150
|
+
}).subscribe({
|
|
151
|
+
next: (response) => console.log('Sent'),
|
|
152
|
+
error: (error) => console.error('Error:', error)
|
|
153
|
+
});
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## 📋 Forms Module
|
|
157
|
+
|
|
158
|
+
### Submit Form
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
this.metigan.forms.submit({
|
|
162
|
+
formId: 'form-123', // or form slug
|
|
163
|
+
data: {
|
|
164
|
+
'field-email': 'user@email.com',
|
|
165
|
+
'field-name': 'John Doe',
|
|
166
|
+
'field-message': 'Hello, I would like more information.'
|
|
167
|
+
}
|
|
168
|
+
}).subscribe({
|
|
169
|
+
next: (response) => {
|
|
170
|
+
console.log(response.message); // "Thank you for your submission!"
|
|
171
|
+
},
|
|
172
|
+
error: (error) => console.error('Error:', error)
|
|
173
|
+
});
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Get Public Form
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
// By slug (for public display, no API key required)
|
|
180
|
+
this.metigan.forms.getPublicForm('my-form').subscribe({
|
|
181
|
+
next: (form) => {
|
|
182
|
+
console.log(form.title);
|
|
183
|
+
console.log(form.fields);
|
|
184
|
+
},
|
|
185
|
+
error: (error) => console.error('Error:', error)
|
|
186
|
+
});
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### List Forms
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
this.metigan.forms.listForms({
|
|
193
|
+
page: 1,
|
|
194
|
+
limit: 10
|
|
195
|
+
}).subscribe({
|
|
196
|
+
next: (response) => {
|
|
197
|
+
response.forms.forEach(form => {
|
|
198
|
+
console.log(`${form.title} - ${form.analytics?.submissions || 0} responses`);
|
|
199
|
+
});
|
|
200
|
+
},
|
|
201
|
+
error: (error) => console.error('Error:', error)
|
|
202
|
+
});
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Create Form
|
|
206
|
+
|
|
207
|
+
```typescript
|
|
208
|
+
this.metigan.forms.createForm({
|
|
209
|
+
title: 'Contact Form',
|
|
210
|
+
description: 'Get in touch with us',
|
|
211
|
+
fields: [
|
|
212
|
+
{
|
|
213
|
+
id: 'field-email',
|
|
214
|
+
type: 'email',
|
|
215
|
+
label: 'Your Email',
|
|
216
|
+
required: true
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
id: 'field-name',
|
|
220
|
+
type: 'text',
|
|
221
|
+
label: 'Your Name',
|
|
222
|
+
required: true
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
id: 'field-message',
|
|
226
|
+
type: 'textarea',
|
|
227
|
+
label: 'Message',
|
|
228
|
+
required: true
|
|
229
|
+
}
|
|
230
|
+
],
|
|
231
|
+
settings: {
|
|
232
|
+
successMessage: 'Thank you! We will get back to you soon.',
|
|
233
|
+
notifyEmail: 'contact@company.com'
|
|
234
|
+
}
|
|
235
|
+
}).subscribe({
|
|
236
|
+
next: (form) => console.log('Form created:', form),
|
|
237
|
+
error: (error) => console.error('Error:', error)
|
|
238
|
+
});
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
## 👥 Contacts Module
|
|
242
|
+
|
|
243
|
+
### Create Contact
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
this.metigan.contacts.create({
|
|
247
|
+
email: 'new@email.com',
|
|
248
|
+
firstName: 'Jane',
|
|
249
|
+
lastName: 'Doe',
|
|
250
|
+
audienceId: 'audience-123',
|
|
251
|
+
tags: ['customer', 'newsletter']
|
|
252
|
+
}).subscribe({
|
|
253
|
+
next: (contact) => console.log('Contact created:', contact),
|
|
254
|
+
error: (error) => console.error('Error:', error)
|
|
255
|
+
});
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### Get Contact
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
// By ID
|
|
262
|
+
this.metigan.contacts.get('contact-456').subscribe({
|
|
263
|
+
next: (contact) => console.log('Contact:', contact),
|
|
264
|
+
error: (error) => console.error('Error:', error)
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
// By email
|
|
268
|
+
this.metigan.contacts.getByEmail('jane@email.com', 'audience-123').subscribe({
|
|
269
|
+
next: (contact) => console.log('Contact:', contact),
|
|
270
|
+
error: (error) => console.error('Error:', error)
|
|
271
|
+
});
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### Update Contact
|
|
275
|
+
|
|
276
|
+
```typescript
|
|
277
|
+
this.metigan.contacts.update('contact-456', {
|
|
278
|
+
firstName: 'Jane Marie',
|
|
279
|
+
tags: ['customer', 'vip']
|
|
280
|
+
}).subscribe({
|
|
281
|
+
next: (updated) => console.log('Contact updated:', updated),
|
|
282
|
+
error: (error) => console.error('Error:', error)
|
|
283
|
+
});
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### List Contacts
|
|
287
|
+
|
|
288
|
+
```typescript
|
|
289
|
+
this.metigan.contacts.list({
|
|
290
|
+
audienceId: 'audience-123',
|
|
291
|
+
status: 'subscribed',
|
|
292
|
+
tag: 'customer',
|
|
293
|
+
page: 1,
|
|
294
|
+
limit: 50
|
|
295
|
+
}).subscribe({
|
|
296
|
+
next: (response) => {
|
|
297
|
+
response.contacts.forEach(contact => {
|
|
298
|
+
console.log(`${contact.email}: ${contact.firstName}`);
|
|
299
|
+
});
|
|
300
|
+
},
|
|
301
|
+
error: (error) => console.error('Error:', error)
|
|
302
|
+
});
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### Manage Subscription
|
|
306
|
+
|
|
307
|
+
```typescript
|
|
308
|
+
// Unsubscribe
|
|
309
|
+
this.metigan.contacts.unsubscribe('contact-456').subscribe({
|
|
310
|
+
next: (contact) => console.log('Unsubscribed:', contact),
|
|
311
|
+
error: (error) => console.error('Error:', error)
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
// Resubscribe
|
|
315
|
+
this.metigan.contacts.subscribe('contact-456').subscribe({
|
|
316
|
+
next: (contact) => console.log('Subscribed:', contact),
|
|
317
|
+
error: (error) => console.error('Error:', error)
|
|
318
|
+
});
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
### Manage Tags
|
|
322
|
+
|
|
323
|
+
```typescript
|
|
324
|
+
// Add tags
|
|
325
|
+
this.metigan.contacts.addTags('contact-456', ['vip', 'black-friday']).subscribe({
|
|
326
|
+
next: (contact) => console.log('Tags added:', contact),
|
|
327
|
+
error: (error) => console.error('Error:', error)
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
// Remove tags
|
|
331
|
+
this.metigan.contacts.removeTags('contact-456', ['test']).subscribe({
|
|
332
|
+
next: (contact) => console.log('Tags removed:', contact),
|
|
333
|
+
error: (error) => console.error('Error:', error)
|
|
334
|
+
});
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### Bulk Import
|
|
338
|
+
|
|
339
|
+
```typescript
|
|
340
|
+
this.metigan.contacts.bulkImport(
|
|
341
|
+
[
|
|
342
|
+
{ email: 'john@email.com', firstName: 'John', audienceId: 'audience-123' },
|
|
343
|
+
{ email: 'jane@email.com', firstName: 'Jane', audienceId: 'audience-123' },
|
|
344
|
+
{ email: 'peter@email.com', firstName: 'Peter', audienceId: 'audience-123', tags: ['vip'] }
|
|
345
|
+
],
|
|
346
|
+
'audience-123'
|
|
347
|
+
).subscribe({
|
|
348
|
+
next: (result) => {
|
|
349
|
+
console.log(`Imported: ${result.imported}`);
|
|
350
|
+
console.log(`Failed: ${result.failed}`);
|
|
351
|
+
},
|
|
352
|
+
error: (error) => console.error('Error:', error)
|
|
353
|
+
});
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
## 📊 Audiences Module
|
|
357
|
+
|
|
358
|
+
### Create Audience
|
|
359
|
+
|
|
360
|
+
```typescript
|
|
361
|
+
this.metigan.audiences.create({
|
|
362
|
+
name: 'Main Newsletter',
|
|
363
|
+
description: 'Main subscriber list'
|
|
364
|
+
}).subscribe({
|
|
365
|
+
next: (audience) => console.log('Audience created:', audience),
|
|
366
|
+
error: (error) => console.error('Error:', error)
|
|
367
|
+
});
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
### List Audiences
|
|
371
|
+
|
|
372
|
+
```typescript
|
|
373
|
+
this.metigan.audiences.list({
|
|
374
|
+
page: 1,
|
|
375
|
+
limit: 10
|
|
376
|
+
}).subscribe({
|
|
377
|
+
next: (response) => {
|
|
378
|
+
response.audiences.forEach(audience => {
|
|
379
|
+
console.log(`${audience.name}: ${audience.count} contacts`);
|
|
380
|
+
});
|
|
381
|
+
},
|
|
382
|
+
error: (error) => console.error('Error:', error)
|
|
383
|
+
});
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
### Get Audience Statistics
|
|
387
|
+
|
|
388
|
+
```typescript
|
|
389
|
+
this.metigan.audiences.getStats('audience-123').subscribe({
|
|
390
|
+
next: (stats) => {
|
|
391
|
+
console.log(`Total: ${stats.total}`);
|
|
392
|
+
console.log(`Subscribed: ${stats.subscribed}`);
|
|
393
|
+
console.log(`Unsubscribed: ${stats.unsubscribed}`);
|
|
394
|
+
},
|
|
395
|
+
error: (error) => console.error('Error:', error)
|
|
396
|
+
});
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
### Clean Audience
|
|
400
|
+
|
|
401
|
+
```typescript
|
|
402
|
+
// Remove bounced and unsubscribed contacts
|
|
403
|
+
this.metigan.audiences.clean('audience-123').subscribe({
|
|
404
|
+
next: (result) => console.log(`${result.removed} contacts removed`),
|
|
405
|
+
error: (error) => console.error('Error:', error)
|
|
406
|
+
});
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
### Merge Audiences
|
|
410
|
+
|
|
411
|
+
```typescript
|
|
412
|
+
// Merge source into target (source is deleted)
|
|
413
|
+
this.metigan.audiences.merge(
|
|
414
|
+
'source-audience-id',
|
|
415
|
+
'target-audience-id'
|
|
416
|
+
).subscribe({
|
|
417
|
+
next: (merged) => console.log('Audiences merged:', merged),
|
|
418
|
+
error: (error) => console.error('Error:', error)
|
|
419
|
+
});
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
## 📧 Templates Module
|
|
423
|
+
|
|
424
|
+
### List Templates
|
|
425
|
+
|
|
426
|
+
```typescript
|
|
427
|
+
this.metigan.templates.list({
|
|
428
|
+
page: 1,
|
|
429
|
+
limit: 10
|
|
430
|
+
}).subscribe({
|
|
431
|
+
next: (response) => {
|
|
432
|
+
response.templates.forEach(template => {
|
|
433
|
+
console.log(`${template.name}: ${template.subject}`);
|
|
434
|
+
});
|
|
435
|
+
},
|
|
436
|
+
error: (error) => console.error('Error:', error)
|
|
437
|
+
});
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
### Get Template
|
|
441
|
+
|
|
442
|
+
```typescript
|
|
443
|
+
this.metigan.templates.get('template-123').subscribe({
|
|
444
|
+
next: (template) => console.log('Template:', template),
|
|
445
|
+
error: (error) => console.error('Error:', error)
|
|
446
|
+
});
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
## ⚙️ Configuration
|
|
450
|
+
|
|
451
|
+
### Module Configuration
|
|
452
|
+
|
|
453
|
+
```typescript
|
|
454
|
+
MetiganModule.forRoot({
|
|
455
|
+
apiKey: 'your-api-key',
|
|
456
|
+
userId: 'user-123', // Optional: User ID for logging
|
|
457
|
+
timeout: 60000, // Optional: Request timeout in ms
|
|
458
|
+
retryCount: 5, // Optional: Number of retries
|
|
459
|
+
retryDelay: 2000, // Optional: Delay between retries in ms
|
|
460
|
+
apiUrl: 'https://api.metigan.com' // Optional: Custom API URL
|
|
461
|
+
})
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
### Manual Initialization
|
|
465
|
+
|
|
466
|
+
```typescript
|
|
467
|
+
this.metigan.initialize({
|
|
468
|
+
apiKey: 'your-api-key',
|
|
469
|
+
timeout: 60000,
|
|
470
|
+
retryCount: 5,
|
|
471
|
+
retryDelay: 2000,
|
|
472
|
+
apiUrl: 'https://api.metigan.com'
|
|
473
|
+
});
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
## 🛡️ Error Handling
|
|
477
|
+
|
|
478
|
+
All services return RxJS Observables, so use standard error handling:
|
|
479
|
+
|
|
480
|
+
```typescript
|
|
481
|
+
import { MetiganError, ValidationError, ApiError } from '@metigan/angular';
|
|
482
|
+
|
|
483
|
+
this.metigan.email.sendEmail(options).subscribe({
|
|
484
|
+
next: (response) => {
|
|
485
|
+
// Success
|
|
486
|
+
},
|
|
487
|
+
error: (error) => {
|
|
488
|
+
if (error instanceof ValidationError) {
|
|
489
|
+
console.error('Invalid data:', error.message);
|
|
490
|
+
} else if (error instanceof ApiError) {
|
|
491
|
+
console.error(`API error (${error.statusCode}):`, error.message);
|
|
492
|
+
} else if (error instanceof MetiganError) {
|
|
493
|
+
console.error('Metigan error:', error.message);
|
|
494
|
+
} else {
|
|
495
|
+
console.error('Unknown error:', error);
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
});
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
## 📝 Using Individual Services
|
|
502
|
+
|
|
503
|
+
If you only need a specific service:
|
|
504
|
+
|
|
505
|
+
```typescript
|
|
506
|
+
import { MetiganEmailService } from '@metigan/angular';
|
|
507
|
+
|
|
508
|
+
constructor(private emailService: MetiganEmailService) {}
|
|
509
|
+
|
|
510
|
+
ngOnInit() {
|
|
511
|
+
this.emailService.initialize('your-api-key');
|
|
512
|
+
|
|
513
|
+
this.emailService.sendEmail({
|
|
514
|
+
from: 'sender@example.com',
|
|
515
|
+
recipients: ['recipient@example.com'],
|
|
516
|
+
subject: 'Test',
|
|
517
|
+
content: '<p>Hello</p>'
|
|
518
|
+
}).subscribe({
|
|
519
|
+
next: (response) => console.log('Sent'),
|
|
520
|
+
error: (error) => console.error('Error:', error)
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
## 🔄 RxJS Observables
|
|
526
|
+
|
|
527
|
+
All service methods return RxJS Observables. Make sure to:
|
|
528
|
+
|
|
529
|
+
1. Subscribe to the observable
|
|
530
|
+
2. Handle both success and error cases
|
|
531
|
+
3. Unsubscribe if needed (or use `async` pipe in templates)
|
|
532
|
+
|
|
533
|
+
### Using Async Pipe
|
|
534
|
+
|
|
535
|
+
```typescript
|
|
536
|
+
// In component
|
|
537
|
+
templates$ = this.metigan.templates.list();
|
|
538
|
+
|
|
539
|
+
// In template
|
|
540
|
+
<div *ngIf="templates$ | async as templates">
|
|
541
|
+
<div *ngFor="let template of templates.templates">
|
|
542
|
+
{{ template.name }}
|
|
543
|
+
</div>
|
|
544
|
+
</div>
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
### Manual Subscription with Cleanup
|
|
548
|
+
|
|
549
|
+
```typescript
|
|
550
|
+
import { Component, OnDestroy } from '@angular/core';
|
|
551
|
+
import { Subscription } from 'rxjs';
|
|
552
|
+
|
|
553
|
+
export class MyComponent implements OnDestroy {
|
|
554
|
+
private subscription = new Subscription();
|
|
555
|
+
|
|
556
|
+
sendEmail() {
|
|
557
|
+
const sub = this.metigan.email.sendEmail(options).subscribe({
|
|
558
|
+
next: (response) => console.log('Sent'),
|
|
559
|
+
error: (error) => console.error('Error:', error)
|
|
560
|
+
});
|
|
561
|
+
|
|
562
|
+
this.subscription.add(sub);
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
ngOnDestroy() {
|
|
566
|
+
this.subscription.unsubscribe();
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
```
|
|
570
|
+
|
|
571
|
+
## 📄 License
|
|
572
|
+
|
|
573
|
+
MIT © Metigan
|
|
574
|
+
|
|
575
|
+
## 🔗 Links
|
|
576
|
+
|
|
577
|
+
- [Documentation](https://docs.metigan.com)
|
|
578
|
+
- [Dashboard](https://app.metigan.com)
|
|
579
|
+
- [API Reference](https://docs.metigan.com/api)
|
|
580
|
+
- [GitHub](https://github.com/frantchessico/metigan-angular)
|
|
581
|
+
|
package/dist/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Metigan
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|