@elizaos/plugin-bluebubbles 2.0.0-alpha.3 → 2.0.0-alpha.5
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/actions/index.d.ts +6 -0
- package/dist/actions/index.d.ts.map +1 -0
- package/{src/actions/index.ts → dist/actions/index.js} +1 -0
- package/dist/actions/index.js.map +1 -0
- package/dist/actions/sendMessage.d.ts +6 -0
- package/dist/actions/sendMessage.d.ts.map +1 -0
- package/dist/actions/sendMessage.js +127 -0
- package/dist/actions/sendMessage.js.map +1 -0
- package/dist/actions/sendReaction.d.ts +6 -0
- package/dist/actions/sendReaction.d.ts.map +1 -0
- package/dist/actions/sendReaction.js +143 -0
- package/dist/actions/sendReaction.js.map +1 -0
- package/dist/client.d.ts +72 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +272 -0
- package/dist/client.js.map +1 -0
- package/dist/constants.d.ts +33 -0
- package/dist/constants.d.ts.map +1 -0
- package/{src/constants.ts → dist/constants.js} +18 -22
- package/dist/constants.js.map +1 -0
- package/dist/environment.d.ts +44 -0
- package/dist/environment.d.ts.map +1 -0
- package/dist/environment.js +99 -0
- package/dist/environment.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js.map +1 -0
- package/dist/providers/chatContext.d.ts +6 -0
- package/dist/providers/chatContext.d.ts.map +1 -0
- package/dist/providers/chatContext.js +82 -0
- package/dist/providers/chatContext.js.map +1 -0
- package/dist/providers/chatState.d.ts +6 -0
- package/dist/providers/chatState.d.ts.map +1 -0
- package/dist/providers/chatState.js +64 -0
- package/dist/providers/chatState.js.map +1 -0
- package/dist/providers/index.d.ts +6 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/{src/providers/index.ts → dist/providers/index.js} +2 -1
- package/dist/providers/index.js.map +1 -0
- package/dist/service.d.ts +87 -0
- package/dist/service.d.ts.map +1 -0
- package/dist/service.js +363 -0
- package/dist/service.js.map +1 -0
- package/dist/types.d.ts +140 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +76 -3
- package/__tests__/integration.test.ts +0 -260
- package/build.ts +0 -16
- package/src/actions/sendMessage.ts +0 -175
- package/src/actions/sendReaction.ts +0 -186
- package/src/client.ts +0 -389
- package/src/environment.ts +0 -120
- package/src/index.ts +0 -68
- package/src/providers/chatContext.ts +0 -105
- package/src/providers/chatState.ts +0 -90
- package/src/service.ts +0 -502
- package/src/types.ts +0 -165
- package/tsconfig.json +0 -22
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chat context provider for the BlueBubbles plugin.
|
|
3
|
+
*/
|
|
4
|
+
import { BLUEBUBBLES_SERVICE_NAME } from "../constants.js";
|
|
5
|
+
/**
|
|
6
|
+
* Extract handle from a chat GUID
|
|
7
|
+
*/
|
|
8
|
+
function extractHandleFromChatGuid(chatGuid) {
|
|
9
|
+
if (!chatGuid)
|
|
10
|
+
return null;
|
|
11
|
+
// Format: iMessage;-;+1234567890 or iMessage;+;group_id
|
|
12
|
+
const parts = chatGuid.split(";");
|
|
13
|
+
if (parts.length >= 3 && parts[1] === "-") {
|
|
14
|
+
return parts[2];
|
|
15
|
+
}
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
export const chatContextProvider = {
|
|
19
|
+
name: "bluebubblesChatContext",
|
|
20
|
+
description: "Provides information about the current BlueBubbles/iMessage chat context",
|
|
21
|
+
get: async (runtime, message, state) => {
|
|
22
|
+
// Only provide context for BlueBubbles messages
|
|
23
|
+
if (message.content.source !== "bluebubbles") {
|
|
24
|
+
return { text: "" };
|
|
25
|
+
}
|
|
26
|
+
const bbService = runtime.getService(BLUEBUBBLES_SERVICE_NAME);
|
|
27
|
+
if (!bbService || !bbService.isConnected()) {
|
|
28
|
+
return {
|
|
29
|
+
values: { connected: false },
|
|
30
|
+
text: "",
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
const agentName = state.values?.agentName?.toString() || "The agent";
|
|
34
|
+
const stateData = (state.data || {});
|
|
35
|
+
const chatGuid = stateData.chatGuid;
|
|
36
|
+
const handle = stateData.handle;
|
|
37
|
+
const displayName = stateData.displayName;
|
|
38
|
+
// Determine chat type from GUID
|
|
39
|
+
let chatType = "direct";
|
|
40
|
+
let chatDescription = "";
|
|
41
|
+
if (chatGuid) {
|
|
42
|
+
if (chatGuid.includes(";+;")) {
|
|
43
|
+
chatType = "group";
|
|
44
|
+
chatDescription = displayName
|
|
45
|
+
? `group chat "${displayName}"`
|
|
46
|
+
: "a group chat";
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
const extractedHandle = extractHandleFromChatGuid(chatGuid);
|
|
50
|
+
chatDescription = extractedHandle
|
|
51
|
+
? `direct message with ${extractedHandle}`
|
|
52
|
+
: handle
|
|
53
|
+
? `direct message with ${handle}`
|
|
54
|
+
: "a direct message";
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
else if (handle) {
|
|
58
|
+
chatDescription = `direct message with ${handle}`;
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
chatDescription = "an iMessage conversation";
|
|
62
|
+
}
|
|
63
|
+
const responseText = `${agentName} is chatting via iMessage (BlueBubbles) in ${chatDescription}. ` +
|
|
64
|
+
"This channel supports reactions, effects (slam, balloons, confetti, etc.), editing, and replying to messages.";
|
|
65
|
+
return {
|
|
66
|
+
values: {
|
|
67
|
+
chatGuid,
|
|
68
|
+
handle,
|
|
69
|
+
displayName,
|
|
70
|
+
chatType,
|
|
71
|
+
connected: true,
|
|
72
|
+
platform: "bluebubbles",
|
|
73
|
+
supportsReactions: true,
|
|
74
|
+
supportsEffects: true,
|
|
75
|
+
supportsEdit: true,
|
|
76
|
+
supportsReply: true,
|
|
77
|
+
},
|
|
78
|
+
text: responseText,
|
|
79
|
+
};
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
//# sourceMappingURL=chatContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chatContext.js","sourceRoot":"","sources":["../../src/providers/chatContext.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chatState.d.ts","sourceRoot":"","sources":["../../src/providers/chatState.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAIL,KAAK,QAAQ,EAGd,MAAM,eAAe,CAAC;AAKvB,eAAO,MAAM,iBAAiB,EAAE,QA0C/B,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chat state provider for BlueBubbles
|
|
3
|
+
*/
|
|
4
|
+
import { logger, } from "@elizaos/core";
|
|
5
|
+
import { BLUEBUBBLES_SERVICE_NAME } from "../constants";
|
|
6
|
+
export const chatStateProvider = {
|
|
7
|
+
name: "BLUEBUBBLES_CHAT_STATE",
|
|
8
|
+
description: "Provides information about the current BlueBubbles/iMessage chat context",
|
|
9
|
+
get: async (runtime, message, _state) => {
|
|
10
|
+
const service = runtime.getService(BLUEBUBBLES_SERVICE_NAME);
|
|
11
|
+
if (!service || !service.getIsRunning()) {
|
|
12
|
+
return { text: "" };
|
|
13
|
+
}
|
|
14
|
+
try {
|
|
15
|
+
const room = await runtime.getRoom(message.roomId);
|
|
16
|
+
if (!room?.channelId) {
|
|
17
|
+
return { text: "" };
|
|
18
|
+
}
|
|
19
|
+
// Only provide state for BlueBubbles channels
|
|
20
|
+
if (room.source !== "bluebubbles") {
|
|
21
|
+
return { text: "" };
|
|
22
|
+
}
|
|
23
|
+
const chatState = await service.getChatState(room.channelId);
|
|
24
|
+
if (!chatState) {
|
|
25
|
+
return { text: "" };
|
|
26
|
+
}
|
|
27
|
+
return { text: formatChatState(chatState) };
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
logger.debug(`Failed to get BlueBubbles chat state: ${error instanceof Error ? error.message : String(error)}`);
|
|
31
|
+
return { text: "" };
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Formats the chat state for inclusion in prompts
|
|
37
|
+
*/
|
|
38
|
+
function formatChatState(state) {
|
|
39
|
+
const lines = [
|
|
40
|
+
"# iMessage Chat Context (BlueBubbles)",
|
|
41
|
+
"",
|
|
42
|
+
`- Chat Type: ${state.isGroup ? "Group Chat" : "Direct Message"}`,
|
|
43
|
+
];
|
|
44
|
+
if (state.displayName) {
|
|
45
|
+
lines.push(`- Chat Name: ${state.displayName}`);
|
|
46
|
+
}
|
|
47
|
+
if (state.isGroup) {
|
|
48
|
+
lines.push(`- Participants: ${state.participants.join(", ")}`);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
lines.push(`- Contact: ${state.participants[0] ?? state.chatIdentifier}`);
|
|
52
|
+
}
|
|
53
|
+
if (state.lastMessageAt) {
|
|
54
|
+
const lastMessageDate = new Date(state.lastMessageAt);
|
|
55
|
+
lines.push(`- Last Message: ${lastMessageDate.toLocaleString()}`);
|
|
56
|
+
}
|
|
57
|
+
if (state.hasUnread) {
|
|
58
|
+
lines.push("- Has Unread Messages: Yes");
|
|
59
|
+
}
|
|
60
|
+
lines.push("");
|
|
61
|
+
lines.push("Note: This conversation is happening through iMessage. Be conversational and friendly.");
|
|
62
|
+
return lines.join("\n");
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=chatState.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chatState.js","sourceRoot":"","sources":["../../src/providers/chatState.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BlueBubbles service for ElizaOS
|
|
3
|
+
*/
|
|
4
|
+
import { type IAgentRuntime, Service } from "@elizaos/core";
|
|
5
|
+
import { BlueBubblesClient } from "./client";
|
|
6
|
+
import type { BlueBubblesChatState, BlueBubblesConfig, BlueBubblesWebhookPayload } from "./types";
|
|
7
|
+
export declare class BlueBubblesService extends Service {
|
|
8
|
+
static serviceType: string;
|
|
9
|
+
capabilityDescription: string;
|
|
10
|
+
private client;
|
|
11
|
+
private blueBubblesConfig;
|
|
12
|
+
private knownChats;
|
|
13
|
+
private entityCache;
|
|
14
|
+
private roomCache;
|
|
15
|
+
private webhookPath;
|
|
16
|
+
private isRunning;
|
|
17
|
+
constructor(runtime?: IAgentRuntime);
|
|
18
|
+
static start(runtime: IAgentRuntime): Promise<BlueBubblesService>;
|
|
19
|
+
static stopRuntime(runtime: IAgentRuntime): Promise<void>;
|
|
20
|
+
stop(): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Gets the BlueBubbles client
|
|
23
|
+
*/
|
|
24
|
+
getClient(): BlueBubblesClient | null;
|
|
25
|
+
/**
|
|
26
|
+
* Gets the current configuration
|
|
27
|
+
*/
|
|
28
|
+
getConfig(): BlueBubblesConfig | null;
|
|
29
|
+
/**
|
|
30
|
+
* Checks if the service is running
|
|
31
|
+
*/
|
|
32
|
+
getIsRunning(): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Gets the webhook path for receiving messages
|
|
35
|
+
*/
|
|
36
|
+
getWebhookPath(): string;
|
|
37
|
+
/**
|
|
38
|
+
* Initializes known chats from the server
|
|
39
|
+
*/
|
|
40
|
+
private initializeChats;
|
|
41
|
+
/**
|
|
42
|
+
* Handles an incoming webhook payload
|
|
43
|
+
*/
|
|
44
|
+
handleWebhook(payload: BlueBubblesWebhookPayload): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Handles an incoming message
|
|
47
|
+
*/
|
|
48
|
+
private handleIncomingMessage;
|
|
49
|
+
/**
|
|
50
|
+
* Handles a message update (edit, unsend, etc.)
|
|
51
|
+
*/
|
|
52
|
+
private handleMessageUpdate;
|
|
53
|
+
/**
|
|
54
|
+
* Handles a chat update
|
|
55
|
+
*/
|
|
56
|
+
private handleChatUpdate;
|
|
57
|
+
/**
|
|
58
|
+
* Gets or creates an entity for a BlueBubbles handle
|
|
59
|
+
*/
|
|
60
|
+
private getOrCreateEntity;
|
|
61
|
+
/**
|
|
62
|
+
* Gets or creates a room for a BlueBubbles chat
|
|
63
|
+
*/
|
|
64
|
+
private getOrCreateRoom;
|
|
65
|
+
/**
|
|
66
|
+
* Sends a message to a target
|
|
67
|
+
*/
|
|
68
|
+
sendMessage(target: string, text: string, _replyToId?: string): Promise<{
|
|
69
|
+
guid: string;
|
|
70
|
+
}>;
|
|
71
|
+
/**
|
|
72
|
+
* Gets the state for a chat
|
|
73
|
+
*/
|
|
74
|
+
getChatState(chatGuid: string): Promise<BlueBubblesChatState | null>;
|
|
75
|
+
private chatToState;
|
|
76
|
+
/**
|
|
77
|
+
* Checks if the service is connected
|
|
78
|
+
*/
|
|
79
|
+
isConnected(): boolean;
|
|
80
|
+
/**
|
|
81
|
+
* Sends a reaction to a message
|
|
82
|
+
*/
|
|
83
|
+
sendReaction(chatGuid: string, messageGuid: string, reaction: string): Promise<{
|
|
84
|
+
success: boolean;
|
|
85
|
+
}>;
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAQL,KAAK,aAAa,EAElB,OAAO,EAER,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAO7C,OAAO,KAAK,EAEV,oBAAoB,EACpB,iBAAiB,EAGjB,yBAAyB,EAC1B,MAAM,SAAS,CAAC;AAEjB,qBAAa,kBAAmB,SAAQ,OAAO;IAC7C,MAAM,CAAC,WAAW,SAA4B;IAC9C,qBAAqB,SAC+C;IAEpE,OAAO,CAAC,MAAM,CAAkC;IAChD,OAAO,CAAC,iBAAiB,CAAkC;IAC3D,OAAO,CAAC,UAAU,CAA2C;IAC7D,OAAO,CAAC,WAAW,CAAgC;IACnD,OAAO,CAAC,SAAS,CAAgC;IACjD,OAAO,CAAC,WAAW,CAAgC;IACnD,OAAO,CAAC,SAAS,CAAS;gBAEd,OAAO,CAAC,EAAE,aAAa;WAsBtB,KAAK,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,kBAAkB,CAAC;WA+C1D,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IASzD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAK3B;;OAEG;IACH,SAAS,IAAI,iBAAiB,GAAG,IAAI;IAIrC;;OAEG;IACH,SAAS,IAAI,iBAAiB,GAAG,IAAI;IAIrC;;OAEG;IACH,YAAY,IAAI,OAAO;IAIvB;;OAEG;IACH,cAAc,IAAI,MAAM;IAIxB;;OAEG;YACW,eAAe;IAgB7B;;OAEG;IACG,aAAa,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC;IAiCtE;;OAEG;YACW,qBAAqB;IA2GnC;;OAEG;YACW,mBAAmB;IASjC;;OAEG;YACW,gBAAgB;IAO9B;;OAEG;YACW,iBAAiB;IAoC/B;;OAEG;YACW,eAAe;IAgC7B;;OAEG;IACG,WAAW,CACf,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAc5B;;OAEG;IACG,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAmB1E,OAAO,CAAC,WAAW;IAYnB;;OAEG;IACH,WAAW,IAAI,OAAO;IAItB;;OAEG;IACG,YAAY,CAChB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;CAejC"}
|
package/dist/service.js
ADDED
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BlueBubbles service for ElizaOS
|
|
3
|
+
*/
|
|
4
|
+
import { ChannelType, createUniqueUuid, EventType, logger, Service, } from "@elizaos/core";
|
|
5
|
+
import { BlueBubblesClient } from "./client";
|
|
6
|
+
import { BLUEBUBBLES_SERVICE_NAME, DEFAULT_WEBHOOK_PATH } from "./constants";
|
|
7
|
+
import { getConfigFromRuntime, isHandleAllowed, normalizeHandle, } from "./environment";
|
|
8
|
+
export class BlueBubblesService extends Service {
|
|
9
|
+
static serviceType = BLUEBUBBLES_SERVICE_NAME;
|
|
10
|
+
capabilityDescription = "The agent is able to send and receive iMessages via BlueBubbles";
|
|
11
|
+
client = null;
|
|
12
|
+
blueBubblesConfig = null;
|
|
13
|
+
knownChats = new Map();
|
|
14
|
+
entityCache = new Map();
|
|
15
|
+
roomCache = new Map();
|
|
16
|
+
webhookPath = DEFAULT_WEBHOOK_PATH;
|
|
17
|
+
isRunning = false;
|
|
18
|
+
constructor(runtime) {
|
|
19
|
+
super(runtime);
|
|
20
|
+
if (!runtime)
|
|
21
|
+
return;
|
|
22
|
+
this.blueBubblesConfig = getConfigFromRuntime(runtime);
|
|
23
|
+
if (!this.blueBubblesConfig) {
|
|
24
|
+
logger.warn("BlueBubbles configuration not provided - BlueBubbles functionality will be unavailable");
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
if (!this.blueBubblesConfig.enabled) {
|
|
28
|
+
logger.info("BlueBubbles plugin is disabled via configuration");
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
this.webhookPath =
|
|
32
|
+
this.blueBubblesConfig.webhookPath ?? DEFAULT_WEBHOOK_PATH;
|
|
33
|
+
this.client = new BlueBubblesClient(this.blueBubblesConfig);
|
|
34
|
+
}
|
|
35
|
+
static async start(runtime) {
|
|
36
|
+
const service = new BlueBubblesService(runtime);
|
|
37
|
+
if (!service.client) {
|
|
38
|
+
logger.warn("BlueBubbles service started without client functionality - no configuration provided");
|
|
39
|
+
return service;
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
// Probe the server to verify connectivity
|
|
43
|
+
const probeResult = await service.client.probe();
|
|
44
|
+
if (!probeResult.ok) {
|
|
45
|
+
logger.error(`Failed to connect to BlueBubbles server: ${probeResult.error}`);
|
|
46
|
+
return service;
|
|
47
|
+
}
|
|
48
|
+
logger.success(`Connected to BlueBubbles server v${probeResult.serverVersion} on macOS ${probeResult.osVersion}`);
|
|
49
|
+
if (probeResult.privateApiEnabled) {
|
|
50
|
+
logger.info("BlueBubbles Private API is enabled - edit and unsend features available");
|
|
51
|
+
}
|
|
52
|
+
// Initialize known chats
|
|
53
|
+
await service.initializeChats();
|
|
54
|
+
service.isRunning = true;
|
|
55
|
+
logger.success(`BlueBubbles service started for ${runtime.character.name}`);
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
logger.error(`Failed to start BlueBubbles service: ${error instanceof Error ? error.message : String(error)}`);
|
|
59
|
+
}
|
|
60
|
+
return service;
|
|
61
|
+
}
|
|
62
|
+
static async stopRuntime(runtime) {
|
|
63
|
+
const service = runtime.getService(BLUEBUBBLES_SERVICE_NAME);
|
|
64
|
+
if (service) {
|
|
65
|
+
await service.stop();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
async stop() {
|
|
69
|
+
this.isRunning = false;
|
|
70
|
+
logger.info("BlueBubbles service stopped");
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Gets the BlueBubbles client
|
|
74
|
+
*/
|
|
75
|
+
getClient() {
|
|
76
|
+
return this.client;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Gets the current configuration
|
|
80
|
+
*/
|
|
81
|
+
getConfig() {
|
|
82
|
+
return this.blueBubblesConfig;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Checks if the service is running
|
|
86
|
+
*/
|
|
87
|
+
getIsRunning() {
|
|
88
|
+
return this.isRunning;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Gets the webhook path for receiving messages
|
|
92
|
+
*/
|
|
93
|
+
getWebhookPath() {
|
|
94
|
+
return this.webhookPath;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Initializes known chats from the server
|
|
98
|
+
*/
|
|
99
|
+
async initializeChats() {
|
|
100
|
+
if (!this.client)
|
|
101
|
+
return;
|
|
102
|
+
try {
|
|
103
|
+
const chats = await this.client.listChats(100);
|
|
104
|
+
for (const chat of chats) {
|
|
105
|
+
this.knownChats.set(chat.guid, chat);
|
|
106
|
+
}
|
|
107
|
+
logger.info(`Loaded ${chats.length} BlueBubbles chats`);
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
logger.error(`Failed to load BlueBubbles chats: ${error instanceof Error ? error.message : String(error)}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Handles an incoming webhook payload
|
|
115
|
+
*/
|
|
116
|
+
async handleWebhook(payload) {
|
|
117
|
+
if (!this.blueBubblesConfig || !this.client) {
|
|
118
|
+
logger.warn("Received webhook but BlueBubbles service is not configured");
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
const event = {
|
|
122
|
+
type: payload.type,
|
|
123
|
+
data: payload.data,
|
|
124
|
+
};
|
|
125
|
+
switch (event.type) {
|
|
126
|
+
case "new-message":
|
|
127
|
+
await this.handleIncomingMessage(event.data);
|
|
128
|
+
break;
|
|
129
|
+
case "updated-message":
|
|
130
|
+
await this.handleMessageUpdate(event.data);
|
|
131
|
+
break;
|
|
132
|
+
case "chat-updated":
|
|
133
|
+
await this.handleChatUpdate(event.data);
|
|
134
|
+
break;
|
|
135
|
+
case "typing-indicator":
|
|
136
|
+
case "read-receipt":
|
|
137
|
+
// These events can be logged but don't require action
|
|
138
|
+
logger.debug(`BlueBubbles ${event.type}: ${JSON.stringify(event.data)}`);
|
|
139
|
+
break;
|
|
140
|
+
default:
|
|
141
|
+
logger.debug(`Unhandled BlueBubbles event: ${event.type}`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Handles an incoming message
|
|
146
|
+
*/
|
|
147
|
+
async handleIncomingMessage(message) {
|
|
148
|
+
// Skip outgoing messages
|
|
149
|
+
if (message.isFromMe) {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
// Skip system messages
|
|
153
|
+
if (message.isSystemMessage) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
if (!this.blueBubblesConfig) {
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
const chat = message.chats[0];
|
|
160
|
+
if (!chat) {
|
|
161
|
+
logger.warn(`Received message without chat info: ${message.guid}`);
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
const isGroup = chat.participants.length > 1;
|
|
165
|
+
const senderHandle = message.handle?.address ?? "";
|
|
166
|
+
// Check access policies
|
|
167
|
+
if (isGroup) {
|
|
168
|
+
if (!isHandleAllowed(senderHandle, this.blueBubblesConfig.groupAllowFrom ?? [], this.blueBubblesConfig.groupPolicy ?? "allowlist")) {
|
|
169
|
+
logger.debug(`Ignoring message from ${senderHandle} - not in group allowlist`);
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
if (!isHandleAllowed(senderHandle, this.blueBubblesConfig.allowFrom ?? [], this.blueBubblesConfig.dmPolicy ?? "pairing")) {
|
|
175
|
+
logger.debug(`Ignoring message from ${senderHandle} - not in DM allowlist`);
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
// Mark as read if configured
|
|
180
|
+
if (this.blueBubblesConfig.sendReadReceipts && this.client) {
|
|
181
|
+
try {
|
|
182
|
+
await this.client.markChatRead(chat.guid);
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
logger.debug(`Failed to mark chat as read: ${error}`);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
// Create or get entity for sender
|
|
189
|
+
const entityId = await this.getOrCreateEntity(senderHandle, message.handle?.address);
|
|
190
|
+
// Create or get room for chat
|
|
191
|
+
const roomId = await this.getOrCreateRoom(chat);
|
|
192
|
+
// Build content
|
|
193
|
+
const content = {
|
|
194
|
+
text: message.text ?? "",
|
|
195
|
+
source: "bluebubbles",
|
|
196
|
+
inReplyTo: (message.threadOriginatorGuid ?? undefined),
|
|
197
|
+
attachments: message.attachments.map((att) => ({
|
|
198
|
+
id: att.guid,
|
|
199
|
+
url: `${this.blueBubblesConfig?.serverUrl}/api/v1/attachment/${encodeURIComponent(att.guid)}?password=${encodeURIComponent(this.blueBubblesConfig?.password ?? "")}`,
|
|
200
|
+
title: att.transferName,
|
|
201
|
+
description: att.mimeType ?? undefined,
|
|
202
|
+
contentType: (att.mimeType ??
|
|
203
|
+
"application/octet-stream"),
|
|
204
|
+
})),
|
|
205
|
+
};
|
|
206
|
+
// Emit message event
|
|
207
|
+
if (this.runtime) {
|
|
208
|
+
this.runtime.emitEvent(EventType.MESSAGE_RECEIVED, {
|
|
209
|
+
runtime: this.runtime,
|
|
210
|
+
message: {
|
|
211
|
+
id: createUniqueUuid(this.runtime, message.guid),
|
|
212
|
+
entityId,
|
|
213
|
+
roomId,
|
|
214
|
+
content,
|
|
215
|
+
createdAt: message.dateCreated,
|
|
216
|
+
},
|
|
217
|
+
source: "bluebubbles",
|
|
218
|
+
channelType: isGroup ? ChannelType.GROUP : ChannelType.DM,
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Handles a message update (edit, unsend, etc.)
|
|
224
|
+
*/
|
|
225
|
+
async handleMessageUpdate(message) {
|
|
226
|
+
// Handle edited or unsent messages
|
|
227
|
+
if (message.dateEdited) {
|
|
228
|
+
logger.debug(`Message ${message.guid} was edited`);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Handles a chat update
|
|
233
|
+
*/
|
|
234
|
+
async handleChatUpdate(chat) {
|
|
235
|
+
this.knownChats.set(chat.guid, chat);
|
|
236
|
+
logger.debug(`Chat ${chat.guid} updated: ${chat.displayName ?? chat.chatIdentifier}`);
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Gets or creates an entity for a BlueBubbles handle
|
|
240
|
+
*/
|
|
241
|
+
async getOrCreateEntity(handle, displayName) {
|
|
242
|
+
const normalized = normalizeHandle(handle);
|
|
243
|
+
const cached = this.entityCache.get(normalized);
|
|
244
|
+
if (cached) {
|
|
245
|
+
return cached;
|
|
246
|
+
}
|
|
247
|
+
const entityId = createUniqueUuid(this.runtime, `bluebubbles:${normalized}`);
|
|
248
|
+
// Check if entity exists
|
|
249
|
+
const existing = await this.runtime.getEntityById(entityId);
|
|
250
|
+
if (!existing) {
|
|
251
|
+
const entity = {
|
|
252
|
+
id: entityId,
|
|
253
|
+
agentId: this.runtime.agentId,
|
|
254
|
+
names: displayName ? [displayName, normalized] : [normalized],
|
|
255
|
+
metadata: {
|
|
256
|
+
bluebubbles: {
|
|
257
|
+
handle: normalized,
|
|
258
|
+
displayName: displayName ?? normalized,
|
|
259
|
+
},
|
|
260
|
+
},
|
|
261
|
+
};
|
|
262
|
+
await this.runtime.createEntity(entity);
|
|
263
|
+
}
|
|
264
|
+
this.entityCache.set(normalized, entityId);
|
|
265
|
+
return entityId;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Gets or creates a room for a BlueBubbles chat
|
|
269
|
+
*/
|
|
270
|
+
async getOrCreateRoom(chat) {
|
|
271
|
+
const cached = this.roomCache.get(chat.guid);
|
|
272
|
+
if (cached) {
|
|
273
|
+
return cached;
|
|
274
|
+
}
|
|
275
|
+
const roomId = createUniqueUuid(this.runtime, `bluebubbles:${chat.guid}`);
|
|
276
|
+
// Check if room exists
|
|
277
|
+
const existing = await this.runtime.getRoom(roomId);
|
|
278
|
+
if (!existing && this.runtime) {
|
|
279
|
+
const isGroup = chat.participants.length > 1;
|
|
280
|
+
await this.runtime.createRoom({
|
|
281
|
+
id: roomId,
|
|
282
|
+
name: chat.displayName ?? chat.chatIdentifier,
|
|
283
|
+
source: "bluebubbles",
|
|
284
|
+
type: isGroup ? ChannelType.GROUP : ChannelType.DM,
|
|
285
|
+
channelId: chat.guid,
|
|
286
|
+
worldId: this.runtime.agentId,
|
|
287
|
+
metadata: {
|
|
288
|
+
blueBubblesServerUrl: this.blueBubblesConfig?.serverUrl,
|
|
289
|
+
},
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
this.roomCache.set(chat.guid, roomId);
|
|
293
|
+
return roomId;
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Sends a message to a target
|
|
297
|
+
*/
|
|
298
|
+
async sendMessage(target, text, _replyToId) {
|
|
299
|
+
if (!this.client) {
|
|
300
|
+
throw new Error("BlueBubbles client not initialized");
|
|
301
|
+
}
|
|
302
|
+
const chatGuid = await this.client.resolveTarget(target);
|
|
303
|
+
const result = await this.client.sendMessage(chatGuid, text, {
|
|
304
|
+
// If we have a replyToId, use it as threadOriginatorGuid
|
|
305
|
+
// BlueBubbles handles this through the message association
|
|
306
|
+
});
|
|
307
|
+
return { guid: result.guid };
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Gets the state for a chat
|
|
311
|
+
*/
|
|
312
|
+
async getChatState(chatGuid) {
|
|
313
|
+
const chat = this.knownChats.get(chatGuid);
|
|
314
|
+
if (!chat && this.client) {
|
|
315
|
+
try {
|
|
316
|
+
const fetchedChat = await this.client.getChat(chatGuid);
|
|
317
|
+
this.knownChats.set(chatGuid, fetchedChat);
|
|
318
|
+
return this.chatToState(fetchedChat);
|
|
319
|
+
}
|
|
320
|
+
catch {
|
|
321
|
+
return null;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
if (!chat) {
|
|
325
|
+
return null;
|
|
326
|
+
}
|
|
327
|
+
return this.chatToState(chat);
|
|
328
|
+
}
|
|
329
|
+
chatToState(chat) {
|
|
330
|
+
return {
|
|
331
|
+
chatGuid: chat.guid,
|
|
332
|
+
chatIdentifier: chat.chatIdentifier,
|
|
333
|
+
isGroup: chat.participants.length > 1,
|
|
334
|
+
participants: chat.participants.map((p) => p.address),
|
|
335
|
+
displayName: chat.displayName,
|
|
336
|
+
lastMessageAt: chat.lastMessage?.dateCreated ?? null,
|
|
337
|
+
hasUnread: chat.hasUnreadMessages,
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Checks if the service is connected
|
|
342
|
+
*/
|
|
343
|
+
isConnected() {
|
|
344
|
+
return this.isRunning && this.client !== null;
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Sends a reaction to a message
|
|
348
|
+
*/
|
|
349
|
+
async sendReaction(chatGuid, messageGuid, reaction) {
|
|
350
|
+
if (!this.client) {
|
|
351
|
+
throw new Error("BlueBubbles client not initialized");
|
|
352
|
+
}
|
|
353
|
+
try {
|
|
354
|
+
await this.client.reactToMessage(chatGuid, messageGuid, reaction);
|
|
355
|
+
return { success: true };
|
|
356
|
+
}
|
|
357
|
+
catch (error) {
|
|
358
|
+
logger.error(`Failed to send reaction: ${error instanceof Error ? error.message : String(error)}`);
|
|
359
|
+
return { success: false };
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
//# sourceMappingURL=service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
|