BlueBubblesApp / bluebubbles-server

Server for forwarding iMessages to clients within the BlueBubbles App ecosystem
https://bluebubbles.app
Apache License 2.0
508 stars 42 forks source link
bluebubbles electron imessage macos nodejs server typescript

BlueBubbles Server

This 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.

Pre-requisites

Warning: Yarn may not work for this project. You may run into build errors.

Development

  1. Clone the repository
    • git clone git@github.com:BlueBubblesApp/BlueBubbles-Server.git
  2. Navigate into the repository on your local machine
    • cd BlueBubbles-Server
  3. Install the server dependencies
    • npm install
  4. Run the dev server (this will start both the renderer and server)
    • npm run start

macOS Warning

If 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

Structure / Directory Map

Back-end

Front-end

Current Feature-set

Response Types

This section will describe what information is returned back to the client from the server

Response Container

This is the basic format of all responses

Response Format

const ResponseFormat = {
    status: ValidStatuses;
    message: ResponseMessages | string;
    error?: Error;
    data?: ResponseData;
};

Valid Statuses

type ValidStatuses = 200 | 201 | 400 | 401 | 403 | 404 | 500;

Response Messages

enum ResponseMessages {
    SUCCESS = 'Success',
    BAD_REQUEST = 'Bad Request',
    SERVER_ERROR = 'Server Error',
    UNAUTHORIZED = 'Unauthorized',
    FORBIDDEN = 'Forbidden',
    NO_DATA = 'No Data'
};

Response Data

type ResponseData =
    MessageResponse |
    HandleResponse |
    ChatResponse |
    AttachmentResponse |
    (MessageResponse | HandleResponse | ChatResponse | AttachmentResponse)[] |
    Uint8Array |
    null;

Response Data

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.

Message Response

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;
};

Chat Response

type ChatResponse = {
    guid: string;
    participants?: HandleResponse[];
    messages?: MessageResponse[];
    style: number;
    chatIdentifier: string;
    isArchived: boolean;
    displayName: string;
    groupId: string;
};

Handle Response

type HandleResponse = {
    messages?: MessageResponse[];
    chats?: ChatResponse[];
    address: string;
    country: string;
    uncanonicalizedId: string
};

Attachment Response

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;
};

UInt8Array Response

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