Server for forwarding iMessages to clients within the BlueBubbles App ecosystem
See the codeThis is the back-end server for the BlueBubbles App. It allows you to forward your iMessages to and from an Android device via the BlueBubbles App.
Warning: Yarn may not work for this project. You may run into build errors.
git clone git@github.com:BlueBubblesApp/BlueBubbles-Server.gitcd BlueBubbles-Servernpm installnpm run startIf you are using macOS 10.x and are having issues building/running the server, please downgrade the node-mac-permissions dependency to v2.2.0. The reason it's on a newer version is to fix a production crashing issue on Big Sur+. Please downgrade it manually for testing on macOS v10.x.
cd packages/server
npm install node-mac-permissions@2.2.0
/bluebubbles-server/src//bluebubbles-server/src/server/index.ts
/bluebubbles-server/src/server/types.ts
/bluebubbles-server/src/server/api/imessage
/bluebubbles-server/src/server/api/imessage/entity
/bluebubbles-server/src/server/api/imessage/transformers
/bluebubbles-server/src/server/api/imessage/listeners
/bluebubbles-server/src/fileSystem
/bluebubbles-server/src/fileSystem/scripts.ts
/bluebubbles-server/src/helpers
/bluebubbles-server/src/services/socket
/bluebubbles-server/src/services/fcm
/bluebubbles-server-ui/src//bluebubbles-server-ui/src/layouts
/bluebubbles-server-ui/src/containers
/bluebubbles-server-ui/src/components
/bluebubbles-server-ui/src/app.tsxadd-fcm-deviceget-chatsget-chat-messagesget-attachmentget-attachment-chunkget-last-chat-messagesend-messagestart-chatThis section will describe what information is returned back to the client from the server
This is the basic format of all responses
const ResponseFormat = {
status: ValidStatuses;
message: ResponseMessages | string;
error?: Error;
data?: ResponseData;
};
type ValidStatuses = 200 | 201 | 400 | 401 | 403 | 404 | 500;
enum ResponseMessages {
SUCCESS = 'Success',
BAD_REQUEST = 'Bad Request',
SERVER_ERROR = 'Server Error',
UNAUTHORIZED = 'Unauthorized',
FORBIDDEN = 'Forbidden',
NO_DATA = 'No Data'
};
type ResponseData =
MessageResponse |
HandleResponse |
ChatResponse |
AttachmentResponse |
(MessageResponse | HandleResponse | ChatResponse | AttachmentResponse)[] |
Uint8Array |
null;
Within each response container, there is an optional data key that contains any data that is returned by the server. That data includes different "views" from the database, whether it be chats, messages, etc.
type MessageResponse = {
guid: string;
text: string;
handle?: HandleResponse | null;
chats?: ChatResponse[];
attachments?: AttachmentResponse[];
subject: string;
country: string;
error: boolean;
dateCreated: number;
dateRead: number | null;
dateDelivered: number | null;
isFromMe: boolean;
isDelayed: boolean;
isAutoReply: boolean;
isSystemMessage: boolean;
isServiceMessage: boolean;
isForward: boolean;
isArchived: boolean;
cacheRoomnames: string | null;
isAudioMessage: boolean;
datePlayed: number | null;
itemType: number;
groupTitle: string | null;
isExpired: boolean;
associatedMessageGuid: string | null;
associatedMessageType: number | null;
expressiveSendStyleId: string | null;
timeExpressiveSendStyleId: number | null;
};
type ChatResponse = {
guid: string;
participants?: HandleResponse[];
messages?: MessageResponse[];
style: number;
chatIdentifier: string;
isArchived: boolean;
displayName: string;
groupId: string;
};
type HandleResponse = {
messages?: MessageResponse[];
chats?: ChatResponse[];
address: string;
country: string;
uncanonicalizedId: string
};
export type AttachmentResponse = {
guid: string;
messages: string[];
data: Uint8Array;
uti: string;
mimeType: string;
transferState: number;
totalBytes: number;
isOutgoing: boolean;
transferName: string;
isSticker: boolean;
hideAttachment: boolean;
};
This response is used when chunking attachments. It allows us to send the data for an attachment in chunks. These chunks can be concatenated together to form the actual attachment. This will allow us to send large attachments over slow connections, or just receiving large attachments over normal connections. We can also use chunking to show a status (progress bar) for receiving attachments
52,705 followers · starred Jan 2026
636 followers · starred Jul 2026
37 followers · starred Sep 2022
165 followers · starred Dec 2020
TypeScript
99.2%
Server for forwarding iMessages to clients within the BlueBubbles App ecosystem
See the codeThis is the back-end server for the BlueBubbles App. It allows you to forward your iMessages to and from an Android device via the BlueBubbles App.
Warning: Yarn may not work for this project. You may run into build errors.
git clone git@github.com:BlueBubblesApp/BlueBubbles-Server.gitcd BlueBubbles-Servernpm installnpm run startIf you are using macOS 10.x and are having issues building/running the server, please downgrade the node-mac-permissions dependency to v2.2.0. The reason it's on a newer version is to fix a production crashing issue on Big Sur+. Please downgrade it manually for testing on macOS v10.x.
cd packages/server
npm install node-mac-permissions@2.2.0
/bluebubbles-server/src//bluebubbles-server/src/server/index.ts
/bluebubbles-server/src/server/types.ts
/bluebubbles-server/src/server/api/imessage
/bluebubbles-server/src/server/api/imessage/entity
/bluebubbles-server/src/server/api/imessage/transformers
/bluebubbles-server/src/server/api/imessage/listeners
/bluebubbles-server/src/fileSystem
/bluebubbles-server/src/fileSystem/scripts.ts
/bluebubbles-server/src/helpers
/bluebubbles-server/src/services/socket
/bluebubbles-server/src/services/fcm
/bluebubbles-server-ui/src//bluebubbles-server-ui/src/layouts
/bluebubbles-server-ui/src/containers
/bluebubbles-server-ui/src/components
/bluebubbles-server-ui/src/app.tsxadd-fcm-deviceget-chatsget-chat-messagesget-attachmentget-attachment-chunkget-last-chat-messagesend-messagestart-chatThis section will describe what information is returned back to the client from the server
This is the basic format of all responses
const ResponseFormat = {
status: ValidStatuses;
message: ResponseMessages | string;
error?: Error;
data?: ResponseData;
};
type ValidStatuses = 200 | 201 | 400 | 401 | 403 | 404 | 500;
enum ResponseMessages {
SUCCESS = 'Success',
BAD_REQUEST = 'Bad Request',
SERVER_ERROR = 'Server Error',
UNAUTHORIZED = 'Unauthorized',
FORBIDDEN = 'Forbidden',
NO_DATA = 'No Data'
};
type ResponseData =
MessageResponse |
HandleResponse |
ChatResponse |
AttachmentResponse |
(MessageResponse | HandleResponse | ChatResponse | AttachmentResponse)[] |
Uint8Array |
null;
Within each response container, there is an optional data key that contains any data that is returned by the server. That data includes different "views" from the database, whether it be chats, messages, etc.
type MessageResponse = {
guid: string;
text: string;
handle?: HandleResponse | null;
chats?: ChatResponse[];
attachments?: AttachmentResponse[];
subject: string;
country: string;
error: boolean;
dateCreated: number;
dateRead: number | null;
dateDelivered: number | null;
isFromMe: boolean;
isDelayed: boolean;
isAutoReply: boolean;
isSystemMessage: boolean;
isServiceMessage: boolean;
isForward: boolean;
isArchived: boolean;
cacheRoomnames: string | null;
isAudioMessage: boolean;
datePlayed: number | null;
itemType: number;
groupTitle: string | null;
isExpired: boolean;
associatedMessageGuid: string | null;
associatedMessageType: number | null;
expressiveSendStyleId: string | null;
timeExpressiveSendStyleId: number | null;
};
type ChatResponse = {
guid: string;
participants?: HandleResponse[];
messages?: MessageResponse[];
style: number;
chatIdentifier: string;
isArchived: boolean;
displayName: string;
groupId: string;
};
type HandleResponse = {
messages?: MessageResponse[];
chats?: ChatResponse[];
address: string;
country: string;
uncanonicalizedId: string
};
export type AttachmentResponse = {
guid: string;
messages: string[];
data: Uint8Array;
uti: string;
mimeType: string;
transferState: number;
totalBytes: number;
isOutgoing: boolean;
transferName: string;
isSticker: boolean;
hideAttachment: boolean;
};
This response is used when chunking attachments. It allows us to send the data for an attachment in chunks. These chunks can be concatenated together to form the actual attachment. This will allow us to send large attachments over slow connections, or just receiving large attachments over normal connections. We can also use chunking to show a status (progress bar) for receiving attachments
52,705 followers · starred Jan 2026
636 followers · starred Jul 2026
37 followers · starred Sep 2022
165 followers · starred Dec 2020
TypeScript
99.2%