@ai-devkit/channel-connector 0.2.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/dist/ChannelManager.d.ts +26 -0
- package/dist/ChannelManager.d.ts.map +1 -0
- package/dist/ChannelManager.js +44 -0
- package/dist/ChannelManager.js.map +1 -0
- package/dist/ConfigStore.d.ts +28 -0
- package/dist/ConfigStore.d.ts.map +1 -0
- package/dist/ConfigStore.js +93 -0
- package/dist/ConfigStore.js.map +1 -0
- package/dist/adapters/ChannelAdapter.d.ts +30 -0
- package/dist/adapters/ChannelAdapter.d.ts.map +1 -0
- package/dist/adapters/ChannelAdapter.js +3 -0
- package/dist/adapters/ChannelAdapter.js.map +1 -0
- package/dist/adapters/TelegramAdapter.d.ts +27 -0
- package/dist/adapters/TelegramAdapter.d.ts.map +1 -0
- package/dist/adapters/TelegramAdapter.js +92 -0
- package/dist/adapters/TelegramAdapter.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +45 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ChannelAdapter } from './adapters/ChannelAdapter';
|
|
2
|
+
/**
|
|
3
|
+
* Central registry for channel adapters.
|
|
4
|
+
* Manages adapter lifecycle (start/stop).
|
|
5
|
+
*/
|
|
6
|
+
export declare class ChannelManager {
|
|
7
|
+
private adapters;
|
|
8
|
+
/**
|
|
9
|
+
* Register a channel adapter.
|
|
10
|
+
* @throws If an adapter for the same type is already registered.
|
|
11
|
+
*/
|
|
12
|
+
registerAdapter(adapter: ChannelAdapter): void;
|
|
13
|
+
/**
|
|
14
|
+
* Get a registered adapter by type.
|
|
15
|
+
*/
|
|
16
|
+
getAdapter(type: string): ChannelAdapter | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* Start all registered adapters.
|
|
19
|
+
*/
|
|
20
|
+
startAll(): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Stop all registered adapters.
|
|
23
|
+
*/
|
|
24
|
+
stopAll(): Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=ChannelManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChannelManager.d.ts","sourceRoot":"","sources":["../src/ChannelManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAEhE;;;GAGG;AACH,qBAAa,cAAc;IACvB,OAAO,CAAC,QAAQ,CAA0C;IAE1D;;;OAGG;IACH,eAAe,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAO9C;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAIpD;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAK/B;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAIjC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ChannelManager = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Central registry for channel adapters.
|
|
6
|
+
* Manages adapter lifecycle (start/stop).
|
|
7
|
+
*/
|
|
8
|
+
class ChannelManager {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.adapters = new Map();
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Register a channel adapter.
|
|
14
|
+
* @throws If an adapter for the same type is already registered.
|
|
15
|
+
*/
|
|
16
|
+
registerAdapter(adapter) {
|
|
17
|
+
if (this.adapters.has(adapter.type)) {
|
|
18
|
+
throw new Error(`Adapter for type "${adapter.type}" is already registered`);
|
|
19
|
+
}
|
|
20
|
+
this.adapters.set(adapter.type, adapter);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Get a registered adapter by type.
|
|
24
|
+
*/
|
|
25
|
+
getAdapter(type) {
|
|
26
|
+
return this.adapters.get(type);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Start all registered adapters.
|
|
30
|
+
*/
|
|
31
|
+
async startAll() {
|
|
32
|
+
const startPromises = Array.from(this.adapters.values()).map(a => a.start());
|
|
33
|
+
await Promise.all(startPromises);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Stop all registered adapters.
|
|
37
|
+
*/
|
|
38
|
+
async stopAll() {
|
|
39
|
+
const stopPromises = Array.from(this.adapters.values()).map(a => a.stop());
|
|
40
|
+
await Promise.all(stopPromises);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
exports.ChannelManager = ChannelManager;
|
|
44
|
+
//# sourceMappingURL=ChannelManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChannelManager.js","sourceRoot":"","sources":["../src/ChannelManager.ts"],"names":[],"mappings":";;;AAEA;;;GAGG;AACH,MAAa,cAAc;IAA3B;QACY,aAAQ,GAAgC,IAAI,GAAG,EAAE,CAAC;IAmC9D,CAAC;IAjCG;;;OAGG;IACH,eAAe,CAAC,OAAuB;QACnC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CAAC,qBAAqB,OAAO,CAAC,IAAI,yBAAyB,CAAC,CAAC;QAChF,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC7C,CAAC;IAED;;OAEG;IACH,UAAU,CAAC,IAAY;QACnB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ;QACV,MAAM,aAAa,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;QAC7E,MAAM,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IACrC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO;QACT,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAC3E,MAAM,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IACpC,CAAC;CACJ;AApCD,wCAoCC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { ChannelConfig, ChannelEntry } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Persists channel configurations to disk.
|
|
4
|
+
* Default location: ~/.ai-devkit/channels.json
|
|
5
|
+
* File permissions are set to 0600 to protect tokens.
|
|
6
|
+
*/
|
|
7
|
+
export declare class ConfigStore {
|
|
8
|
+
private configPath;
|
|
9
|
+
constructor(configPath?: string);
|
|
10
|
+
/**
|
|
11
|
+
* Read the full config. Returns default empty config if file is missing or corrupt.
|
|
12
|
+
*/
|
|
13
|
+
getConfig(): Promise<ChannelConfig>;
|
|
14
|
+
/**
|
|
15
|
+
* Save a channel entry. Creates the file and parent directory if needed.
|
|
16
|
+
*/
|
|
17
|
+
saveChannel(name: string, entry: ChannelEntry): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Remove a channel entry by name.
|
|
20
|
+
*/
|
|
21
|
+
removeChannel(name: string): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Get a single channel entry by name.
|
|
24
|
+
*/
|
|
25
|
+
getChannel(name: string): Promise<ChannelEntry | undefined>;
|
|
26
|
+
private writeConfig;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=ConfigStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConfigStore.d.ts","sourceRoot":"","sources":["../src/ConfigStore.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAK3D;;;;GAIG;AACH,qBAAa,WAAW;IACpB,OAAO,CAAC,UAAU,CAAS;gBAEf,UAAU,CAAC,EAAE,MAAM;IAI/B;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,aAAa,CAAC;IASzC;;OAEG;IACG,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAMnE;;OAEG;IACG,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMhD;;OAEG;IACG,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;YAKnD,WAAW;CAK5B"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.ConfigStore = void 0;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const os = __importStar(require("os"));
|
|
40
|
+
const DEFAULT_CONFIG_PATH = path.join(os.homedir(), '.ai-devkit', 'channels.json');
|
|
41
|
+
const DEFAULT_CONFIG = { channels: {} };
|
|
42
|
+
/**
|
|
43
|
+
* Persists channel configurations to disk.
|
|
44
|
+
* Default location: ~/.ai-devkit/channels.json
|
|
45
|
+
* File permissions are set to 0600 to protect tokens.
|
|
46
|
+
*/
|
|
47
|
+
class ConfigStore {
|
|
48
|
+
constructor(configPath) {
|
|
49
|
+
this.configPath = configPath ?? DEFAULT_CONFIG_PATH;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Read the full config. Returns default empty config if file is missing or corrupt.
|
|
53
|
+
*/
|
|
54
|
+
async getConfig() {
|
|
55
|
+
try {
|
|
56
|
+
const raw = fs.readFileSync(this.configPath, 'utf-8');
|
|
57
|
+
return JSON.parse(raw);
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return { ...DEFAULT_CONFIG, channels: {} };
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Save a channel entry. Creates the file and parent directory if needed.
|
|
65
|
+
*/
|
|
66
|
+
async saveChannel(name, entry) {
|
|
67
|
+
const config = await this.getConfig();
|
|
68
|
+
config.channels[name] = entry;
|
|
69
|
+
await this.writeConfig(config);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Remove a channel entry by name.
|
|
73
|
+
*/
|
|
74
|
+
async removeChannel(name) {
|
|
75
|
+
const config = await this.getConfig();
|
|
76
|
+
delete config.channels[name];
|
|
77
|
+
await this.writeConfig(config);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Get a single channel entry by name.
|
|
81
|
+
*/
|
|
82
|
+
async getChannel(name) {
|
|
83
|
+
const config = await this.getConfig();
|
|
84
|
+
return config.channels[name];
|
|
85
|
+
}
|
|
86
|
+
async writeConfig(config) {
|
|
87
|
+
const dir = path.dirname(this.configPath);
|
|
88
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
89
|
+
fs.writeFileSync(this.configPath, JSON.stringify(config, null, 2), { mode: 0o600 });
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
exports.ConfigStore = ConfigStore;
|
|
93
|
+
//# sourceMappingURL=ConfigStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConfigStore.js","sourceRoot":"","sources":["../src/ConfigStore.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAyB;AACzB,2CAA6B;AAC7B,uCAAyB;AAGzB,MAAM,mBAAmB,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,YAAY,EAAE,eAAe,CAAC,CAAC;AACnF,MAAM,cAAc,GAAkB,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;AAEvD;;;;GAIG;AACH,MAAa,WAAW;IAGpB,YAAY,UAAmB;QAC3B,IAAI,CAAC,UAAU,GAAG,UAAU,IAAI,mBAAmB,CAAC;IACxD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,SAAS;QACX,IAAI,CAAC;YACD,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;YACtD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAkB,CAAC;QAC5C,CAAC;QAAC,MAAM,CAAC;YACL,OAAO,EAAE,GAAG,cAAc,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;QAC/C,CAAC;IACL,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW,CAAC,IAAY,EAAE,KAAmB;QAC/C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QACtC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;QAC9B,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa,CAAC,IAAY;QAC5B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QACtC,OAAO,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC7B,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU,CAAC,IAAY;QACzB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QACtC,OAAO,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAEO,KAAK,CAAC,WAAW,CAAC,MAAqB;QAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC1C,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACvC,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACxF,CAAC;CACJ;AAlDD,kCAkDC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { IncomingMessage } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Interface for messaging platform adapters.
|
|
4
|
+
*
|
|
5
|
+
* Implementations connect to a specific platform (Telegram, Slack, etc.)
|
|
6
|
+
* and provide a generic send/receive abstraction.
|
|
7
|
+
*/
|
|
8
|
+
export interface ChannelAdapter {
|
|
9
|
+
/** Identifier for this channel type (e.g., 'telegram') */
|
|
10
|
+
readonly type: string;
|
|
11
|
+
/** Start listening for incoming messages */
|
|
12
|
+
start(): Promise<void>;
|
|
13
|
+
/** Stop listening and clean up resources */
|
|
14
|
+
stop(): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* Send a message to a specific chat.
|
|
17
|
+
* Implementations should handle platform-specific limits
|
|
18
|
+
* (e.g., chunking at 4096 chars for Telegram).
|
|
19
|
+
*/
|
|
20
|
+
sendMessage(chatId: string, text: string): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Register a handler for incoming text messages.
|
|
23
|
+
* Fire-and-forget — handler returns void.
|
|
24
|
+
* Responses are sent separately via sendMessage().
|
|
25
|
+
*/
|
|
26
|
+
onMessage(handler: (msg: IncomingMessage) => Promise<void>): void;
|
|
27
|
+
/** Check if the adapter is connected and healthy */
|
|
28
|
+
isHealthy(): Promise<boolean>;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=ChannelAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChannelAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/ChannelAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAEhD;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC3B,0DAA0D;IAC1D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,4CAA4C;IAC5C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB,4CAA4C;IAC5C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtB;;;;OAIG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzD;;;;OAIG;IACH,SAAS,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAElE,oDAAoD;IACpD,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CACjC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChannelAdapter.js","sourceRoot":"","sources":["../../src/adapters/ChannelAdapter.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ChannelAdapter } from './ChannelAdapter';
|
|
2
|
+
import type { IncomingMessage } from '../types';
|
|
3
|
+
export declare const TELEGRAM_CHANNEL_TYPE = "telegram";
|
|
4
|
+
export declare const TELEGRAM_MAX_MESSAGE_LENGTH = 4096;
|
|
5
|
+
export interface TelegramAdapterOptions {
|
|
6
|
+
botToken: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Telegram Bot API adapter using telegraf with long polling.
|
|
10
|
+
*/
|
|
11
|
+
export declare class TelegramAdapter implements ChannelAdapter {
|
|
12
|
+
readonly type = "telegram";
|
|
13
|
+
private bot;
|
|
14
|
+
private messageHandler;
|
|
15
|
+
private running;
|
|
16
|
+
constructor(options: TelegramAdapterOptions);
|
|
17
|
+
start(): Promise<void>;
|
|
18
|
+
stop(): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Send a message to a chat. Automatically chunks messages exceeding
|
|
21
|
+
* Telegram's 4096-char limit, preferring newline boundaries.
|
|
22
|
+
*/
|
|
23
|
+
sendMessage(chatId: string, text: string): Promise<void>;
|
|
24
|
+
onMessage(handler: (msg: IncomingMessage) => Promise<void>): void;
|
|
25
|
+
isHealthy(): Promise<boolean>;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=TelegramAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TelegramAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/TelegramAdapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAEhD,eAAO,MAAM,qBAAqB,aAAa,CAAC;AAChD,eAAO,MAAM,2BAA2B,OAAO,CAAC;AAEhD,MAAM,WAAW,sBAAsB;IACnC,QAAQ,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,qBAAa,eAAgB,YAAW,cAAc;IAClD,QAAQ,CAAC,IAAI,cAAyB;IAEtC,OAAO,CAAC,GAAG,CAAW;IACtB,OAAO,CAAC,cAAc,CAA0D;IAChF,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,EAAE,sBAAsB;IAIrC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAwBtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAK3B;;;OAGG;IACG,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAO9D,SAAS,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAI3D,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;CAGtC"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TelegramAdapter = exports.TELEGRAM_MAX_MESSAGE_LENGTH = exports.TELEGRAM_CHANNEL_TYPE = void 0;
|
|
4
|
+
const telegraf_1 = require("telegraf");
|
|
5
|
+
exports.TELEGRAM_CHANNEL_TYPE = 'telegram';
|
|
6
|
+
exports.TELEGRAM_MAX_MESSAGE_LENGTH = 4096;
|
|
7
|
+
/**
|
|
8
|
+
* Telegram Bot API adapter using telegraf with long polling.
|
|
9
|
+
*/
|
|
10
|
+
class TelegramAdapter {
|
|
11
|
+
constructor(options) {
|
|
12
|
+
this.type = exports.TELEGRAM_CHANNEL_TYPE;
|
|
13
|
+
this.messageHandler = null;
|
|
14
|
+
this.running = false;
|
|
15
|
+
this.bot = new telegraf_1.Telegraf(options.botToken);
|
|
16
|
+
}
|
|
17
|
+
async start() {
|
|
18
|
+
this.bot.on('text', async (ctx) => {
|
|
19
|
+
if (!this.messageHandler)
|
|
20
|
+
return;
|
|
21
|
+
const msg = {
|
|
22
|
+
channelType: exports.TELEGRAM_CHANNEL_TYPE,
|
|
23
|
+
chatId: String(ctx.message.chat.id),
|
|
24
|
+
userId: String(ctx.message.from.id),
|
|
25
|
+
text: ctx.message.text,
|
|
26
|
+
timestamp: new Date(ctx.message.date * 1000),
|
|
27
|
+
};
|
|
28
|
+
try {
|
|
29
|
+
await this.messageHandler(msg);
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
33
|
+
await ctx.reply(`Error processing message: ${errorMessage}`);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
await this.bot.launch();
|
|
37
|
+
this.running = true;
|
|
38
|
+
}
|
|
39
|
+
async stop() {
|
|
40
|
+
this.running = false;
|
|
41
|
+
await this.bot.stop();
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Send a message to a chat. Automatically chunks messages exceeding
|
|
45
|
+
* Telegram's 4096-char limit, preferring newline boundaries.
|
|
46
|
+
*/
|
|
47
|
+
async sendMessage(chatId, text) {
|
|
48
|
+
const chunks = chunkMessage(text, exports.TELEGRAM_MAX_MESSAGE_LENGTH);
|
|
49
|
+
for (const chunk of chunks) {
|
|
50
|
+
await this.bot.telegram.sendMessage(chatId, chunk);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
onMessage(handler) {
|
|
54
|
+
this.messageHandler = handler;
|
|
55
|
+
}
|
|
56
|
+
async isHealthy() {
|
|
57
|
+
return this.running;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
exports.TelegramAdapter = TelegramAdapter;
|
|
61
|
+
/**
|
|
62
|
+
* Split text into chunks of maxLen or fewer characters,
|
|
63
|
+
* preferring to split at newline boundaries.
|
|
64
|
+
*/
|
|
65
|
+
function chunkMessage(text, maxLen) {
|
|
66
|
+
if (text.length <= maxLen) {
|
|
67
|
+
return [text];
|
|
68
|
+
}
|
|
69
|
+
const chunks = [];
|
|
70
|
+
let remaining = text;
|
|
71
|
+
while (remaining.length > 0) {
|
|
72
|
+
if (remaining.length <= maxLen) {
|
|
73
|
+
chunks.push(remaining);
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
// Find the last newline within the limit
|
|
77
|
+
const searchArea = remaining.slice(0, maxLen);
|
|
78
|
+
const lastNewline = searchArea.lastIndexOf('\n');
|
|
79
|
+
let splitAt;
|
|
80
|
+
if (lastNewline > 0) {
|
|
81
|
+
splitAt = lastNewline + 1; // include the newline in the current chunk
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
// No newline found — hard split at maxLen
|
|
85
|
+
splitAt = maxLen;
|
|
86
|
+
}
|
|
87
|
+
chunks.push(remaining.slice(0, splitAt));
|
|
88
|
+
remaining = remaining.slice(splitAt);
|
|
89
|
+
}
|
|
90
|
+
return chunks;
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=TelegramAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TelegramAdapter.js","sourceRoot":"","sources":["../../src/adapters/TelegramAdapter.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { ChannelManager } from './ChannelManager';
|
|
2
|
+
export { ConfigStore } from './ConfigStore';
|
|
3
|
+
export { TelegramAdapter, TELEGRAM_CHANNEL_TYPE, TELEGRAM_MAX_MESSAGE_LENGTH } from './adapters/TelegramAdapter';
|
|
4
|
+
export type { TelegramAdapterOptions } from './adapters/TelegramAdapter';
|
|
5
|
+
export type { ChannelAdapter } from './adapters/ChannelAdapter';
|
|
6
|
+
export type { IncomingMessage, MessageHandler, ChannelConfig, ChannelEntry, ChannelType, TelegramConfig, } from './types';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AACjH,YAAY,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AAEzE,YAAY,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAEhE,YAAY,EACR,eAAe,EACf,cAAc,EACd,aAAa,EACb,YAAY,EACZ,WAAW,EACX,cAAc,GACjB,MAAM,SAAS,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TELEGRAM_MAX_MESSAGE_LENGTH = exports.TELEGRAM_CHANNEL_TYPE = exports.TelegramAdapter = exports.ConfigStore = exports.ChannelManager = void 0;
|
|
4
|
+
var ChannelManager_1 = require("./ChannelManager");
|
|
5
|
+
Object.defineProperty(exports, "ChannelManager", { enumerable: true, get: function () { return ChannelManager_1.ChannelManager; } });
|
|
6
|
+
var ConfigStore_1 = require("./ConfigStore");
|
|
7
|
+
Object.defineProperty(exports, "ConfigStore", { enumerable: true, get: function () { return ConfigStore_1.ConfigStore; } });
|
|
8
|
+
var TelegramAdapter_1 = require("./adapters/TelegramAdapter");
|
|
9
|
+
Object.defineProperty(exports, "TelegramAdapter", { enumerable: true, get: function () { return TelegramAdapter_1.TelegramAdapter; } });
|
|
10
|
+
Object.defineProperty(exports, "TELEGRAM_CHANNEL_TYPE", { enumerable: true, get: function () { return TelegramAdapter_1.TELEGRAM_CHANNEL_TYPE; } });
|
|
11
|
+
Object.defineProperty(exports, "TELEGRAM_MAX_MESSAGE_LENGTH", { enumerable: true, get: function () { return TelegramAdapter_1.TELEGRAM_MAX_MESSAGE_LENGTH; } });
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,mDAAkD;AAAzC,gHAAA,cAAc,OAAA;AACvB,6CAA4C;AAAnC,0GAAA,WAAW,OAAA;AACpB,8DAAiH;AAAxG,kHAAA,eAAe,OAAA;AAAE,wHAAA,qBAAqB,OAAA;AAAE,8HAAA,2BAA2B,OAAA"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An incoming message from a messaging platform.
|
|
3
|
+
* Generic — no agent-specific concepts.
|
|
4
|
+
*/
|
|
5
|
+
export interface IncomingMessage {
|
|
6
|
+
channelType: string;
|
|
7
|
+
chatId: string;
|
|
8
|
+
userId: string;
|
|
9
|
+
text: string;
|
|
10
|
+
timestamp: Date;
|
|
11
|
+
metadata?: Record<string, unknown>;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Handler function provided by the consumer (e.g., CLI).
|
|
15
|
+
* Fire-and-forget — returns void. Responses are sent separately via sendMessage().
|
|
16
|
+
*/
|
|
17
|
+
export type MessageHandler = (message: IncomingMessage) => Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Root configuration for all channels.
|
|
20
|
+
*/
|
|
21
|
+
export interface ChannelConfig {
|
|
22
|
+
channels: Record<string, ChannelEntry>;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Configuration entry for a single channel.
|
|
26
|
+
*/
|
|
27
|
+
export interface ChannelEntry {
|
|
28
|
+
type: ChannelType;
|
|
29
|
+
enabled: boolean;
|
|
30
|
+
createdAt: string;
|
|
31
|
+
config: TelegramConfig;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Supported channel types.
|
|
35
|
+
*/
|
|
36
|
+
export type ChannelType = 'telegram' | 'slack' | 'whatsapp';
|
|
37
|
+
/**
|
|
38
|
+
* Telegram-specific configuration.
|
|
39
|
+
*/
|
|
40
|
+
export interface TelegramConfig {
|
|
41
|
+
botToken: string;
|
|
42
|
+
botUsername: string;
|
|
43
|
+
authorizedChatId?: number;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,IAAI,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED;;;GAGG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAEzE;;GAEG;AACH,MAAM,WAAW,aAAa;IAC1B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CAC1C;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IACzB,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,cAAc,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,OAAO,GAAG,UAAU,CAAC;AAE5D;;GAEG;AACH,MAAM,WAAW,cAAc;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC7B"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ai-devkit/channel-connector",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Generic messaging bridge for connecting to external communication platforms",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"default": "./dist/index.js"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsc",
|
|
15
|
+
"test": "jest",
|
|
16
|
+
"test:coverage": "jest --coverage",
|
|
17
|
+
"lint": "eslint src --ext .ts",
|
|
18
|
+
"typecheck": "tsc --noEmit",
|
|
19
|
+
"clean": "rm -rf dist"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"ai",
|
|
23
|
+
"channel",
|
|
24
|
+
"connector",
|
|
25
|
+
"telegram",
|
|
26
|
+
"messaging"
|
|
27
|
+
],
|
|
28
|
+
"author": "",
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"telegraf": "^4.16.3"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/jest": "^30.0.0",
|
|
35
|
+
"@types/node": "^20.11.5",
|
|
36
|
+
"@typescript-eslint/eslint-plugin": "^6.19.1",
|
|
37
|
+
"@typescript-eslint/parser": "^6.19.1",
|
|
38
|
+
"eslint": "^8.56.0",
|
|
39
|
+
"jest": "^29.7.0",
|
|
40
|
+
"ts-jest": "^29.4.5",
|
|
41
|
+
"typescript": "^5.3.3"
|
|
42
|
+
},
|
|
43
|
+
"engines": {
|
|
44
|
+
"node": ">=20.20.0"
|
|
45
|
+
}
|
|
46
|
+
}
|