@auxiora/channels 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.
Files changed (89) hide show
  1. package/LICENSE +191 -0
  2. package/dist/adapters/bluebubbles.d.ts +63 -0
  3. package/dist/adapters/bluebubbles.d.ts.map +1 -0
  4. package/dist/adapters/bluebubbles.js +197 -0
  5. package/dist/adapters/bluebubbles.js.map +1 -0
  6. package/dist/adapters/discord.d.ts +27 -0
  7. package/dist/adapters/discord.d.ts.map +1 -0
  8. package/dist/adapters/discord.js +202 -0
  9. package/dist/adapters/discord.js.map +1 -0
  10. package/dist/adapters/email.d.ts +39 -0
  11. package/dist/adapters/email.d.ts.map +1 -0
  12. package/dist/adapters/email.js +359 -0
  13. package/dist/adapters/email.js.map +1 -0
  14. package/dist/adapters/googlechat.d.ts +77 -0
  15. package/dist/adapters/googlechat.d.ts.map +1 -0
  16. package/dist/adapters/googlechat.js +232 -0
  17. package/dist/adapters/googlechat.js.map +1 -0
  18. package/dist/adapters/matrix.d.ts +37 -0
  19. package/dist/adapters/matrix.d.ts.map +1 -0
  20. package/dist/adapters/matrix.js +262 -0
  21. package/dist/adapters/matrix.js.map +1 -0
  22. package/dist/adapters/signal.d.ts +32 -0
  23. package/dist/adapters/signal.d.ts.map +1 -0
  24. package/dist/adapters/signal.js +216 -0
  25. package/dist/adapters/signal.js.map +1 -0
  26. package/dist/adapters/slack.d.ts +29 -0
  27. package/dist/adapters/slack.d.ts.map +1 -0
  28. package/dist/adapters/slack.js +202 -0
  29. package/dist/adapters/slack.js.map +1 -0
  30. package/dist/adapters/teams.d.ts +66 -0
  31. package/dist/adapters/teams.d.ts.map +1 -0
  32. package/dist/adapters/teams.js +227 -0
  33. package/dist/adapters/teams.js.map +1 -0
  34. package/dist/adapters/telegram.d.ts +28 -0
  35. package/dist/adapters/telegram.d.ts.map +1 -0
  36. package/dist/adapters/telegram.js +170 -0
  37. package/dist/adapters/telegram.js.map +1 -0
  38. package/dist/adapters/twilio.d.ts +63 -0
  39. package/dist/adapters/twilio.d.ts.map +1 -0
  40. package/dist/adapters/twilio.js +193 -0
  41. package/dist/adapters/twilio.js.map +1 -0
  42. package/dist/adapters/whatsapp.d.ts +99 -0
  43. package/dist/adapters/whatsapp.d.ts.map +1 -0
  44. package/dist/adapters/whatsapp.js +218 -0
  45. package/dist/adapters/whatsapp.js.map +1 -0
  46. package/dist/adapters/zalo.d.ts +64 -0
  47. package/dist/adapters/zalo.d.ts.map +1 -0
  48. package/dist/adapters/zalo.js +216 -0
  49. package/dist/adapters/zalo.js.map +1 -0
  50. package/dist/index.d.ts +15 -0
  51. package/dist/index.d.ts.map +1 -0
  52. package/dist/index.js +16 -0
  53. package/dist/index.js.map +1 -0
  54. package/dist/manager.d.ts +35 -0
  55. package/dist/manager.d.ts.map +1 -0
  56. package/dist/manager.js +127 -0
  57. package/dist/manager.js.map +1 -0
  58. package/dist/types.d.ts +71 -0
  59. package/dist/types.d.ts.map +1 -0
  60. package/dist/types.js +2 -0
  61. package/dist/types.js.map +1 -0
  62. package/package.json +32 -0
  63. package/src/adapters/bluebubbles.ts +294 -0
  64. package/src/adapters/discord.ts +253 -0
  65. package/src/adapters/email.ts +457 -0
  66. package/src/adapters/googlechat.ts +364 -0
  67. package/src/adapters/matrix.ts +376 -0
  68. package/src/adapters/signal.ts +313 -0
  69. package/src/adapters/slack.ts +252 -0
  70. package/src/adapters/teams.ts +320 -0
  71. package/src/adapters/telegram.ts +208 -0
  72. package/src/adapters/twilio.ts +256 -0
  73. package/src/adapters/whatsapp.ts +342 -0
  74. package/src/adapters/zalo.ts +319 -0
  75. package/src/index.ts +78 -0
  76. package/src/manager.ts +180 -0
  77. package/src/types.ts +84 -0
  78. package/tests/bluebubbles.test.ts +438 -0
  79. package/tests/email.test.ts +136 -0
  80. package/tests/googlechat.test.ts +439 -0
  81. package/tests/matrix.test.ts +564 -0
  82. package/tests/signal.test.ts +404 -0
  83. package/tests/slack.test.ts +343 -0
  84. package/tests/teams.test.ts +429 -0
  85. package/tests/twilio.test.ts +269 -0
  86. package/tests/whatsapp.test.ts +530 -0
  87. package/tests/zalo.test.ts +499 -0
  88. package/tsconfig.json +8 -0
  89. package/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1,202 @@
1
+ import { Client, GatewayIntentBits, Partials, } from 'discord.js';
2
+ import { audit } from '@auxiora/audit';
3
+ const MAX_MESSAGE_LENGTH = 2000;
4
+ export class DiscordAdapter {
5
+ type = 'discord';
6
+ name = 'Discord';
7
+ client;
8
+ config;
9
+ messageHandler;
10
+ errorHandler;
11
+ connected = false;
12
+ constructor(config) {
13
+ this.config = config;
14
+ this.client = new Client({
15
+ intents: [
16
+ GatewayIntentBits.Guilds,
17
+ GatewayIntentBits.GuildMessages,
18
+ GatewayIntentBits.DirectMessages,
19
+ GatewayIntentBits.MessageContent,
20
+ ],
21
+ partials: [Partials.Channel, Partials.Message],
22
+ });
23
+ this.setupEventHandlers();
24
+ }
25
+ setupEventHandlers() {
26
+ this.client.on('clientReady', () => {
27
+ audit('channel.connected', {
28
+ channelType: 'discord',
29
+ username: this.client.user?.tag,
30
+ });
31
+ this.connected = true;
32
+ });
33
+ this.client.on('messageCreate', async (message) => {
34
+ // Ignore bot messages
35
+ if (message.author.bot)
36
+ return;
37
+ // Check guild allowlist
38
+ if (message.guild &&
39
+ this.config.allowedGuilds?.length &&
40
+ !this.config.allowedGuilds.includes(message.guild.id)) {
41
+ return;
42
+ }
43
+ // Check mention requirement for guild messages
44
+ if (this.config.mentionOnly &&
45
+ message.guild &&
46
+ !message.mentions.has(this.client.user.id)) {
47
+ return;
48
+ }
49
+ // Convert to inbound message
50
+ const inbound = this.toInboundMessage(message);
51
+ audit('message.received', {
52
+ channelType: 'discord',
53
+ senderId: inbound.senderId,
54
+ channelId: inbound.channelId,
55
+ });
56
+ if (this.messageHandler) {
57
+ try {
58
+ await this.messageHandler(inbound);
59
+ }
60
+ catch (error) {
61
+ this.errorHandler?.(error instanceof Error ? error : new Error(String(error)));
62
+ }
63
+ }
64
+ });
65
+ this.client.on('error', (error) => {
66
+ audit('channel.error', { channelType: 'discord', error: error.message });
67
+ this.errorHandler?.(error);
68
+ });
69
+ this.client.on('disconnect', () => {
70
+ this.connected = false;
71
+ audit('channel.disconnected', { channelType: 'discord' });
72
+ });
73
+ }
74
+ toInboundMessage(message) {
75
+ // Strip bot mention from content
76
+ let content = message.content;
77
+ if (this.client.user) {
78
+ content = content.replace(new RegExp(`<@!?${this.client.user.id}>`, 'g'), '').trim();
79
+ }
80
+ return {
81
+ id: message.id,
82
+ channelType: 'discord',
83
+ channelId: message.channel.id,
84
+ senderId: message.author.id,
85
+ senderName: message.author.displayName || message.author.username,
86
+ content,
87
+ timestamp: message.createdTimestamp,
88
+ replyToId: message.reference?.messageId,
89
+ attachments: message.attachments.map((a) => ({
90
+ type: a.contentType?.startsWith('image/')
91
+ ? 'image'
92
+ : a.contentType?.startsWith('audio/')
93
+ ? 'audio'
94
+ : a.contentType?.startsWith('video/')
95
+ ? 'video'
96
+ : 'file',
97
+ url: a.url,
98
+ mimeType: a.contentType || undefined,
99
+ filename: a.name,
100
+ size: a.size,
101
+ })),
102
+ raw: message,
103
+ };
104
+ }
105
+ async connect() {
106
+ await this.client.login(this.config.token);
107
+ }
108
+ async disconnect() {
109
+ this.client.destroy();
110
+ this.connected = false;
111
+ }
112
+ isConnected() {
113
+ return this.connected;
114
+ }
115
+ async send(channelId, message) {
116
+ try {
117
+ const channel = await this.client.channels.fetch(channelId);
118
+ if (!channel || !channel.isTextBased() || !('send' in channel)) {
119
+ return { success: false, error: 'Channel not found or not text-based' };
120
+ }
121
+ // Chunk long messages
122
+ const chunks = this.chunkMessage(message.content);
123
+ let lastMessageId;
124
+ for (const chunk of chunks) {
125
+ const sent = await channel.send({
126
+ content: chunk,
127
+ reply: message.replyToId
128
+ ? { messageReference: message.replyToId }
129
+ : undefined,
130
+ });
131
+ lastMessageId = sent.id;
132
+ }
133
+ audit('message.sent', {
134
+ channelType: 'discord',
135
+ channelId,
136
+ messageId: lastMessageId,
137
+ });
138
+ return { success: true, messageId: lastMessageId };
139
+ }
140
+ catch (error) {
141
+ const errorMessage = error instanceof Error ? error.message : String(error);
142
+ audit('channel.error', {
143
+ channelType: 'discord',
144
+ action: 'send',
145
+ error: errorMessage,
146
+ });
147
+ return { success: false, error: errorMessage };
148
+ }
149
+ }
150
+ chunkMessage(content) {
151
+ if (content.length <= MAX_MESSAGE_LENGTH) {
152
+ return [content];
153
+ }
154
+ const chunks = [];
155
+ let remaining = content;
156
+ while (remaining.length > 0) {
157
+ if (remaining.length <= MAX_MESSAGE_LENGTH) {
158
+ chunks.push(remaining);
159
+ break;
160
+ }
161
+ // Find a good break point
162
+ let breakPoint = remaining.lastIndexOf('\n', MAX_MESSAGE_LENGTH);
163
+ if (breakPoint === -1 || breakPoint < MAX_MESSAGE_LENGTH / 2) {
164
+ breakPoint = remaining.lastIndexOf(' ', MAX_MESSAGE_LENGTH);
165
+ }
166
+ if (breakPoint === -1 || breakPoint < MAX_MESSAGE_LENGTH / 2) {
167
+ breakPoint = MAX_MESSAGE_LENGTH;
168
+ }
169
+ chunks.push(remaining.slice(0, breakPoint));
170
+ remaining = remaining.slice(breakPoint).trimStart();
171
+ }
172
+ return chunks;
173
+ }
174
+ async startTyping(channelId) {
175
+ // Use cache (populated by messageCreate) to avoid extra API call
176
+ const channel = this.client.channels.cache.get(channelId);
177
+ if (!channel || !channel.isTextBased() || !('sendTyping' in channel)) {
178
+ return () => { };
179
+ }
180
+ // Send immediately, then repeat every 8s (Discord typing expires after ~10s)
181
+ let stopped = false;
182
+ channel.sendTyping().catch((e) => {
183
+ audit('channel.error', { channelType: 'discord', action: 'typing', error: e.message });
184
+ });
185
+ const interval = setInterval(() => {
186
+ if (stopped)
187
+ return;
188
+ channel.sendTyping().catch(() => { });
189
+ }, 8000);
190
+ return () => {
191
+ stopped = true;
192
+ clearInterval(interval);
193
+ };
194
+ }
195
+ onMessage(handler) {
196
+ this.messageHandler = handler;
197
+ }
198
+ onError(handler) {
199
+ this.errorHandler = handler;
200
+ }
201
+ }
202
+ //# sourceMappingURL=discord.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discord.js","sourceRoot":"","sources":["../../src/adapters/discord.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import type { ChannelAdapter, InboundMessage, OutboundMessage, SendResult } from '../types.js';
2
+ export interface EmailAdapterConfig {
3
+ imapHost: string;
4
+ imapPort: number;
5
+ smtpHost: string;
6
+ smtpPort: number;
7
+ email: string;
8
+ password: string;
9
+ pollInterval?: number;
10
+ allowedSenders?: string[];
11
+ tls?: boolean;
12
+ }
13
+ export declare class EmailAdapter implements ChannelAdapter {
14
+ readonly type: "email";
15
+ readonly name = "Email";
16
+ private config;
17
+ private messageHandler?;
18
+ private errorHandler?;
19
+ private connected;
20
+ private pollTimer?;
21
+ private seenUids;
22
+ private imapConnection?;
23
+ private smtpConnection?;
24
+ constructor(config: EmailAdapterConfig);
25
+ connect(): Promise<void>;
26
+ disconnect(): Promise<void>;
27
+ isConnected(): boolean;
28
+ private connectImap;
29
+ private connectSmtp;
30
+ private startPolling;
31
+ private pollInbox;
32
+ private fetchNewMessages;
33
+ private parseImapMessage;
34
+ private toInboundMessage;
35
+ send(channelId: string, message: OutboundMessage): Promise<SendResult>;
36
+ onMessage(handler: (message: InboundMessage) => Promise<void>): void;
37
+ onError(handler: (error: Error) => void): void;
38
+ }
39
+ //# sourceMappingURL=email.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email.d.ts","sourceRoot":"","sources":["../../src/adapters/email.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EACd,eAAe,EACf,UAAU,EACX,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAuBD,qBAAa,YAAa,YAAW,cAAc;IACjD,QAAQ,CAAC,IAAI,EAAG,OAAO,CAAU;IACjC,QAAQ,CAAC,IAAI,WAAW;IAExB,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,cAAc,CAAC,CAA6C;IACpE,OAAO,CAAC,YAAY,CAAC,CAAyB;IAC9C,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAC,CAAiC;IACnD,OAAO,CAAC,QAAQ,CAA0B;IAC1C,OAAO,CAAC,cAAc,CAAC,CAAqB;IAC5C,OAAO,CAAC,cAAc,CAAC,CAAqB;gBAEhC,MAAM,EAAE,kBAAkB;IAIhC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAsBxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAwBjC,WAAW,IAAI,OAAO;YAIR,WAAW;YA4DX,WAAW;IA2DzB,OAAO,CAAC,YAAY;YAUN,SAAS;YA0CT,gBAAgB;IAkC9B,OAAO,CAAC,gBAAgB;IAyCxB,OAAO,CAAC,gBAAgB;IA0BlB,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC;IAyD5E,SAAS,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAIpE,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI;CAG/C"}
@@ -0,0 +1,359 @@
1
+ import { audit } from '@auxiora/audit';
2
+ const DEFAULT_POLL_INTERVAL = 30000; // 30 seconds
3
+ export class EmailAdapter {
4
+ type = 'email';
5
+ name = 'Email';
6
+ config;
7
+ messageHandler;
8
+ errorHandler;
9
+ connected = false;
10
+ pollTimer;
11
+ seenUids = new Set();
12
+ imapConnection;
13
+ smtpConnection;
14
+ constructor(config) {
15
+ this.config = config;
16
+ }
17
+ async connect() {
18
+ try {
19
+ // Connect IMAP
20
+ this.imapConnection = await this.connectImap();
21
+ // Connect SMTP
22
+ this.smtpConnection = await this.connectSmtp();
23
+ this.connected = true;
24
+ audit('channel.connected', {
25
+ channelType: 'email',
26
+ email: this.config.email,
27
+ });
28
+ // Start polling for new messages
29
+ this.startPolling();
30
+ }
31
+ catch (error) {
32
+ throw new Error(`Failed to connect email: ${error instanceof Error ? error.message : error}`);
33
+ }
34
+ }
35
+ async disconnect() {
36
+ if (this.pollTimer) {
37
+ clearInterval(this.pollTimer);
38
+ this.pollTimer = undefined;
39
+ }
40
+ try {
41
+ await this.imapConnection?.close();
42
+ }
43
+ catch {
44
+ // Ignore close errors
45
+ }
46
+ try {
47
+ await this.smtpConnection?.close();
48
+ }
49
+ catch {
50
+ // Ignore close errors
51
+ }
52
+ this.imapConnection = undefined;
53
+ this.smtpConnection = undefined;
54
+ this.connected = false;
55
+ audit('channel.disconnected', { channelType: 'email' });
56
+ }
57
+ isConnected() {
58
+ return this.connected;
59
+ }
60
+ async connectImap() {
61
+ // Use native TCP connection via Node.js net/tls modules
62
+ const net = await import('node:net');
63
+ const tls = await import('node:tls');
64
+ const useTls = this.config.tls !== false;
65
+ const socket = useTls
66
+ ? tls.connect({
67
+ host: this.config.imapHost,
68
+ port: this.config.imapPort,
69
+ rejectUnauthorized: true,
70
+ })
71
+ : net.connect({
72
+ host: this.config.imapHost,
73
+ port: this.config.imapPort,
74
+ });
75
+ return new Promise((resolve, reject) => {
76
+ const timeout = setTimeout(() => {
77
+ socket.destroy();
78
+ reject(new Error('IMAP connection timeout'));
79
+ }, 10000);
80
+ socket.once('error', (err) => {
81
+ clearTimeout(timeout);
82
+ reject(err);
83
+ });
84
+ const onReady = () => {
85
+ clearTimeout(timeout);
86
+ resolve({
87
+ socket,
88
+ close: async () => { socket.destroy(); },
89
+ sendCommand: async (cmd) => {
90
+ return new Promise((res, rej) => {
91
+ let data = '';
92
+ const onData = (chunk) => {
93
+ data += chunk.toString();
94
+ if (data.includes('\r\n')) {
95
+ socket.removeListener('data', onData);
96
+ res(data);
97
+ }
98
+ };
99
+ socket.on('data', onData);
100
+ socket.write(`${cmd}\r\n`, (err) => {
101
+ if (err)
102
+ rej(err);
103
+ });
104
+ });
105
+ },
106
+ });
107
+ };
108
+ if (useTls) {
109
+ socket.once('secureConnect', onReady);
110
+ }
111
+ else {
112
+ socket.once('connect', onReady);
113
+ }
114
+ });
115
+ }
116
+ async connectSmtp() {
117
+ const net = await import('node:net');
118
+ const tls = await import('node:tls');
119
+ const useTls = this.config.tls !== false;
120
+ const socket = useTls
121
+ ? tls.connect({
122
+ host: this.config.smtpHost,
123
+ port: this.config.smtpPort,
124
+ rejectUnauthorized: true,
125
+ })
126
+ : net.connect({
127
+ host: this.config.smtpHost,
128
+ port: this.config.smtpPort,
129
+ });
130
+ return new Promise((resolve, reject) => {
131
+ const timeout = setTimeout(() => {
132
+ socket.destroy();
133
+ reject(new Error('SMTP connection timeout'));
134
+ }, 10000);
135
+ socket.once('error', (err) => {
136
+ clearTimeout(timeout);
137
+ reject(err);
138
+ });
139
+ const onReady = () => {
140
+ clearTimeout(timeout);
141
+ resolve({
142
+ socket,
143
+ close: async () => { socket.destroy(); },
144
+ sendCommand: async (cmd) => {
145
+ return new Promise((res, rej) => {
146
+ let data = '';
147
+ const onData = (chunk) => {
148
+ data += chunk.toString();
149
+ if (data.includes('\r\n')) {
150
+ socket.removeListener('data', onData);
151
+ res(data);
152
+ }
153
+ };
154
+ socket.on('data', onData);
155
+ socket.write(`${cmd}\r\n`, (err) => {
156
+ if (err)
157
+ rej(err);
158
+ });
159
+ });
160
+ },
161
+ });
162
+ };
163
+ if (useTls) {
164
+ socket.once('secureConnect', onReady);
165
+ }
166
+ else {
167
+ socket.once('connect', onReady);
168
+ }
169
+ });
170
+ }
171
+ startPolling() {
172
+ const interval = this.config.pollInterval || DEFAULT_POLL_INTERVAL;
173
+ this.pollTimer = setInterval(() => {
174
+ void this.pollInbox();
175
+ }, interval);
176
+ // Initial poll
177
+ void this.pollInbox();
178
+ }
179
+ async pollInbox() {
180
+ if (!this.connected || !this.imapConnection)
181
+ return;
182
+ try {
183
+ // Fetch messages using IMAP commands
184
+ const messages = await this.fetchNewMessages();
185
+ for (const msg of messages) {
186
+ if (this.seenUids.has(msg.uid))
187
+ continue;
188
+ this.seenUids.add(msg.uid);
189
+ // Check allowed senders whitelist
190
+ if (this.config.allowedSenders?.length &&
191
+ !this.config.allowedSenders.some((s) => msg.from.toLowerCase().includes(s.toLowerCase()))) {
192
+ continue;
193
+ }
194
+ const inbound = this.toInboundMessage(msg);
195
+ audit('message.received', {
196
+ channelType: 'email',
197
+ senderId: inbound.senderId,
198
+ channelId: inbound.channelId,
199
+ });
200
+ if (this.messageHandler) {
201
+ try {
202
+ await this.messageHandler(inbound);
203
+ }
204
+ catch (error) {
205
+ this.errorHandler?.(error instanceof Error ? error : new Error(String(error)));
206
+ }
207
+ }
208
+ }
209
+ }
210
+ catch (error) {
211
+ this.errorHandler?.(error instanceof Error ? error : new Error(String(error)));
212
+ }
213
+ }
214
+ async fetchNewMessages() {
215
+ // Simplified IMAP fetch - in production you'd use a full IMAP client
216
+ // This sends raw IMAP commands over the socket connection
217
+ try {
218
+ await this.imapConnection.sendCommand(`A001 LOGIN "${this.config.email}" "${this.config.password}"`);
219
+ await this.imapConnection.sendCommand('A002 SELECT INBOX');
220
+ const searchResult = await this.imapConnection.sendCommand('A003 SEARCH UNSEEN');
221
+ // Parse UIDs from search result
222
+ const match = searchResult.match(/\* SEARCH (.+)/);
223
+ if (!match)
224
+ return [];
225
+ const uids = match[1].trim().split(/\s+/).filter(Boolean);
226
+ const messages = [];
227
+ for (const uid of uids) {
228
+ try {
229
+ const fetchResult = await this.imapConnection.sendCommand(`A004 FETCH ${uid} (BODY[HEADER] BODY[TEXT])`);
230
+ const msg = this.parseImapMessage(uid, fetchResult);
231
+ if (msg)
232
+ messages.push(msg);
233
+ }
234
+ catch {
235
+ // Skip individual message errors
236
+ }
237
+ }
238
+ return messages;
239
+ }
240
+ catch {
241
+ return [];
242
+ }
243
+ }
244
+ parseImapMessage(uid, raw) {
245
+ // Parse headers and body from IMAP FETCH response
246
+ const fromMatch = raw.match(/From:\s*(.+)/i);
247
+ const toMatch = raw.match(/To:\s*(.+)/i);
248
+ const subjectMatch = raw.match(/Subject:\s*(.+)/i);
249
+ const dateMatch = raw.match(/Date:\s*(.+)/i);
250
+ const messageIdMatch = raw.match(/Message-ID:\s*<(.+?)>/i);
251
+ const inReplyToMatch = raw.match(/In-Reply-To:\s*<(.+?)>/i);
252
+ const referencesMatch = raw.match(/References:\s*(.+)/i);
253
+ if (!fromMatch)
254
+ return null;
255
+ // Extract the body (text after headers)
256
+ const headerBodySplit = raw.indexOf('\r\n\r\n');
257
+ const body = headerBodySplit > -1 ? raw.slice(headerBodySplit + 4).trim() : '';
258
+ // Parse from name and address
259
+ const fromFull = fromMatch[1].trim();
260
+ const fromNameMatch = fromFull.match(/^"?(.+?)"?\s*<(.+?)>$/);
261
+ const from = fromNameMatch ? fromNameMatch[2] : fromFull;
262
+ const fromName = fromNameMatch ? fromNameMatch[1] : undefined;
263
+ // Parse references
264
+ const references = referencesMatch
265
+ ? referencesMatch[1].match(/<(.+?)>/g)?.map((r) => r.slice(1, -1))
266
+ : undefined;
267
+ return {
268
+ uid,
269
+ from,
270
+ fromName,
271
+ to: toMatch?.[1].trim() || '',
272
+ subject: subjectMatch?.[1].trim() || '(no subject)',
273
+ body,
274
+ date: dateMatch ? new Date(dateMatch[1].trim()) : new Date(),
275
+ messageId: messageIdMatch?.[1] || `${uid}@unknown`,
276
+ inReplyTo: inReplyToMatch?.[1],
277
+ references,
278
+ };
279
+ }
280
+ toInboundMessage(msg) {
281
+ // Use the email thread (via In-Reply-To/References) as the channel
282
+ const threadId = msg.references?.[0] || msg.inReplyTo || msg.messageId;
283
+ return {
284
+ id: msg.messageId,
285
+ channelType: 'email',
286
+ channelId: threadId,
287
+ senderId: msg.from,
288
+ senderName: msg.fromName,
289
+ content: `Subject: ${msg.subject}\n\n${msg.body}`,
290
+ timestamp: msg.date.getTime(),
291
+ replyToId: msg.inReplyTo,
292
+ attachments: msg.attachments?.map((a) => ({
293
+ type: a.contentType.startsWith('image/')
294
+ ? 'image'
295
+ : 'file',
296
+ mimeType: a.contentType,
297
+ filename: a.filename,
298
+ size: a.size,
299
+ data: a.content,
300
+ })),
301
+ raw: msg,
302
+ };
303
+ }
304
+ async send(channelId, message) {
305
+ try {
306
+ if (!this.smtpConnection) {
307
+ return { success: false, error: 'SMTP not connected' };
308
+ }
309
+ // Parse the recipient from the channelId (thread message-id) or replyToId
310
+ // In email adapter, channelId is the thread message-id
311
+ // The actual recipient is derived from the original sender
312
+ const messageId = `<${Date.now()}.${Math.random().toString(36).slice(2)}@auxiora>`;
313
+ // Build email
314
+ const headers = [
315
+ `From: ${this.config.email}`,
316
+ `To: ${channelId}`,
317
+ `Subject: Re: Auxiora`,
318
+ `Message-ID: ${messageId}`,
319
+ `Date: ${new Date().toUTCString()}`,
320
+ 'MIME-Version: 1.0',
321
+ 'Content-Type: text/plain; charset=utf-8',
322
+ ];
323
+ if (message.replyToId) {
324
+ headers.push(`In-Reply-To: <${message.replyToId}>`);
325
+ headers.push(`References: <${message.replyToId}>`);
326
+ }
327
+ const emailContent = headers.join('\r\n') + '\r\n\r\n' + message.content;
328
+ // Send via SMTP
329
+ await this.smtpConnection.sendCommand(`EHLO auxiora`);
330
+ await this.smtpConnection.sendCommand(`AUTH PLAIN ${Buffer.from(`\0${this.config.email}\0${this.config.password}`).toString('base64')}`);
331
+ await this.smtpConnection.sendCommand(`MAIL FROM:<${this.config.email}>`);
332
+ await this.smtpConnection.sendCommand(`RCPT TO:<${channelId}>`);
333
+ await this.smtpConnection.sendCommand('DATA');
334
+ await this.smtpConnection.sendCommand(`${emailContent}\r\n.`);
335
+ audit('message.sent', {
336
+ channelType: 'email',
337
+ channelId,
338
+ messageId,
339
+ });
340
+ return { success: true, messageId };
341
+ }
342
+ catch (error) {
343
+ const errorMessage = error instanceof Error ? error.message : String(error);
344
+ audit('channel.error', {
345
+ channelType: 'email',
346
+ action: 'send',
347
+ error: errorMessage,
348
+ });
349
+ return { success: false, error: errorMessage };
350
+ }
351
+ }
352
+ onMessage(handler) {
353
+ this.messageHandler = handler;
354
+ }
355
+ onError(handler) {
356
+ this.errorHandler = handler;
357
+ }
358
+ }
359
+ //# sourceMappingURL=email.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email.js","sourceRoot":"","sources":["../../src/adapters/email.ts"],"names":[],"mappings":"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"}