n8n-nodes-gmail-custom 0.2.1 → 0.3.0

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.
@@ -161,19 +161,19 @@ async function buildMimeMessage(options) {
161
161
  .replace(/=+$/, '');
162
162
  }
163
163
 
164
- async function getOrRefreshAccessToken(ctx, credentials, fromEmail) {
165
- const cacheKey = `${credentials.email}:${fromEmail}`;
164
+ async function getOrRefreshAccessToken(ctx, serviceAccountEmail, privateKeyRaw, fromEmail) {
165
+ const cacheKey = `${serviceAccountEmail}:${fromEmail}`;
166
166
  let token = TOKEN_CACHE[cacheKey];
167
167
  if (token && token.expiresAt > Date.now()) {
168
168
  return token.accessToken;
169
169
  }
170
170
 
171
- const privateKey = formatPrivateKey(credentials.privateKey);
171
+ const privateKey = formatPrivateKey(privateKeyRaw);
172
172
  const now = Math.floor(Date.now() / 1000);
173
173
 
174
174
  let jwt;
175
175
  const payload = {
176
- iss: credentials.email,
176
+ iss: serviceAccountEmail,
177
177
  scope: 'https://mail.google.com/',
178
178
  aud: 'https://oauth2.googleapis.com/token',
179
179
  exp: now + 3600,
@@ -230,13 +230,25 @@ class GmailCustom {
230
230
  },
231
231
  inputs: ['main'],
232
232
  outputs: ['main'],
233
- credentials: [
233
+ properties: [
234
234
  {
235
- name: 'googleApi',
235
+ displayName: 'Service Account Email',
236
+ name: 'serviceAccountEmail',
237
+ type: 'string',
238
+ default: '',
236
239
  required: true,
240
+ placeholder: 'sa-name@project.iam.gserviceaccount.com',
241
+ description: 'The service account client_email (issuer for JWT)',
242
+ },
243
+ {
244
+ displayName: 'Private Key',
245
+ name: 'privateKey',
246
+ type: 'string',
247
+ typeOptions: { password: true },
248
+ default: '',
249
+ required: true,
250
+ description: 'The service account RSA private key in PEM format',
237
251
  },
238
- ],
239
- properties: [
240
252
  {
241
253
  displayName: 'From Email',
242
254
  name: 'fromEmail',
@@ -343,6 +355,14 @@ class GmailCustom {
343
355
  default: '',
344
356
  description: 'The email address that the reply message is sent to',
345
357
  },
358
+ {
359
+ displayName: 'Sender Name',
360
+ name: 'senderName',
361
+ type: 'string',
362
+ default: '',
363
+ placeholder: 'e.g. John Doe',
364
+ description: 'Name shown as the sender in recipients\' inboxes',
365
+ },
346
366
  ],
347
367
  },
348
368
  ],
@@ -360,6 +380,8 @@ class GmailCustom {
360
380
  for (let i = 0; i < items.length; i++) {
361
381
  try {
362
382
  const item = items[i];
383
+ const serviceAccountEmail = this.getNodeParameter('serviceAccountEmail', i, '');
384
+ const privateKey = this.getNodeParameter('privateKey', i, '');
363
385
  const fromEmail = this.getNodeParameter('fromEmail', i, '');
364
386
  const sendTo = this.getNodeParameter('sendTo', i, '');
365
387
  const subject = this.getNodeParameter('subject', i, '');
@@ -375,6 +397,12 @@ class GmailCustom {
375
397
  let cc = options.ccList || '';
376
398
  let bcc = options.bccList || '';
377
399
  let replyTo = options.replyTo || '';
400
+ const senderName = options.senderName || '';
401
+
402
+ let fromHeader = fromEmail;
403
+ if (senderName) {
404
+ fromHeader = `${senderName} <${fromEmail}>`;
405
+ }
378
406
 
379
407
  let bodyText = message;
380
408
  let bodyHtml = '';
@@ -387,8 +415,7 @@ class GmailCustom {
387
415
  bodyText = message;
388
416
  }
389
417
 
390
- const credentials = await this.getCredentials('googleApi');
391
- const accessToken = await getOrRefreshAccessToken(this, credentials, fromEmail);
418
+ const accessToken = await getOrRefreshAccessToken(this, serviceAccountEmail, privateKey, fromEmail);
392
419
 
393
420
  let attachments = [];
394
421
  if (options.attachmentsUi && options.attachmentsUi.attachmentsBinary) {
@@ -414,7 +441,7 @@ class GmailCustom {
414
441
  }
415
442
 
416
443
  const base64UrlMessage = await buildMimeMessage({
417
- from: fromEmail,
444
+ from: fromHeader,
418
445
  to: sendTo,
419
446
  cc,
420
447
  bcc,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-gmail-custom",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "Custom Gmail node for n8n with token caching and 429 retry",
5
5
  "keywords": [
6
6
  "n8n-community-node-package",