@elizaos/plugin-bluebubbles 2.0.0-alpha.3 → 2.0.0-alpha.4

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 (60) hide show
  1. package/dist/actions/index.d.ts +6 -0
  2. package/dist/actions/index.d.ts.map +1 -0
  3. package/{src/actions/index.ts → dist/actions/index.js} +1 -0
  4. package/dist/actions/index.js.map +1 -0
  5. package/dist/actions/sendMessage.d.ts +6 -0
  6. package/dist/actions/sendMessage.d.ts.map +1 -0
  7. package/dist/actions/sendMessage.js +119 -0
  8. package/dist/actions/sendMessage.js.map +1 -0
  9. package/dist/actions/sendReaction.d.ts +6 -0
  10. package/dist/actions/sendReaction.d.ts.map +1 -0
  11. package/dist/actions/sendReaction.js +139 -0
  12. package/dist/actions/sendReaction.js.map +1 -0
  13. package/dist/client.d.ts +72 -0
  14. package/dist/client.d.ts.map +1 -0
  15. package/dist/client.js +272 -0
  16. package/dist/client.js.map +1 -0
  17. package/dist/constants.d.ts +33 -0
  18. package/dist/constants.d.ts.map +1 -0
  19. package/{src/constants.ts → dist/constants.js} +18 -22
  20. package/dist/constants.js.map +1 -0
  21. package/dist/environment.d.ts +44 -0
  22. package/dist/environment.d.ts.map +1 -0
  23. package/dist/environment.js +98 -0
  24. package/dist/environment.js.map +1 -0
  25. package/dist/index.d.ts +21 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/providers/chatContext.d.ts +6 -0
  29. package/dist/providers/chatContext.d.ts.map +1 -0
  30. package/dist/providers/chatContext.js +80 -0
  31. package/dist/providers/chatContext.js.map +1 -0
  32. package/dist/providers/chatState.d.ts +6 -0
  33. package/dist/providers/chatState.d.ts.map +1 -0
  34. package/dist/providers/chatState.js +64 -0
  35. package/dist/providers/chatState.js.map +1 -0
  36. package/dist/providers/index.d.ts +6 -0
  37. package/dist/providers/index.d.ts.map +1 -0
  38. package/{src/providers/index.ts → dist/providers/index.js} +2 -1
  39. package/dist/providers/index.js.map +1 -0
  40. package/dist/service.d.ts +87 -0
  41. package/dist/service.d.ts.map +1 -0
  42. package/dist/service.js +361 -0
  43. package/dist/service.js.map +1 -0
  44. package/dist/types.d.ts +140 -0
  45. package/dist/types.d.ts.map +1 -0
  46. package/dist/types.js +5 -0
  47. package/dist/types.js.map +1 -0
  48. package/package.json +18 -3
  49. package/__tests__/integration.test.ts +0 -260
  50. package/build.ts +0 -16
  51. package/src/actions/sendMessage.ts +0 -175
  52. package/src/actions/sendReaction.ts +0 -186
  53. package/src/client.ts +0 -389
  54. package/src/environment.ts +0 -120
  55. package/src/index.ts +0 -68
  56. package/src/providers/chatContext.ts +0 -105
  57. package/src/providers/chatState.ts +0 -90
  58. package/src/service.ts +0 -502
  59. package/src/types.ts +0 -165
  60. package/tsconfig.json +0 -22
@@ -0,0 +1,6 @@
1
+ /**
2
+ * BlueBubbles actions export
3
+ */
4
+ export { sendMessageAction } from "./sendMessage";
5
+ export { sendReactionAction } from "./sendReaction";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/actions/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC"}
@@ -3,3 +3,4 @@
3
3
  */
4
4
  export { sendMessageAction } from "./sendMessage";
5
5
  export { sendReactionAction } from "./sendReaction";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/actions/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Send message action for BlueBubbles
3
+ */
4
+ import { type Action } from "@elizaos/core";
5
+ export declare const sendMessageAction: Action;
6
+ //# sourceMappingURL=sendMessage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sendMessage.d.ts","sourceRoot":"","sources":["../../src/actions/sendMessage.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EACL,KAAK,MAAM,EAWZ,MAAM,eAAe,CAAC;AA6CvB,eAAO,MAAM,iBAAiB,EAAE,MAkG/B,CAAC"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Send message action for BlueBubbles
3
+ */
4
+ import { composePromptFromState, logger, ModelType, } from "@elizaos/core";
5
+ import { BLUEBUBBLES_SERVICE_NAME } from "../constants";
6
+ const sendMessageTemplate = `
7
+ # Task: Generate a response to send via iMessage (BlueBubbles)
8
+ {{recentMessages}}
9
+
10
+ # Instructions: Write a response to send to the user via iMessage. Be conversational and friendly.
11
+ Your response should be appropriate for iMessage - keep it relatively concise but engaging.
12
+ `;
13
+ const examples = [
14
+ [
15
+ {
16
+ name: "{{user1}}",
17
+ content: {
18
+ text: "Can you send a message to John saying I'll be late?",
19
+ },
20
+ },
21
+ {
22
+ name: "{{agentName}}",
23
+ content: {
24
+ text: "I'll send that message to John for you.",
25
+ action: "SEND_BLUEBUBBLES_MESSAGE",
26
+ },
27
+ },
28
+ ],
29
+ [
30
+ {
31
+ name: "{{user1}}",
32
+ content: {
33
+ text: "Reply to this iMessage for me",
34
+ },
35
+ },
36
+ {
37
+ name: "{{agentName}}",
38
+ content: {
39
+ text: "I'll compose and send a reply for you.",
40
+ action: "SEND_BLUEBUBBLES_MESSAGE",
41
+ },
42
+ },
43
+ ],
44
+ ];
45
+ export const sendMessageAction = {
46
+ name: "SEND_BLUEBUBBLES_MESSAGE",
47
+ description: "Send a message via iMessage through BlueBubbles",
48
+ similes: ["SEND_IMESSAGE", "TEXT_MESSAGE", "IMESSAGE_REPLY", "BLUEBUBBLES_SEND", "APPLE_MESSAGE"],
49
+ examples,
50
+ validate: async (runtime, _message) => {
51
+ const service = runtime.getService(BLUEBUBBLES_SERVICE_NAME);
52
+ return service?.getIsRunning() ?? false;
53
+ },
54
+ handler: async (runtime, message, state, _options, callback) => {
55
+ const service = runtime.getService(BLUEBUBBLES_SERVICE_NAME);
56
+ const currentState = state ?? (await runtime.composeState(message));
57
+ if (!service || !service.getIsRunning()) {
58
+ logger.error("BlueBubbles service is not available");
59
+ if (callback) {
60
+ await callback({
61
+ text: "Sorry, the iMessage service is currently unavailable.",
62
+ });
63
+ }
64
+ return { success: false, error: "BlueBubbles service not available" };
65
+ }
66
+ try {
67
+ // Get the room to find the target
68
+ const room = await runtime.getRoom(message.roomId);
69
+ if (!room?.channelId) {
70
+ logger.error("No channel ID found for room");
71
+ if (callback) {
72
+ await callback({
73
+ text: "Unable to determine the message recipient.",
74
+ });
75
+ }
76
+ return { success: false, error: "No channel ID" };
77
+ }
78
+ // Generate response if state is available
79
+ const prompt = composePromptFromState({
80
+ state: currentState,
81
+ template: sendMessageTemplate,
82
+ });
83
+ const response = await runtime.useModel(ModelType.TEXT_LARGE, {
84
+ prompt,
85
+ });
86
+ const responseText = typeof response === "string" ? response : (response.text ?? "");
87
+ if (!responseText.trim()) {
88
+ logger.warn("Generated empty response, skipping send");
89
+ return { success: false, error: "Empty response generated" };
90
+ }
91
+ // Send the message
92
+ const result = await service.sendMessage(room.channelId, responseText, message.content.inReplyTo);
93
+ logger.info(`Sent BlueBubbles message: ${result.guid}`);
94
+ const content = {
95
+ text: responseText,
96
+ source: "bluebubbles",
97
+ metadata: {
98
+ messageGuid: result.guid,
99
+ chatGuid: room.channelId,
100
+ },
101
+ };
102
+ if (callback) {
103
+ await callback(content);
104
+ }
105
+ return { success: true, text: responseText };
106
+ }
107
+ catch (error) {
108
+ const errorMessage = error instanceof Error ? error.message : String(error);
109
+ logger.error(`Failed to send BlueBubbles message: ${errorMessage}`);
110
+ if (callback) {
111
+ await callback({
112
+ text: "Failed to send the iMessage. Please try again.",
113
+ });
114
+ }
115
+ return { success: false, error: errorMessage };
116
+ }
117
+ },
118
+ };
119
+ //# sourceMappingURL=sendMessage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sendMessage.js","sourceRoot":"","sources":["../../src/actions/sendMessage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Send reaction action for the BlueBubbles plugin.
3
+ */
4
+ import type { Action } from "@elizaos/core";
5
+ export declare const sendReactionAction: Action;
6
+ //# sourceMappingURL=sendReaction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sendReaction.d.ts","sourceRoot":"","sources":["../../src/actions/sendReaction.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,MAAM,EAMP,MAAM,eAAe,CAAC;AAiCvB,eAAO,MAAM,kBAAkB,EAAE,MAwIhC,CAAC"}
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Send reaction action for the BlueBubbles plugin.
3
+ */
4
+ import { composePromptFromState, logger, ModelType, parseJSONObjectFromText } from "@elizaos/core";
5
+ import { BLUEBUBBLES_SERVICE_NAME } from "../constants.js";
6
+ const SEND_REACTION_TEMPLATE = `# Task: Extract BlueBubbles reaction parameters
7
+
8
+ Based on the conversation, determine what reaction to add or remove.
9
+
10
+ Recent conversation:
11
+ {{recentMessages}}
12
+
13
+ Extract the following:
14
+ 1. emoji: The emoji reaction to add (heart, thumbsup, thumbsdown, haha, exclamation, question, or any emoji)
15
+ 2. messageId: The message ID to react to (or "last" for the last message)
16
+ 3. remove: true to remove the reaction, false to add it
17
+
18
+ Respond with a JSON object:
19
+ \`\`\`json
20
+ {
21
+ "emoji": "❤️",
22
+ "messageId": "last",
23
+ "remove": false
24
+ }
25
+ \`\`\`
26
+ `;
27
+ export const sendReactionAction = {
28
+ name: "BLUEBUBBLES_SEND_REACTION",
29
+ similes: ["BLUEBUBBLES_REACT", "BB_REACTION", "IMESSAGE_REACT"],
30
+ description: "Add or remove a reaction on a message via BlueBubbles",
31
+ validate: async (_runtime, message, _state) => {
32
+ return message.content.source === "bluebubbles";
33
+ },
34
+ handler: async (runtime, message, state, _options, callback) => {
35
+ const bbService = runtime.getService(BLUEBUBBLES_SERVICE_NAME);
36
+ const currentState = state ?? (await runtime.composeState(message));
37
+ if (!bbService || !bbService.isConnected()) {
38
+ if (callback) {
39
+ await callback({
40
+ text: "BlueBubbles service is not available.",
41
+ source: "bluebubbles",
42
+ });
43
+ }
44
+ return { success: false, error: "BlueBubbles service not available" };
45
+ }
46
+ // Extract parameters using LLM
47
+ const prompt = await composePromptFromState({
48
+ template: SEND_REACTION_TEMPLATE,
49
+ state: currentState,
50
+ });
51
+ let reactionInfo = null;
52
+ for (let attempt = 0; attempt < 3; attempt++) {
53
+ const response = await runtime.useModel(ModelType.TEXT_SMALL, {
54
+ prompt,
55
+ });
56
+ const parsed = parseJSONObjectFromText(response);
57
+ if (parsed?.emoji) {
58
+ reactionInfo = {
59
+ emoji: String(parsed.emoji),
60
+ messageId: String(parsed.messageId || "last"),
61
+ remove: Boolean(parsed.remove),
62
+ };
63
+ break;
64
+ }
65
+ }
66
+ if (!reactionInfo || !reactionInfo.emoji) {
67
+ if (callback) {
68
+ await callback({
69
+ text: "I couldn't understand the reaction. Please specify an emoji.",
70
+ source: "bluebubbles",
71
+ });
72
+ }
73
+ return { success: false, error: "Could not extract reaction parameters" };
74
+ }
75
+ // Get chat context
76
+ const stateData = (currentState.data || {});
77
+ const chatGuid = stateData.chatGuid;
78
+ let messageGuid = reactionInfo.messageId;
79
+ if (!chatGuid) {
80
+ if (callback) {
81
+ await callback({
82
+ text: "I couldn't determine the chat to react in.",
83
+ source: "bluebubbles",
84
+ });
85
+ }
86
+ return { success: false, error: "Could not determine chat" };
87
+ }
88
+ // If "last", get the last message GUID from context
89
+ if (messageGuid === "last" || !messageGuid) {
90
+ messageGuid = stateData.lastMessageGuid;
91
+ if (!messageGuid) {
92
+ if (callback) {
93
+ await callback({
94
+ text: "I couldn't find the message to react to.",
95
+ source: "bluebubbles",
96
+ });
97
+ }
98
+ return { success: false, error: "Could not find message to react to" };
99
+ }
100
+ }
101
+ // Send reaction - we only support adding reactions, not removing
102
+ // The BlueBubbles API handles remove through a negative reaction type internally
103
+ const reactionValue = reactionInfo.remove ? `-${reactionInfo.emoji}` : reactionInfo.emoji;
104
+ const result = await bbService.sendReaction(chatGuid, messageGuid, reactionValue);
105
+ if (!result.success) {
106
+ if (callback) {
107
+ await callback({
108
+ text: `Failed to ${reactionInfo.remove ? "remove" : "add"} reaction.`,
109
+ source: "bluebubbles",
110
+ });
111
+ }
112
+ return { success: false, error: "Failed to send reaction" };
113
+ }
114
+ logger.debug(`${reactionInfo.remove ? "Removed" : "Added"} reaction ${reactionInfo.emoji} on ${messageGuid}`);
115
+ if (callback) {
116
+ await callback({
117
+ text: reactionInfo.remove ? "Reaction removed." : `Reacted with ${reactionInfo.emoji}.`,
118
+ source: message.content.source,
119
+ });
120
+ }
121
+ return { success: true };
122
+ },
123
+ examples: [
124
+ [
125
+ {
126
+ name: "{{user1}}",
127
+ content: { text: "React to that message with a heart" },
128
+ },
129
+ {
130
+ name: "{{agent}}",
131
+ content: {
132
+ text: "I'll add a heart reaction.",
133
+ actions: ["BLUEBUBBLES_SEND_REACTION"],
134
+ },
135
+ },
136
+ ],
137
+ ],
138
+ };
139
+ //# sourceMappingURL=sendReaction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sendReaction.js","sourceRoot":"","sources":["../../src/actions/sendReaction.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,72 @@
1
+ import type { BlueBubblesChat, BlueBubblesConfig, BlueBubblesMessage, BlueBubblesProbeResult, SendAttachmentOptions, SendMessageOptions, SendMessageResult } from "./types";
2
+ export declare class BlueBubblesClient {
3
+ private baseUrl;
4
+ private password;
5
+ constructor(config: BlueBubblesConfig);
6
+ private request;
7
+ /**
8
+ * Probes the BlueBubbles server to check connectivity and capabilities
9
+ */
10
+ probe(timeoutMs?: number): Promise<BlueBubblesProbeResult>;
11
+ /**
12
+ * Sends a text message
13
+ */
14
+ sendMessage(chatGuid: string, text: string, options?: SendMessageOptions): Promise<SendMessageResult>;
15
+ /**
16
+ * Sends an attachment
17
+ */
18
+ sendAttachment(chatGuid: string, attachmentPath: string, options?: SendAttachmentOptions): Promise<SendMessageResult>;
19
+ /**
20
+ * Sends an attachment from a buffer
21
+ */
22
+ sendAttachmentBuffer(chatGuid: string, buffer: Uint8Array, filename: string, mimeType: string, caption?: string): Promise<SendMessageResult>;
23
+ /**
24
+ * Gets information about a chat
25
+ */
26
+ getChat(chatGuid: string): Promise<BlueBubblesChat>;
27
+ /**
28
+ * Lists all chats
29
+ */
30
+ listChats(limit?: number, offset?: number): Promise<BlueBubblesChat[]>;
31
+ /**
32
+ * Gets messages for a chat
33
+ */
34
+ getMessages(chatGuid: string, limit?: number, offset?: number): Promise<BlueBubblesMessage[]>;
35
+ /**
36
+ * Marks a chat as read
37
+ */
38
+ markChatRead(chatGuid: string): Promise<void>;
39
+ /**
40
+ * Sends a reaction to a message
41
+ */
42
+ reactToMessage(chatGuid: string, messageGuid: string, reaction: string): Promise<void>;
43
+ /**
44
+ * Edits a message (requires private API)
45
+ */
46
+ editMessage(messageGuid: string, newText: string, backwardsCompatMessage?: string): Promise<void>;
47
+ /**
48
+ * Unsends a message (requires private API)
49
+ */
50
+ unsendMessage(messageGuid: string): Promise<void>;
51
+ /**
52
+ * Resolves a target (handle or chat GUID) to a chat GUID
53
+ */
54
+ resolveTarget(target: string): Promise<string>;
55
+ /**
56
+ * Creates a new group chat
57
+ */
58
+ createGroupChat(participants: string[], name?: string, message?: string): Promise<BlueBubblesChat>;
59
+ /**
60
+ * Adds a participant to a group chat
61
+ */
62
+ addParticipant(chatGuid: string, handle: string): Promise<void>;
63
+ /**
64
+ * Removes a participant from a group chat
65
+ */
66
+ removeParticipant(chatGuid: string, handle: string): Promise<void>;
67
+ /**
68
+ * Renames a group chat
69
+ */
70
+ renameGroupChat(chatGuid: string, newName: string): Promise<void>;
71
+ }
72
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,sBAAsB,EAEtB,qBAAqB,EACrB,kBAAkB,EAClB,iBAAiB,EAClB,MAAM,SAAS,CAAC;AAEjB,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAS;gBAEb,MAAM,EAAE,iBAAiB;YAKvB,OAAO;IAqBrB;;OAEG;IACG,KAAK,CAAC,SAAS,SAAO,GAAG,OAAO,CAAC,sBAAsB,CAAC;IA4B9D;;OAEG;IACG,WAAW,CACf,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,iBAAiB,CAAC;IAwB7B;;OAEG;IACG,cAAc,CAClB,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,EACtB,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,iBAAiB,CAAC;IAqC7B;;OAEG;IACG,oBAAoB,CACxB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,iBAAiB,CAAC;IA8B7B;;OAEG;IACG,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAOzD;;OAEG;IACG,SAAS,CAAC,KAAK,SAAM,EAAE,MAAM,SAAI,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;IAOpE;;OAEG;IACG,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,SAAK,EAAE,MAAM,SAAI,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAO1F;;OAEG;IACG,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOnD;;OAEG;IACG,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAW5F;;OAEG;IACG,WAAW,CACf,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,sBAAsB,CAAC,EAAE,MAAM,GAC9B,OAAO,CAAC,IAAI,CAAC;IAWhB;;OAEG;IACG,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOvD;;OAEG;IACG,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAsBpD;;OAEG;IACG,eAAe,CACnB,YAAY,EAAE,MAAM,EAAE,EACtB,IAAI,CAAC,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,eAAe,CAAC;IAY3B;;OAEG;IACG,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOrE;;OAEG;IACG,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOxE;;OAEG;IACG,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAMxE"}
package/dist/client.js ADDED
@@ -0,0 +1,272 @@
1
+ /**
2
+ * BlueBubbles API client for interacting with the BlueBubbles server
3
+ */
4
+ import { logger } from "@elizaos/core";
5
+ import { API_ENDPOINTS } from "./constants";
6
+ export class BlueBubblesClient {
7
+ baseUrl;
8
+ password;
9
+ constructor(config) {
10
+ this.baseUrl = config.serverUrl.replace(/\/$/, "");
11
+ this.password = config.password;
12
+ }
13
+ async request(endpoint, options = {}) {
14
+ const url = `${this.baseUrl}${endpoint}`;
15
+ const separator = endpoint.includes("?") ? "&" : "?";
16
+ const urlWithPassword = `${url}${separator}password=${encodeURIComponent(this.password)}`;
17
+ const response = await fetch(urlWithPassword, {
18
+ ...options,
19
+ headers: {
20
+ "Content-Type": "application/json",
21
+ ...options.headers,
22
+ },
23
+ });
24
+ if (!response.ok) {
25
+ const errorText = await response.text();
26
+ throw new Error(`BlueBubbles API error (${response.status}): ${errorText}`);
27
+ }
28
+ return response.json();
29
+ }
30
+ /**
31
+ * Probes the BlueBubbles server to check connectivity and capabilities
32
+ */
33
+ async probe(timeoutMs = 5000) {
34
+ try {
35
+ const controller = new AbortController();
36
+ const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
37
+ const info = await this.request(API_ENDPOINTS.SERVER_INFO, {
38
+ signal: controller.signal,
39
+ });
40
+ clearTimeout(timeoutId);
41
+ return {
42
+ ok: true,
43
+ serverVersion: info.data.server_version,
44
+ osVersion: info.data.os_version,
45
+ privateApiEnabled: info.data.private_api,
46
+ helperConnected: info.data.helper_connected,
47
+ };
48
+ }
49
+ catch (error) {
50
+ const errorMessage = error instanceof Error ? error.message : String(error);
51
+ logger.error(`BlueBubbles probe failed: ${errorMessage}`);
52
+ return {
53
+ ok: false,
54
+ error: errorMessage,
55
+ };
56
+ }
57
+ }
58
+ /**
59
+ * Sends a text message
60
+ */
61
+ async sendMessage(chatGuid, text, options = {}) {
62
+ const response = await this.request(API_ENDPOINTS.SEND_MESSAGE, {
63
+ method: "POST",
64
+ body: JSON.stringify({
65
+ chatGuid,
66
+ message: text,
67
+ tempGuid: options.tempGuid,
68
+ method: options.method ?? "apple-script",
69
+ subject: options.subject,
70
+ effectId: options.effectId,
71
+ partIndex: options.partIndex,
72
+ ddScan: options.ddScan,
73
+ }),
74
+ });
75
+ return {
76
+ guid: response.data.guid,
77
+ tempGuid: options.tempGuid,
78
+ status: "sent",
79
+ dateCreated: response.data.dateCreated,
80
+ text: response.data.text ?? text,
81
+ };
82
+ }
83
+ /**
84
+ * Sends an attachment
85
+ */
86
+ async sendAttachment(chatGuid, attachmentPath, options = {}) {
87
+ const formData = new FormData();
88
+ formData.append("chatGuid", chatGuid);
89
+ formData.append("attachment", attachmentPath);
90
+ if (options.tempGuid) {
91
+ formData.append("tempGuid", options.tempGuid);
92
+ }
93
+ if (options.name) {
94
+ formData.append("name", options.name);
95
+ }
96
+ if (options.isAudioMessage !== undefined) {
97
+ formData.append("isAudioMessage", String(options.isAudioMessage));
98
+ }
99
+ const url = `${this.baseUrl}${API_ENDPOINTS.SEND_ATTACHMENT}?password=${encodeURIComponent(this.password)}`;
100
+ const response = await fetch(url, {
101
+ method: "POST",
102
+ body: formData,
103
+ });
104
+ if (!response.ok) {
105
+ const errorText = await response.text();
106
+ throw new Error(`Failed to send attachment: ${errorText}`);
107
+ }
108
+ const result = (await response.json());
109
+ return {
110
+ guid: result.data.guid,
111
+ tempGuid: options.tempGuid,
112
+ status: "sent",
113
+ dateCreated: result.data.dateCreated,
114
+ text: result.data.text ?? "",
115
+ };
116
+ }
117
+ /**
118
+ * Sends an attachment from a buffer
119
+ */
120
+ async sendAttachmentBuffer(chatGuid, buffer, filename, mimeType, caption) {
121
+ const blob = new Blob([buffer], { type: mimeType });
122
+ const formData = new FormData();
123
+ formData.append("chatGuid", chatGuid);
124
+ formData.append("attachment", blob, filename);
125
+ if (caption) {
126
+ formData.append("message", caption);
127
+ }
128
+ const url = `${this.baseUrl}${API_ENDPOINTS.SEND_ATTACHMENT}?password=${encodeURIComponent(this.password)}`;
129
+ const response = await fetch(url, {
130
+ method: "POST",
131
+ body: formData,
132
+ });
133
+ if (!response.ok) {
134
+ const errorText = await response.text();
135
+ throw new Error(`Failed to send attachment: ${errorText}`);
136
+ }
137
+ const result = (await response.json());
138
+ return {
139
+ guid: result.data.guid,
140
+ status: "sent",
141
+ dateCreated: result.data.dateCreated,
142
+ text: caption ?? "",
143
+ };
144
+ }
145
+ /**
146
+ * Gets information about a chat
147
+ */
148
+ async getChat(chatGuid) {
149
+ const response = await this.request(`${API_ENDPOINTS.CHAT_INFO}/${encodeURIComponent(chatGuid)}`);
150
+ return response.data;
151
+ }
152
+ /**
153
+ * Lists all chats
154
+ */
155
+ async listChats(limit = 100, offset = 0) {
156
+ const response = await this.request(`${API_ENDPOINTS.CHATS}?limit=${limit}&offset=${offset}&with=lastMessage,participants`);
157
+ return response.data;
158
+ }
159
+ /**
160
+ * Gets messages for a chat
161
+ */
162
+ async getMessages(chatGuid, limit = 50, offset = 0) {
163
+ const response = await this.request(`${API_ENDPOINTS.CHAT_INFO}/${encodeURIComponent(chatGuid)}/message?limit=${limit}&offset=${offset}`);
164
+ return response.data;
165
+ }
166
+ /**
167
+ * Marks a chat as read
168
+ */
169
+ async markChatRead(chatGuid) {
170
+ const endpoint = API_ENDPOINTS.MARK_READ.replace(":guid", encodeURIComponent(chatGuid));
171
+ await this.request(endpoint, {
172
+ method: "POST",
173
+ });
174
+ }
175
+ /**
176
+ * Sends a reaction to a message
177
+ */
178
+ async reactToMessage(chatGuid, messageGuid, reaction) {
179
+ await this.request(API_ENDPOINTS.REACT, {
180
+ method: "POST",
181
+ body: JSON.stringify({
182
+ chatGuid,
183
+ messageGuid,
184
+ reaction,
185
+ }),
186
+ });
187
+ }
188
+ /**
189
+ * Edits a message (requires private API)
190
+ */
191
+ async editMessage(messageGuid, newText, backwardsCompatMessage) {
192
+ const endpoint = API_ENDPOINTS.EDIT.replace(":guid", encodeURIComponent(messageGuid));
193
+ await this.request(endpoint, {
194
+ method: "POST",
195
+ body: JSON.stringify({
196
+ editedMessage: newText,
197
+ backwardsCompatibilityMessage: backwardsCompatMessage ?? newText,
198
+ }),
199
+ });
200
+ }
201
+ /**
202
+ * Unsends a message (requires private API)
203
+ */
204
+ async unsendMessage(messageGuid) {
205
+ const endpoint = API_ENDPOINTS.UNSEND.replace(":guid", encodeURIComponent(messageGuid));
206
+ await this.request(endpoint, {
207
+ method: "POST",
208
+ });
209
+ }
210
+ /**
211
+ * Resolves a target (handle or chat GUID) to a chat GUID
212
+ */
213
+ async resolveTarget(target) {
214
+ // If it already looks like a chat GUID, return it
215
+ if (target.startsWith("iMessage;") || target.startsWith("SMS;")) {
216
+ return target;
217
+ }
218
+ // If it looks like a chat ID or identifier, query for it
219
+ if (target.startsWith("chat_")) {
220
+ const chats = await this.listChats();
221
+ const chat = chats.find((c) => c.chatIdentifier === target || c.guid === target || c.chatIdentifier.includes(target));
222
+ if (chat) {
223
+ return chat.guid;
224
+ }
225
+ }
226
+ // Otherwise, construct a DM chat GUID
227
+ // First try as iMessage, which is most common
228
+ return `iMessage;-;${target}`;
229
+ }
230
+ /**
231
+ * Creates a new group chat
232
+ */
233
+ async createGroupChat(participants, name, message) {
234
+ const response = await this.request(API_ENDPOINTS.CHATS, {
235
+ method: "POST",
236
+ body: JSON.stringify({
237
+ participants,
238
+ name,
239
+ message,
240
+ }),
241
+ });
242
+ return response.data;
243
+ }
244
+ /**
245
+ * Adds a participant to a group chat
246
+ */
247
+ async addParticipant(chatGuid, handle) {
248
+ await this.request(`${API_ENDPOINTS.CHAT_INFO}/${encodeURIComponent(chatGuid)}/participant`, {
249
+ method: "POST",
250
+ body: JSON.stringify({ address: handle }),
251
+ });
252
+ }
253
+ /**
254
+ * Removes a participant from a group chat
255
+ */
256
+ async removeParticipant(chatGuid, handle) {
257
+ await this.request(`${API_ENDPOINTS.CHAT_INFO}/${encodeURIComponent(chatGuid)}/participant`, {
258
+ method: "DELETE",
259
+ body: JSON.stringify({ address: handle }),
260
+ });
261
+ }
262
+ /**
263
+ * Renames a group chat
264
+ */
265
+ async renameGroupChat(chatGuid, newName) {
266
+ await this.request(`${API_ENDPOINTS.CHAT_INFO}/${encodeURIComponent(chatGuid)}`, {
267
+ method: "PATCH",
268
+ body: JSON.stringify({ displayName: newName }),
269
+ });
270
+ }
271
+ }
272
+ //# sourceMappingURL=client.js.map