or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

constants.mdindex.mdmessage.mdsender.md

sender.mddocs/

0

# Message Sending

1

2

Message delivery system with FCM authentication, automatic retries, and comprehensive error handling for reliable push notification delivery. The Sender handles authentication, request formatting, response parsing, and retry logic.

3

4

## Capabilities

5

6

### Sender Constructor

7

8

Creates a new Sender instance with FCM server API key and optional configuration.

9

10

```javascript { .api }

11

/**

12

* Creates a new Sender instance

13

* @param {string} apiKey - FCM server API key

14

* @param {Object} options - Optional sender configuration

15

* @returns {Sender} Sender instance

16

*/

17

function Sender(apiKey, options);

18

19

// Can be called with or without 'new'

20

const sender1 = new Sender('YOUR_API_KEY');

21

const sender2 = Sender('YOUR_API_KEY', { timeout: 30000 });

22

```

23

24

**Usage Examples:**

25

26

```javascript

27

const gcm = require('node-gcm');

28

29

// Basic sender

30

const sender = new gcm.Sender('AIzaSyD...YOUR_FCM_SERVER_KEY');

31

32

// Sender with custom options

33

const sender = new gcm.Sender('AIzaSyD...YOUR_FCM_SERVER_KEY', {

34

timeout: 60000, // Custom timeout

35

proxy: 'http://proxy.example.com:8080' // HTTP proxy

36

});

37

```

38

39

### Send with Automatic Retries

40

41

Sends a message with automatic retry logic for failed deliveries.

42

43

```javascript { .api }

44

/**

45

* Send message with automatic retries and custom options

46

* @param {Message} message - Message instance to send

47

* @param {Recipient} recipient - Target recipient(s)

48

* @param {SendOptions|number} options - Send options or retry count

49

* @param {Function} callback - Callback function (err, response)

50

*/

51

sender.send(message, recipient, options, callback);

52

53

/**

54

* Send message with automatic retries using default options

55

* @param {Message} message - Message instance to send

56

* @param {Recipient} recipient - Target recipient(s)

57

* @param {Function} callback - Callback function (err, response)

58

*/

59

sender.send(message, recipient, callback);

60

61

/**

62

* Send message with specific retry count

63

* @param {Message} message - Message instance to send

64

* @param {Recipient} recipient - Target recipient(s)

65

* @param {number} retries - Number of retry attempts

66

* @param {Function} callback - Callback function (err, response)

67

*/

68

sender.send(message, recipient, retries, callback);

69

```

70

71

**Usage Examples:**

72

73

```javascript

74

const message = new gcm.Message({ data: { alert: 'Hello World' } });

75

const tokens = ['token1', 'token2', 'token3'];

76

77

// Send with default retry settings (5 retries)

78

sender.send(message, { registrationTokens: tokens }, function(err, response) {

79

if (err) {

80

console.error('Send failed:', err);

81

} else {

82

console.log('Send successful:', response);

83

// Handle failed tokens

84

const failedTokens = tokens.filter((token, i) =>

85

response.results[i].error === 'NotRegistered'

86

);

87

console.log('Failed tokens to remove:', failedTokens);

88

}

89

});

90

91

// Send with custom retry options

92

sender.send(message, { registrationTokens: tokens }, {

93

retries: 3,

94

backoff: 2000 // 2 second initial backoff

95

}, function(err, response) {

96

console.log('Send completed');

97

});

98

99

// Send with specific retry count

100

sender.send(message, { registrationTokens: tokens }, 10, function(err, response) {

101

console.log('Send with 10 retries completed');

102

});

103

```

104

105

### Send without Retries

106

107

Sends a message once without any retry logic.

108

109

```javascript { .api }

110

/**

111

* Send message without automatic retries

112

* @param {Message} message - Message instance to send

113

* @param {Recipient} recipient - Target recipient(s)

114

* @param {Function} callback - Callback function (err, response)

115

*/

116

sender.sendNoRetry(message, recipient, callback);

117

```

118

119

**Usage Example:**

120

121

```javascript

122

const message = new gcm.Message({

123

notification: { title: 'Test', body: 'Test message' }

124

});

125

126

sender.sendNoRetry(message, 'single_token_here', function(err, response) {

127

if (err) {

128

console.error('Send failed (no retries):', err);

129

} else {

130

console.log('Send successful:', response);

131

}

132

});

133

```

134

135

## Recipient Types

136

137

Different ways to specify message recipients.

138

139

### Single Registration Token

140

141

```javascript { .api }

142

// Send to a single device

143

const recipient = 'eHcE7r_bNzE:APA91bF...'; // Registration token string

144

sender.send(message, recipient, callback);

145

```

146

147

### Multiple Registration Tokens

148

149

```javascript { .api }

150

// Send to multiple devices (array format)

151

const recipients = ['token1', 'token2', 'token3']; // Max 1000 tokens

152

sender.send(message, recipients, callback);

153

154

// Send to multiple devices (object format)

155

const recipients = {

156

registrationTokens: ['token1', 'token2', 'token3']

157

};

158

sender.send(message, recipients, callback);

159

160

// Deprecated format (still supported)

161

const recipients = {

162

registrationIds: ['token1', 'token2', 'token3']

163

};

164

sender.send(message, recipients, callback);

165

```

166

167

### Topic Messaging

168

169

```javascript { .api }

170

// Send to a topic

171

const recipient = { topic: 'news' };

172

sender.send(message, recipient, callback);

173

174

// Alternative format

175

const recipient = '/topics/news';

176

sender.send(message, recipient, callback);

177

```

178

179

### Condition-based Messaging

180

181

```javascript { .api }

182

// Send based on topic conditions

183

const recipient = {

184

condition: "'sports' in topics && 'news' in topics"

185

};

186

sender.send(message, recipient, callback);

187

```

188

189

### Device Group Messaging

190

191

```javascript { .api }

192

// Send to device group (notification key)

193

const recipient = {

194

notificationKey: 'APA91bH...' // Device group key

195

};

196

sender.send(message, recipient, callback);

197

```

198

199

## Send Options

200

201

Configuration options for controlling retry behavior.

202

203

```javascript { .api }

204

interface SendOptions {

205

/** Number of retry attempts (default: 5) */

206

retries?: number;

207

208

/** Initial backoff delay in milliseconds (default: 1000) */

209

backoff?: number;

210

}

211

```

212

213

**Usage Examples:**

214

215

```javascript

216

// Custom retry configuration

217

const options = {

218

retries: 10, // Retry up to 10 times

219

backoff: 500 // Start with 500ms delay

220

};

221

222

sender.send(message, recipients, options, callback);

223

224

// Quick shorthand for just retry count

225

sender.send(message, recipients, 3, callback); // 3 retries

226

```

227

228

## Response Handling

229

230

Understanding FCM response structure for processing results.

231

232

### Success Response

233

234

```javascript { .api }

235

interface FCMResponse {

236

/** Unique identifier for the multicast message */

237

multicast_id?: number;

238

239

/** Number of successful deliveries */

240

success: number;

241

242

/** Number of failed deliveries */

243

failure: number;

244

245

/** Number of registration token updates */

246

canonical_ids: number;

247

248

/** Array of individual message results (matches recipient order) */

249

results: MessageResult[];

250

}

251

252

interface MessageResult {

253

/** Unique message identifier (on success) */

254

message_id?: string;

255

256

/** Updated registration token (if canonical_ids > 0) */

257

registration_id?: string;

258

259

/** Error code (on failure) */

260

error?: string;

261

}

262

```

263

264

### Error Handling

265

266

```javascript { .api }

267

// Common error codes in MessageResult.error:

268

// 'NotRegistered' - Token is no longer valid

269

// 'InvalidRegistration' - Token format is invalid

270

// 'MismatchSenderId' - Token doesn't match sender ID

271

// 'MessageTooBig' - Message payload exceeds size limit

272

// 'QuotaExceeded' - Sending quota exceeded

273

// 'Unavailable' - FCM service temporarily unavailable

274

// 'InternalServerError' - FCM internal error

275

276

// HTTP status codes passed to callback as error:

277

// 400 - Bad request (authentication, malformed request)

278

// 401 - Unauthorized (invalid API key)

279

// 5xx - Server errors (retry automatically handled)

280

```

281

282

**Response Processing Example:**

283

284

```javascript

285

sender.send(message, { registrationTokens: tokens }, function(err, response) {

286

if (err) {

287

if (err === 401) {

288

console.error('Authentication failed - check API key');

289

} else if (err >= 500) {

290

console.error('FCM server error:', err);

291

} else {

292

console.error('Send error:', err);

293

}

294

return;

295

}

296

297

console.log(`Sent to ${response.success} devices successfully`);

298

console.log(`Failed to send to ${response.failure} devices`);

299

console.log(`${response.canonical_ids} tokens need updating`);

300

301

// Process individual results

302

response.results.forEach((result, index) => {

303

const token = tokens[index];

304

305

if (result.message_id) {

306

console.log(`Success for token ${token}: ${result.message_id}`);

307

308

// Handle token updates

309

if (result.registration_id) {

310

console.log(`Update token ${token} to ${result.registration_id}`);

311

// Update token in your database

312

}

313

} else if (result.error) {

314

console.log(`Error for token ${token}: ${result.error}`);

315

316

// Handle specific errors

317

if (result.error === 'NotRegistered') {

318

console.log(`Remove invalid token: ${token}`);

319

// Remove token from your database

320

}

321

}

322

});

323

});

324

```

325

326

## Advanced Features

327

328

### Proxy Configuration

329

330

```javascript

331

const sender = new gcm.Sender('YOUR_API_KEY', {

332

proxy: 'http://proxy.company.com:8080',

333

timeout: 30000

334

});

335

```

336

337

### Custom Headers

338

339

```javascript

340

const sender = new gcm.Sender('YOUR_API_KEY', {

341

headers: {

342

'X-Custom-Header': 'custom-value'

343

}

344

});

345

```

346

347

### Debug Logging

348

349

Enable debug logging using the `DEBUG` environment variable:

350

351

```bash

352

DEBUG=node-gcm node your-app.js

353

```

354

355

## Important Notes

356

357

- **API Key**: Requires FCM server API key (Legacy API) - obtain from Firebase Console

358

- **Batch Limits**: Maximum 1000 registration tokens per request

359

- **Rate Limits**: Respect FCM rate limits to avoid quota exceeded errors

360

- **Token Management**: Monitor response results to update/remove invalid tokens

361

- **Retry Logic**: Failed requests are automatically retried with exponential backoff

362

- **Error Codes**: 4xx errors are not retried (permanent failures), 5xx errors are retried

363

- **Response Order**: Results array order matches recipient array order for token correlation