Skip to content

Commit f8703e0

Browse files
committed
feat: finalized plugs
1 parent 7ca7a14 commit f8703e0

File tree

4 files changed

+151
-9
lines changed

4 files changed

+151
-9
lines changed

libraries/nestjs-libraries/src/database/prisma/posts/posts.service.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -342,12 +342,12 @@ export class PostsService {
342342
this._workerServiceProducer.emit('plugs', {
343343
id: 'plug_' + postId + '_' + runPlug.identifier,
344344
options: {
345-
delay: 0, // runPlug.runEveryMilliseconds,
345+
delay: runPlug.runEveryMilliseconds,
346346
},
347347
payload: {
348348
plugId: plug.id,
349349
postId,
350-
delay: 0, // runPlug.runEveryMilliseconds,
350+
delay: runPlug.runEveryMilliseconds,
351351
totalRuns: runPlug.totalRuns,
352352
currentRun: 1,
353353
},

libraries/nestjs-libraries/src/integrations/social/linkedin.page.provider.ts

+73
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,79 @@ export class LinkedinPageProvider
433433

434434
return false;
435435
}
436+
437+
@Plug({
438+
identifier: 'linkedin-page-autoPlugPost',
439+
title: 'Auto plug post',
440+
description:
441+
'When a post reached a certain number of likes, add another post to it so you followers get a notification about your promotion',
442+
runEveryMilliseconds: 21600000,
443+
totalRuns: 3,
444+
fields: [
445+
{
446+
name: 'likesAmount',
447+
type: 'number',
448+
placeholder: 'Amount of likes',
449+
description: 'The amount of likes to trigger the repost',
450+
validation: /^\d+$/,
451+
},
452+
{
453+
name: 'post',
454+
type: 'richtext',
455+
placeholder: 'Post to plug',
456+
description: 'Message content to plug',
457+
validation: /^[\s\S]{3,}$/g,
458+
},
459+
],
460+
})
461+
async autoPlugPost(
462+
integration: Integration,
463+
id: string,
464+
fields: { likesAmount: string; post: string }
465+
) {
466+
const {
467+
likesSummary: { totalLikes },
468+
} = await (
469+
await this.fetch(
470+
`https://api.linkedin.com/v2/socialActions/${encodeURIComponent(id)}`,
471+
{
472+
method: 'GET',
473+
headers: {
474+
'X-Restli-Protocol-Version': '2.0.0',
475+
'Content-Type': 'application/json',
476+
'LinkedIn-Version': '202402',
477+
Authorization: `Bearer ${integration.token}`,
478+
},
479+
}
480+
)
481+
).json();
482+
483+
if (totalLikes >= fields.likesAmount) {
484+
await timer(2000);
485+
await this.fetch(
486+
`https://api.linkedin.com/v2/socialActions/${decodeURIComponent(
487+
id
488+
)}/comments`,
489+
{
490+
method: 'POST',
491+
headers: {
492+
'Content-Type': 'application/json',
493+
Authorization: `Bearer ${integration.token}`,
494+
},
495+
body: JSON.stringify({
496+
actor: `urn:li:organization:${integration.internalId}`,
497+
object: id,
498+
message: {
499+
text: this.fixText(fields.post)
500+
},
501+
}),
502+
}
503+
);
504+
return true;
505+
}
506+
507+
return false;
508+
}
436509
}
437510

438511
export interface Root {

libraries/nestjs-libraries/src/integrations/social/linkedin.provider.ts

+5-6
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,14 @@ import {
1414
SocialAbstract,
1515
} from '@gitroom/nestjs-libraries/integrations/social.abstract';
1616
import { Integration } from '@prisma/client';
17-
import { Plug } from '@gitroom/helpers/decorators/plug.decorator';
18-
import { string } from 'yup';
19-
import { timer } from '@gitroom/helpers/utils/timer';
20-
2117
export class LinkedinProvider extends SocialAbstract implements SocialProvider {
2218
identifier = 'linkedin';
2319
name = 'LinkedIn';
2420
isBetweenSteps = false;
2521
scopes = ['openid', 'profile', 'w_member_social', 'r_basicprofile'];
2622
refreshWait = true;
2723

24+
2825
async refreshToken(refresh_token: string): Promise<AuthTokenDetails> {
2926
const {
3027
access_token: accessToken,
@@ -285,7 +282,7 @@ export class LinkedinProvider extends SocialAbstract implements SocialProvider {
285282
}
286283
}
287284

288-
private fixText(text: string) {
285+
protected fixText(text: string) {
289286
const pattern = /@\[.+?]\(urn:li:organization.+?\)/g;
290287
const matches = text.match(pattern) || [];
291288
const splitAll = text.split(pattern);
@@ -434,7 +431,9 @@ export class LinkedinProvider extends SocialAbstract implements SocialProvider {
434431
? `urn:li:person:${id}`
435432
: `urn:li:organization:${id}`,
436433
object: topPostId,
437-
message: this.fixText(post.message),
434+
message: {
435+
text: this.fixText(post.message)
436+
},
438437
}),
439438
}
440439
)

libraries/nestjs-libraries/src/integrations/social/threads.provider.ts

+71-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import { timer } from '@gitroom/helpers/utils/timer';
1010
import dayjs from 'dayjs';
1111
import { SocialAbstract } from '@gitroom/nestjs-libraries/integrations/social.abstract';
1212
import { capitalize, chunk } from 'lodash';
13+
import { Plug } from '@gitroom/helpers/decorators/plug.decorator';
14+
import { Integration } from '@prisma/client';
1315

1416
export class ThreadsProvider extends SocialAbstract implements SocialProvider {
1517
identifier = 'threads';
@@ -152,7 +154,6 @@ export class ThreadsProvider extends SocialAbstract implements SocialProvider {
152154

153155
let globalThread = '';
154156
let link = '';
155-
156157
if (firstPost?.media?.length! <= 1) {
157158
const type = !firstPost?.media?.[0]?.url
158159
? undefined
@@ -345,4 +346,73 @@ export class ThreadsProvider extends SocialAbstract implements SocialProvider {
345346
})) || []
346347
);
347348
}
349+
350+
@Plug({
351+
identifier: 'threads-autoPlugPost',
352+
title: 'Auto plug post',
353+
description:
354+
'When a post reached a certain number of likes, add another post to it so you followers get a notification about your promotion',
355+
runEveryMilliseconds: 21600000,
356+
totalRuns: 3,
357+
fields: [
358+
{
359+
name: 'likesAmount',
360+
type: 'number',
361+
placeholder: 'Amount of likes',
362+
description: 'The amount of likes to trigger the repost',
363+
validation: /^\d+$/,
364+
},
365+
{
366+
name: 'post',
367+
type: 'richtext',
368+
placeholder: 'Post to plug',
369+
description: 'Message content to plug',
370+
validation: /^[\s\S]{3,}$/g,
371+
},
372+
],
373+
})
374+
async autoPlugPost(
375+
integration: Integration,
376+
id: string,
377+
fields: { likesAmount: string; post: string }
378+
) {
379+
const { data } = await (
380+
await fetch(
381+
`https://graph.threads.net/v1.0/${id}/insights?metric=likes&access_token=${integration.token}`
382+
)
383+
).json();
384+
385+
const {
386+
values: [value],
387+
} = data.find((p: any) => p.name === 'likes');
388+
389+
if (value.value >= fields.likesAmount) {
390+
await timer(2000);
391+
392+
const form = new FormData();
393+
form.append('media_type', 'TEXT');
394+
form.append('text', fields.post);
395+
form.append('reply_to_id', id);
396+
form.append('access_token', integration.token);
397+
398+
const { id: replyId } = await (
399+
await this.fetch('https://graph.threads.net/v1.0/me/threads', {
400+
method: 'POST',
401+
body: form,
402+
})
403+
).json();
404+
405+
await (
406+
await this.fetch(
407+
`https://graph.threads.net/v1.0/${integration.internalId}/threads_publish?creation_id=${replyId}&access_token=${integration.token}`,
408+
{
409+
method: 'POST',
410+
}
411+
)
412+
).json();
413+
return true;
414+
}
415+
416+
return false;
417+
}
348418
}

0 commit comments

Comments
 (0)