happy-coder 0.6.0 → 0.6.2
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/index.cjs +89 -4
- package/dist/index.mjs +89 -4
- package/dist/lib.cjs +1 -1
- package/dist/lib.mjs +1 -1
- package/dist/{types-Cqy5Dx2C.mjs → types-DKVMGtcN.mjs} +24 -9
- package/dist/{types-Bkw2UUhb.cjs → types-iMUxaPkI.cjs} +24 -9
- package/package.json +1 -1
- package/scripts/claude_local_launcher.cjs +3 -0
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var chalk = require('chalk');
|
|
4
|
-
var types$1 = require('./types-
|
|
4
|
+
var types$1 = require('./types-iMUxaPkI.cjs');
|
|
5
5
|
var node_crypto = require('node:crypto');
|
|
6
6
|
var node_child_process = require('node:child_process');
|
|
7
7
|
var node_path = require('node:path');
|
|
@@ -2262,7 +2262,7 @@ async function loop(opts) {
|
|
|
2262
2262
|
}
|
|
2263
2263
|
|
|
2264
2264
|
var name = "happy-coder";
|
|
2265
|
-
var version = "0.6.
|
|
2265
|
+
var version = "0.6.2";
|
|
2266
2266
|
var description = "Claude Code session sharing CLI";
|
|
2267
2267
|
var author = "Kirill Dubovitskiy";
|
|
2268
2268
|
var license = "MIT";
|
|
@@ -3087,6 +3087,10 @@ async function start(credentials, options = {}) {
|
|
|
3087
3087
|
const logPath = await types$1.logger.logFilePathPromise;
|
|
3088
3088
|
types$1.logger.infoDeveloper(`Session: ${response.id}`);
|
|
3089
3089
|
types$1.logger.infoDeveloper(`Logs: ${logPath}`);
|
|
3090
|
+
session.updateAgentState((currentState) => ({
|
|
3091
|
+
...currentState,
|
|
3092
|
+
controlledByUser: options.startingMode === "local"
|
|
3093
|
+
}));
|
|
3090
3094
|
const caffeinateStarted = startCaffeinate();
|
|
3091
3095
|
if (caffeinateStarted) {
|
|
3092
3096
|
types$1.logger.infoDeveloper("Sleep prevention enabled (macOS)");
|
|
@@ -3185,7 +3189,7 @@ async function start(credentials, options = {}) {
|
|
|
3185
3189
|
session.sendSessionEvent({ type: "switch", mode: newMode });
|
|
3186
3190
|
session.updateAgentState((currentState) => ({
|
|
3187
3191
|
...currentState,
|
|
3188
|
-
controlledByUser:
|
|
3192
|
+
controlledByUser: newMode === "local"
|
|
3189
3193
|
}));
|
|
3190
3194
|
},
|
|
3191
3195
|
mcpServers: {},
|
|
@@ -3656,7 +3660,7 @@ class ApiDaemonSession extends node_events.EventEmitter {
|
|
|
3656
3660
|
};
|
|
3657
3661
|
const encrypted = types$1.encrypt(JSON.stringify(metadata), this.secret);
|
|
3658
3662
|
const encryptedMetadata = types$1.encodeBase64(encrypted);
|
|
3659
|
-
this.socket.emit("update-machine
|
|
3663
|
+
this.socket.emit("update-machine", { metadata: encryptedMetadata });
|
|
3660
3664
|
}
|
|
3661
3665
|
shutdown() {
|
|
3662
3666
|
types$1.logger.debug(`[DAEMON SESSION] Shutting down daemon, killing ${this.spawnedProcesses.size} spawned processes`);
|
|
@@ -4090,6 +4094,17 @@ async function uninstall() {
|
|
|
4090
4094
|
process.exit(1);
|
|
4091
4095
|
}
|
|
4092
4096
|
return;
|
|
4097
|
+
} else if (subcommand === "notify") {
|
|
4098
|
+
try {
|
|
4099
|
+
await handleNotifyCommand(args.slice(1));
|
|
4100
|
+
} catch (error) {
|
|
4101
|
+
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
4102
|
+
if (process.env.DEBUG) {
|
|
4103
|
+
console.error(error);
|
|
4104
|
+
}
|
|
4105
|
+
process.exit(1);
|
|
4106
|
+
}
|
|
4107
|
+
return;
|
|
4093
4108
|
} else if (subcommand === "daemon") {
|
|
4094
4109
|
const daemonSubcommand = args[1];
|
|
4095
4110
|
if (daemonSubcommand === "start") {
|
|
@@ -4170,6 +4185,7 @@ ${chalk.bold("happy")} - Claude Code On the Go
|
|
|
4170
4185
|
|
|
4171
4186
|
${chalk.bold("Usage:")}
|
|
4172
4187
|
happy [options]
|
|
4188
|
+
happy notify Send notification
|
|
4173
4189
|
happy logout Logs out of your account and removes data directory
|
|
4174
4190
|
happy daemon Manage the background daemon (macOS only)
|
|
4175
4191
|
|
|
@@ -4202,6 +4218,7 @@ ${chalk.bold("Examples:")}
|
|
|
4202
4218
|
happy -m opus Use Claude Opus model
|
|
4203
4219
|
happy -p plan Use plan permission mode
|
|
4204
4220
|
happy --auth Force re-authentication before starting session
|
|
4221
|
+
happy notify -p "Hello!" Send notification
|
|
4205
4222
|
happy --claude-env KEY=VALUE
|
|
4206
4223
|
Set environment variable for Claude Code
|
|
4207
4224
|
happy --claude-arg --option
|
|
@@ -4316,3 +4333,71 @@ async function cleanKey() {
|
|
|
4316
4333
|
console.log(chalk.blue("Operation cancelled"));
|
|
4317
4334
|
}
|
|
4318
4335
|
}
|
|
4336
|
+
async function handleNotifyCommand(args) {
|
|
4337
|
+
let message = "";
|
|
4338
|
+
let title = "";
|
|
4339
|
+
let showHelp = false;
|
|
4340
|
+
for (let i = 0; i < args.length; i++) {
|
|
4341
|
+
const arg = args[i];
|
|
4342
|
+
if (arg === "-p" && i + 1 < args.length) {
|
|
4343
|
+
message = args[++i];
|
|
4344
|
+
} else if (arg === "-t" && i + 1 < args.length) {
|
|
4345
|
+
title = args[++i];
|
|
4346
|
+
} else if (arg === "-h" || arg === "--help") {
|
|
4347
|
+
showHelp = true;
|
|
4348
|
+
} else {
|
|
4349
|
+
console.error(chalk.red(`Unknown argument for notify command: ${arg}`));
|
|
4350
|
+
process.exit(1);
|
|
4351
|
+
}
|
|
4352
|
+
}
|
|
4353
|
+
if (showHelp) {
|
|
4354
|
+
console.log(`
|
|
4355
|
+
${chalk.bold("happy notify")} - Send notification
|
|
4356
|
+
|
|
4357
|
+
${chalk.bold("Usage:")}
|
|
4358
|
+
happy notify -p <message> [-t <title>] Send notification with custom message and optional title
|
|
4359
|
+
happy notify -h, --help Show this help
|
|
4360
|
+
|
|
4361
|
+
${chalk.bold("Options:")}
|
|
4362
|
+
-p <message> Notification message (required)
|
|
4363
|
+
-t <title> Notification title (optional, defaults to "Happy")
|
|
4364
|
+
|
|
4365
|
+
${chalk.bold("Examples:")}
|
|
4366
|
+
happy notify -p "Deployment complete!"
|
|
4367
|
+
happy notify -p "System update complete" -t "Server Status"
|
|
4368
|
+
happy notify -t "Alert" -p "Database connection restored"
|
|
4369
|
+
`);
|
|
4370
|
+
return;
|
|
4371
|
+
}
|
|
4372
|
+
if (!message) {
|
|
4373
|
+
console.error(chalk.red('Error: Message is required. Use -p "your message" to specify the notification text.'));
|
|
4374
|
+
console.log(chalk.gray('Run "happy notify --help" for usage information.'));
|
|
4375
|
+
process.exit(1);
|
|
4376
|
+
}
|
|
4377
|
+
let credentials = await readCredentials();
|
|
4378
|
+
if (!credentials) {
|
|
4379
|
+
console.error(chalk.red('Error: Not authenticated. Please run "happy --auth" first.'));
|
|
4380
|
+
process.exit(1);
|
|
4381
|
+
}
|
|
4382
|
+
console.log(chalk.blue("\u{1F4F1} Sending push notification..."));
|
|
4383
|
+
try {
|
|
4384
|
+
const api = new types$1.ApiClient(credentials.token, credentials.secret);
|
|
4385
|
+
const notificationTitle = title || "Happy";
|
|
4386
|
+
api.push().sendToAllDevices(
|
|
4387
|
+
notificationTitle,
|
|
4388
|
+
message,
|
|
4389
|
+
{
|
|
4390
|
+
source: "cli",
|
|
4391
|
+
timestamp: Date.now()
|
|
4392
|
+
}
|
|
4393
|
+
);
|
|
4394
|
+
console.log(chalk.green("\u2713 Push notification sent successfully!"));
|
|
4395
|
+
console.log(chalk.gray(` Title: ${notificationTitle}`));
|
|
4396
|
+
console.log(chalk.gray(` Message: ${message}`));
|
|
4397
|
+
console.log(chalk.gray(" Check your mobile device for the notification."));
|
|
4398
|
+
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
4399
|
+
} catch (error) {
|
|
4400
|
+
console.error(chalk.red("\u2717 Failed to send push notification"));
|
|
4401
|
+
throw error;
|
|
4402
|
+
}
|
|
4403
|
+
}
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
-
import { l as logger, d as backoff, e as delay, R as RawJSONLinesSchema, c as configuration, f as encodeBase64, A as ApiClient, g as encodeBase64Url, h as decodeBase64, j as encrypt, b as initializeConfiguration, i as initLoggerWithGlobalConfiguration } from './types-
|
|
2
|
+
import { l as logger, d as backoff, e as delay, R as RawJSONLinesSchema, c as configuration, f as encodeBase64, A as ApiClient, g as encodeBase64Url, h as decodeBase64, j as encrypt, b as initializeConfiguration, i as initLoggerWithGlobalConfiguration } from './types-DKVMGtcN.mjs';
|
|
3
3
|
import { randomUUID, randomBytes } from 'node:crypto';
|
|
4
4
|
import { spawn, execSync } from 'node:child_process';
|
|
5
5
|
import { resolve, join, dirname as dirname$1 } from 'node:path';
|
|
@@ -2241,7 +2241,7 @@ async function loop(opts) {
|
|
|
2241
2241
|
}
|
|
2242
2242
|
|
|
2243
2243
|
var name = "happy-coder";
|
|
2244
|
-
var version = "0.6.
|
|
2244
|
+
var version = "0.6.2";
|
|
2245
2245
|
var description = "Claude Code session sharing CLI";
|
|
2246
2246
|
var author = "Kirill Dubovitskiy";
|
|
2247
2247
|
var license = "MIT";
|
|
@@ -3066,6 +3066,10 @@ async function start(credentials, options = {}) {
|
|
|
3066
3066
|
const logPath = await logger.logFilePathPromise;
|
|
3067
3067
|
logger.infoDeveloper(`Session: ${response.id}`);
|
|
3068
3068
|
logger.infoDeveloper(`Logs: ${logPath}`);
|
|
3069
|
+
session.updateAgentState((currentState) => ({
|
|
3070
|
+
...currentState,
|
|
3071
|
+
controlledByUser: options.startingMode === "local"
|
|
3072
|
+
}));
|
|
3069
3073
|
const caffeinateStarted = startCaffeinate();
|
|
3070
3074
|
if (caffeinateStarted) {
|
|
3071
3075
|
logger.infoDeveloper("Sleep prevention enabled (macOS)");
|
|
@@ -3164,7 +3168,7 @@ async function start(credentials, options = {}) {
|
|
|
3164
3168
|
session.sendSessionEvent({ type: "switch", mode: newMode });
|
|
3165
3169
|
session.updateAgentState((currentState) => ({
|
|
3166
3170
|
...currentState,
|
|
3167
|
-
controlledByUser:
|
|
3171
|
+
controlledByUser: newMode === "local"
|
|
3168
3172
|
}));
|
|
3169
3173
|
},
|
|
3170
3174
|
mcpServers: {},
|
|
@@ -3635,7 +3639,7 @@ class ApiDaemonSession extends EventEmitter {
|
|
|
3635
3639
|
};
|
|
3636
3640
|
const encrypted = encrypt(JSON.stringify(metadata), this.secret);
|
|
3637
3641
|
const encryptedMetadata = encodeBase64(encrypted);
|
|
3638
|
-
this.socket.emit("update-machine
|
|
3642
|
+
this.socket.emit("update-machine", { metadata: encryptedMetadata });
|
|
3639
3643
|
}
|
|
3640
3644
|
shutdown() {
|
|
3641
3645
|
logger.debug(`[DAEMON SESSION] Shutting down daemon, killing ${this.spawnedProcesses.size} spawned processes`);
|
|
@@ -4069,6 +4073,17 @@ async function uninstall() {
|
|
|
4069
4073
|
process.exit(1);
|
|
4070
4074
|
}
|
|
4071
4075
|
return;
|
|
4076
|
+
} else if (subcommand === "notify") {
|
|
4077
|
+
try {
|
|
4078
|
+
await handleNotifyCommand(args.slice(1));
|
|
4079
|
+
} catch (error) {
|
|
4080
|
+
console.error(chalk.red("Error:"), error instanceof Error ? error.message : "Unknown error");
|
|
4081
|
+
if (process.env.DEBUG) {
|
|
4082
|
+
console.error(error);
|
|
4083
|
+
}
|
|
4084
|
+
process.exit(1);
|
|
4085
|
+
}
|
|
4086
|
+
return;
|
|
4072
4087
|
} else if (subcommand === "daemon") {
|
|
4073
4088
|
const daemonSubcommand = args[1];
|
|
4074
4089
|
if (daemonSubcommand === "start") {
|
|
@@ -4149,6 +4164,7 @@ ${chalk.bold("happy")} - Claude Code On the Go
|
|
|
4149
4164
|
|
|
4150
4165
|
${chalk.bold("Usage:")}
|
|
4151
4166
|
happy [options]
|
|
4167
|
+
happy notify Send notification
|
|
4152
4168
|
happy logout Logs out of your account and removes data directory
|
|
4153
4169
|
happy daemon Manage the background daemon (macOS only)
|
|
4154
4170
|
|
|
@@ -4181,6 +4197,7 @@ ${chalk.bold("Examples:")}
|
|
|
4181
4197
|
happy -m opus Use Claude Opus model
|
|
4182
4198
|
happy -p plan Use plan permission mode
|
|
4183
4199
|
happy --auth Force re-authentication before starting session
|
|
4200
|
+
happy notify -p "Hello!" Send notification
|
|
4184
4201
|
happy --claude-env KEY=VALUE
|
|
4185
4202
|
Set environment variable for Claude Code
|
|
4186
4203
|
happy --claude-arg --option
|
|
@@ -4295,3 +4312,71 @@ async function cleanKey() {
|
|
|
4295
4312
|
console.log(chalk.blue("Operation cancelled"));
|
|
4296
4313
|
}
|
|
4297
4314
|
}
|
|
4315
|
+
async function handleNotifyCommand(args) {
|
|
4316
|
+
let message = "";
|
|
4317
|
+
let title = "";
|
|
4318
|
+
let showHelp = false;
|
|
4319
|
+
for (let i = 0; i < args.length; i++) {
|
|
4320
|
+
const arg = args[i];
|
|
4321
|
+
if (arg === "-p" && i + 1 < args.length) {
|
|
4322
|
+
message = args[++i];
|
|
4323
|
+
} else if (arg === "-t" && i + 1 < args.length) {
|
|
4324
|
+
title = args[++i];
|
|
4325
|
+
} else if (arg === "-h" || arg === "--help") {
|
|
4326
|
+
showHelp = true;
|
|
4327
|
+
} else {
|
|
4328
|
+
console.error(chalk.red(`Unknown argument for notify command: ${arg}`));
|
|
4329
|
+
process.exit(1);
|
|
4330
|
+
}
|
|
4331
|
+
}
|
|
4332
|
+
if (showHelp) {
|
|
4333
|
+
console.log(`
|
|
4334
|
+
${chalk.bold("happy notify")} - Send notification
|
|
4335
|
+
|
|
4336
|
+
${chalk.bold("Usage:")}
|
|
4337
|
+
happy notify -p <message> [-t <title>] Send notification with custom message and optional title
|
|
4338
|
+
happy notify -h, --help Show this help
|
|
4339
|
+
|
|
4340
|
+
${chalk.bold("Options:")}
|
|
4341
|
+
-p <message> Notification message (required)
|
|
4342
|
+
-t <title> Notification title (optional, defaults to "Happy")
|
|
4343
|
+
|
|
4344
|
+
${chalk.bold("Examples:")}
|
|
4345
|
+
happy notify -p "Deployment complete!"
|
|
4346
|
+
happy notify -p "System update complete" -t "Server Status"
|
|
4347
|
+
happy notify -t "Alert" -p "Database connection restored"
|
|
4348
|
+
`);
|
|
4349
|
+
return;
|
|
4350
|
+
}
|
|
4351
|
+
if (!message) {
|
|
4352
|
+
console.error(chalk.red('Error: Message is required. Use -p "your message" to specify the notification text.'));
|
|
4353
|
+
console.log(chalk.gray('Run "happy notify --help" for usage information.'));
|
|
4354
|
+
process.exit(1);
|
|
4355
|
+
}
|
|
4356
|
+
let credentials = await readCredentials();
|
|
4357
|
+
if (!credentials) {
|
|
4358
|
+
console.error(chalk.red('Error: Not authenticated. Please run "happy --auth" first.'));
|
|
4359
|
+
process.exit(1);
|
|
4360
|
+
}
|
|
4361
|
+
console.log(chalk.blue("\u{1F4F1} Sending push notification..."));
|
|
4362
|
+
try {
|
|
4363
|
+
const api = new ApiClient(credentials.token, credentials.secret);
|
|
4364
|
+
const notificationTitle = title || "Happy";
|
|
4365
|
+
api.push().sendToAllDevices(
|
|
4366
|
+
notificationTitle,
|
|
4367
|
+
message,
|
|
4368
|
+
{
|
|
4369
|
+
source: "cli",
|
|
4370
|
+
timestamp: Date.now()
|
|
4371
|
+
}
|
|
4372
|
+
);
|
|
4373
|
+
console.log(chalk.green("\u2713 Push notification sent successfully!"));
|
|
4374
|
+
console.log(chalk.gray(` Title: ${notificationTitle}`));
|
|
4375
|
+
console.log(chalk.gray(` Message: ${message}`));
|
|
4376
|
+
console.log(chalk.gray(" Check your mobile device for the notification."));
|
|
4377
|
+
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
4378
|
+
} catch (error) {
|
|
4379
|
+
console.error(chalk.red("\u2717 Failed to send push notification"));
|
|
4380
|
+
throw error;
|
|
4381
|
+
}
|
|
4382
|
+
}
|
package/dist/lib.cjs
CHANGED
package/dist/lib.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as ApiClient, a as ApiSessionClient, R as RawJSONLinesSchema, c as configuration, i as initLoggerWithGlobalConfiguration, b as initializeConfiguration, l as logger } from './types-
|
|
1
|
+
export { A as ApiClient, a as ApiSessionClient, R as RawJSONLinesSchema, c as configuration, i as initLoggerWithGlobalConfiguration, b as initializeConfiguration, l as logger } from './types-DKVMGtcN.mjs';
|
|
2
2
|
import 'axios';
|
|
3
3
|
import 'chalk';
|
|
4
4
|
import 'fs';
|
|
@@ -692,6 +692,9 @@ class PushNotificationClient {
|
|
|
692
692
|
}
|
|
693
693
|
);
|
|
694
694
|
logger.debug(`Fetched ${response.data.tokens.length} push tokens`);
|
|
695
|
+
response.data.tokens.forEach((token, index) => {
|
|
696
|
+
logger.debug(`[PUSH] Token ${index + 1}: id=${token.id}, token=${token.token}, created=${new Date(token.createdAt).toISOString()}, updated=${new Date(token.updatedAt).toISOString()}`);
|
|
697
|
+
});
|
|
695
698
|
return response.data.tokens;
|
|
696
699
|
} catch (error) {
|
|
697
700
|
logger.debug("[PUSH] [ERROR] Failed to fetch push tokens:", error);
|
|
@@ -724,7 +727,8 @@ class PushNotificationClient {
|
|
|
724
727
|
const ticketChunk = await this.expo.sendPushNotificationsAsync(chunk);
|
|
725
728
|
const errors = ticketChunk.filter((ticket) => ticket.status === "error");
|
|
726
729
|
if (errors.length > 0) {
|
|
727
|
-
|
|
730
|
+
const errorDetails = errors.map((e) => ({ message: e.message, details: e.details }));
|
|
731
|
+
logger.debug("[PUSH] Some notifications failed:", errorDetails);
|
|
728
732
|
}
|
|
729
733
|
if (errors.length === ticketChunk.length) {
|
|
730
734
|
throw new Error("All push notifications in chunk failed");
|
|
@@ -756,22 +760,33 @@ class PushNotificationClient {
|
|
|
756
760
|
* @param data - Additional data to send with the notification
|
|
757
761
|
*/
|
|
758
762
|
sendToAllDevices(title, body, data) {
|
|
763
|
+
logger.debug(`[PUSH] sendToAllDevices called with title: "${title}", body: "${body}"`);
|
|
759
764
|
(async () => {
|
|
760
765
|
try {
|
|
766
|
+
logger.debug("[PUSH] Fetching push tokens...");
|
|
761
767
|
const tokens = await this.fetchPushTokens();
|
|
768
|
+
logger.debug(`[PUSH] Fetched ${tokens.length} push tokens`);
|
|
769
|
+
tokens.forEach((token, index) => {
|
|
770
|
+
logger.debug(`[PUSH] Using token ${index + 1}: id=${token.id}, token=${token.token}`);
|
|
771
|
+
});
|
|
762
772
|
if (tokens.length === 0) {
|
|
763
773
|
logger.debug("No push tokens found for user");
|
|
764
774
|
return;
|
|
765
775
|
}
|
|
766
|
-
const messages = tokens.map((token) =>
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
776
|
+
const messages = tokens.map((token, index) => {
|
|
777
|
+
logger.debug(`[PUSH] Creating message ${index + 1} for token: ${token.token}`);
|
|
778
|
+
return {
|
|
779
|
+
to: token.token,
|
|
780
|
+
title,
|
|
781
|
+
body,
|
|
782
|
+
data,
|
|
783
|
+
sound: "default",
|
|
784
|
+
priority: "high"
|
|
785
|
+
};
|
|
786
|
+
});
|
|
787
|
+
logger.debug(`[PUSH] Sending ${messages.length} push notifications...`);
|
|
774
788
|
await this.sendPushNotifications(messages);
|
|
789
|
+
logger.debug("[PUSH] Push notifications sent successfully");
|
|
775
790
|
} catch (error) {
|
|
776
791
|
logger.debug("[PUSH] Error sending to all devices:", error);
|
|
777
792
|
}
|
|
@@ -694,6 +694,9 @@ class PushNotificationClient {
|
|
|
694
694
|
}
|
|
695
695
|
);
|
|
696
696
|
exports.logger.debug(`Fetched ${response.data.tokens.length} push tokens`);
|
|
697
|
+
response.data.tokens.forEach((token, index) => {
|
|
698
|
+
exports.logger.debug(`[PUSH] Token ${index + 1}: id=${token.id}, token=${token.token}, created=${new Date(token.createdAt).toISOString()}, updated=${new Date(token.updatedAt).toISOString()}`);
|
|
699
|
+
});
|
|
697
700
|
return response.data.tokens;
|
|
698
701
|
} catch (error) {
|
|
699
702
|
exports.logger.debug("[PUSH] [ERROR] Failed to fetch push tokens:", error);
|
|
@@ -726,7 +729,8 @@ class PushNotificationClient {
|
|
|
726
729
|
const ticketChunk = await this.expo.sendPushNotificationsAsync(chunk);
|
|
727
730
|
const errors = ticketChunk.filter((ticket) => ticket.status === "error");
|
|
728
731
|
if (errors.length > 0) {
|
|
729
|
-
|
|
732
|
+
const errorDetails = errors.map((e) => ({ message: e.message, details: e.details }));
|
|
733
|
+
exports.logger.debug("[PUSH] Some notifications failed:", errorDetails);
|
|
730
734
|
}
|
|
731
735
|
if (errors.length === ticketChunk.length) {
|
|
732
736
|
throw new Error("All push notifications in chunk failed");
|
|
@@ -758,22 +762,33 @@ class PushNotificationClient {
|
|
|
758
762
|
* @param data - Additional data to send with the notification
|
|
759
763
|
*/
|
|
760
764
|
sendToAllDevices(title, body, data) {
|
|
765
|
+
exports.logger.debug(`[PUSH] sendToAllDevices called with title: "${title}", body: "${body}"`);
|
|
761
766
|
(async () => {
|
|
762
767
|
try {
|
|
768
|
+
exports.logger.debug("[PUSH] Fetching push tokens...");
|
|
763
769
|
const tokens = await this.fetchPushTokens();
|
|
770
|
+
exports.logger.debug(`[PUSH] Fetched ${tokens.length} push tokens`);
|
|
771
|
+
tokens.forEach((token, index) => {
|
|
772
|
+
exports.logger.debug(`[PUSH] Using token ${index + 1}: id=${token.id}, token=${token.token}`);
|
|
773
|
+
});
|
|
764
774
|
if (tokens.length === 0) {
|
|
765
775
|
exports.logger.debug("No push tokens found for user");
|
|
766
776
|
return;
|
|
767
777
|
}
|
|
768
|
-
const messages = tokens.map((token) =>
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
778
|
+
const messages = tokens.map((token, index) => {
|
|
779
|
+
exports.logger.debug(`[PUSH] Creating message ${index + 1} for token: ${token.token}`);
|
|
780
|
+
return {
|
|
781
|
+
to: token.token,
|
|
782
|
+
title,
|
|
783
|
+
body,
|
|
784
|
+
data,
|
|
785
|
+
sound: "default",
|
|
786
|
+
priority: "high"
|
|
787
|
+
};
|
|
788
|
+
});
|
|
789
|
+
exports.logger.debug(`[PUSH] Sending ${messages.length} push notifications...`);
|
|
776
790
|
await this.sendPushNotifications(messages);
|
|
791
|
+
exports.logger.debug("[PUSH] Push notifications sent successfully");
|
|
777
792
|
} catch (error) {
|
|
778
793
|
exports.logger.debug("[PUSH] Error sending to all devices:", error);
|
|
779
794
|
}
|
package/package.json
CHANGED