diff --git a/apps/publisher/src/api-publisher/api-publisher.service.ts b/apps/publisher/src/api-publisher/api-publisher.service.ts index 64f0fa66..31b98ab3 100644 --- a/apps/publisher/src/api-publisher/api-publisher.service.ts +++ b/apps/publisher/src/api-publisher/api-publisher.service.ts @@ -10,7 +10,7 @@ import { catchError, concatMap, filter, map, reduce, scan, shareReplay, switchMa import { SharedService } from "../shared/shared.service"; import { ApiPublisherHelper } from "./helper"; -@Injectable({ scope: Scope.REQUEST }) +@Injectable() export class ApiPublisherService{ private report$: Observable = this.shared.report$; private meedanReport$: Observable = this.shared.meedanReport$; diff --git a/apps/publisher/src/app/app.controller.ts b/apps/publisher/src/app/app.controller.ts index f9a1e708..986e19ec 100644 --- a/apps/publisher/src/app/app.controller.ts +++ b/apps/publisher/src/app/app.controller.ts @@ -26,7 +26,7 @@ class PublishReportDto { @Controller() export class AppController { private readonly logger = new Logger('PublisherAppService'); - + constructor( private readonly appService: AppService, ) {} @@ -67,9 +67,21 @@ export class AppController { this.logger.error(err); throw new HttpException(err.message, 500); }) - ); + ); }catch(e){ return new HttpException(e.message, 500) } } + + // only for test + // @Get('subscribers') + // @ApiTags('subscribers') + // async subscribers(){ + // try{ + // return this.appService.notifySubscribers(); + // }catch(e){ + // return new HttpException(e.message, 500) + // } + // } + } diff --git a/apps/publisher/src/app/app.module.ts b/apps/publisher/src/app/app.module.ts index 9750af22..c808c165 100644 --- a/apps/publisher/src/app/app.module.ts +++ b/apps/publisher/src/app/app.module.ts @@ -1,6 +1,5 @@ import { HttpModule, Module } from '@nestjs/common'; - import { AppController } from './app.controller'; import { AppService } from './app.service'; import { SharedModule } from '../shared/shared.module'; @@ -9,21 +8,20 @@ import { MeedanCheckClientModule } from '@iverify/meedan-check-client'; import { ApiClientModule } from '@iverify/api-client'; import { WpClientModule } from '@iverify/wp-client'; import { ApiPublisherModule } from '../api-publisher/api-publisher.module'; - - +import { CronServicePublisher } from './cron.service'; +import { ScheduleModule } from '@nestjs/schedule'; @Module({ imports: [ + ScheduleModule.forRoot(), SharedModule, WpPublisherModule, MeedanCheckClientModule, WpClientModule, ApiPublisherModule, ApiClientModule, - HttpModule + HttpModule, ], controllers: [AppController], - providers: [ - AppService, - ], + providers: [AppService,CronServicePublisher] }) export class AppModule {} diff --git a/apps/publisher/src/app/app.service.ts b/apps/publisher/src/app/app.service.ts index e9683efd..a85c0bfc 100644 --- a/apps/publisher/src/app/app.service.ts +++ b/apps/publisher/src/app/app.service.ts @@ -1,25 +1,28 @@ -import { Injectable, Scope } from '@nestjs/common'; +import { Injectable } from '@nestjs/common'; import { combineLatest, Observable } from 'rxjs'; import { ApiPublisherService } from '../api-publisher/api-publisher.service'; import { SharedService } from '../shared/shared.service'; import { WpPublisherService } from '../wp-publisher/wp-publisher.service'; -@Injectable({ scope: Scope.REQUEST }) +@Injectable() export class AppService { - itemsToBePublished$: Observable = combineLatest(([ + itemsToBePublished$: Observable = combineLatest([ this.wpPublsher.post$, - this.apiPublisher.postToApi$ - ])) + this.apiPublisher.postToApi$, + ]); constructor( private shared: SharedService, private wpPublsher: WpPublisherService, - private apiPublisher: ApiPublisherService - ){} - - publishReportById(id: string){ + private apiPublisher: ApiPublisherService, + ) {} + + publishReportById(id: string) { this.shared.updateReportId(id); return this.itemsToBePublished$; - } - + } + + notifySubscribers() { + return this.wpPublsher.sendSubscribesEmail$; + } } diff --git a/apps/publisher/src/app/cron.service.ts b/apps/publisher/src/app/cron.service.ts new file mode 100644 index 00000000..f1ad4cb6 --- /dev/null +++ b/apps/publisher/src/app/cron.service.ts @@ -0,0 +1,37 @@ +import { HttpException,Injectable} from '@nestjs/common'; +import { Cron} from '@nestjs/schedule'; +import { AppService } from './app.service'; + +@Injectable() +export class CronServicePublisher { + @Cron('0 0 0 * * *', { + timeZone: process.env.CRON_TIMEZONE || 'UTC' + }) + async handleCron() { + const start = new Date(); + const startDate = start.toISOString(); + console.log('Running hourly job',startDate ); + try { + await this.analyze(); + } catch (error) { + // this.logger.error(`Failed to run analyze: ${error.message}`, error.stack); + } + } + + constructor(private appService: AppService) {} + + private async analyze(): Promise { + this.appService.notifySubscribers().subscribe({ + next: (created) => { + console.log('Subscribers notified', created); + }, + error: (error) => { + console.error(`Cron job error: ${error.message}`, error.stack); + throw new HttpException(error.message, 500); + }, + complete: () => { + console.log('Notification process completed.'); + }, + }); + } +} diff --git a/apps/publisher/src/shared/shared.service.ts b/apps/publisher/src/shared/shared.service.ts index 82c818d2..ef111bf9 100644 --- a/apps/publisher/src/shared/shared.service.ts +++ b/apps/publisher/src/shared/shared.service.ts @@ -3,7 +3,7 @@ import { MeedanCheckClientService } from "libs/meedan-check-client/src/lib/meeda import { Observable, Subject } from "rxjs"; import { shareReplay, switchMap, take } from "rxjs/operators"; -@Injectable({ scope: Scope.REQUEST }) +@Injectable() export class SharedService{ private _reportId: Subject = new Subject(); reportId$: Observable = this._reportId.asObservable().pipe(take(1), shareReplay(1)); @@ -12,19 +12,19 @@ export class SharedService{ wpPost$: Observable = this._wpPost.asObservable().pipe(take(1), shareReplay(1)); report$: Observable = this.reportId$.pipe( - switchMap(id => this.checkClient.getReport(id)), - shareReplay(1) + switchMap(id => this.checkClient.getReport(id)), + shareReplay(1) ) meedanReport$: Observable = this.reportId$.pipe( - switchMap(id => this.checkClient.getMeedanReport(id)), - shareReplay(1) + switchMap(id => this.checkClient.getMeedanReport(id)), + shareReplay(1) ) private sub = this.report$.subscribe(); private wpPostSub = this.wpPost$.subscribe(); - + constructor(private checkClient: MeedanCheckClientService){} - + updateReportId(id: string){ this._reportId.next(id); } diff --git a/apps/publisher/src/wp-publisher/wp-publisher.service.ts b/apps/publisher/src/wp-publisher/wp-publisher.service.ts index 5b352687..c4ad3a79 100644 --- a/apps/publisher/src/wp-publisher/wp-publisher.service.ts +++ b/apps/publisher/src/wp-publisher/wp-publisher.service.ts @@ -3,13 +3,14 @@ import { CreateCategoryDto } from "libs/wp-client/src/lib/interfaces/create-cate import { CommentStatus, CreatePostDto, PostFormat, PostStatus } from "libs/wp-client/src/lib/interfaces/create-post.dto"; import { CreateTagDto } from "libs/wp-client/src/lib/interfaces/create-tag.dto"; import { WpClientService } from "libs/wp-client/src/lib/wp-client.service"; -import { combineLatest, from, iif, Observable, of, zip } from "rxjs"; +import { combineLatest, forkJoin, from, iif, Observable, of, zip } from "rxjs"; import { catchError, concatMap, filter, map, reduce, scan, shareReplay, switchMap, take, tap, withLatestFrom } from "rxjs/operators"; import { SharedService } from "../shared/shared.service"; import { WpPublisherHelper } from "./wp-publisher-helper.service"; import { EmailService } from "@iverify/email/src"; +import { DateTime } from 'luxon'; -@Injectable({ scope: Scope.REQUEST }) +@Injectable() export class WpPublisherService{ private reportId$: Observable = this.shared.reportId$; private report$: Observable = this.shared.report$.pipe(tap(report => console.log('Report: ', JSON.stringify(report)))); @@ -76,7 +77,7 @@ export class WpPublisherService{ tap(wpPost => { this.shared.updateWpPost(wpPost); if (data.postDto.email_address) { - this.emailService.submittedFactCheckContent(data.postDto.email_address, wpPost.link).catch(err => { + this.emailService.submittedFactCheckContent(data.postDto.email_address,data.postDto.title,wpPost.link , this.formatDate(data.postDto.date)).catch(err => { console.error('Error sending post published email:', err); }); } @@ -87,6 +88,45 @@ export class WpPublisherService{ )) ); + subscribersList$:Observable = this.wpClient.getWPSubscribers(); + + latestPosts$:Observable = this.wpClient.getPostsFromDate(); + + sendSubscribesEmail$: Observable = combineLatest([this.subscribersList$, this.latestPosts$]).pipe( + switchMap(([subscribersList, latestPosts]) => { + // Handle the case where latestPosts might be null or undefined + console.log('latestPosts', latestPosts) + const postObservables = (latestPosts ?? []).map((post: any) => + this.wpClient.getPostsThumbnail(post.featured_media).pipe( + map((thumbnail: any) => ({ + link: post.link, + title: post.title.rendered, + thumbnail: thumbnail?.guid?.rendered || '', + date: this.formatDate(post.date) + })), + catchError(() => of({ + link: post.link, + title: post.title.rendered, + thumbnail: 'https://rdc.i-verify.org/wp-content/uploads/2024/10/Frame-1.jpg', + date: this.formatDate(post.date) + })) + ) + ); + + return forkJoin(postObservables).pipe( + switchMap((formattedPosts) => { + if (subscribersList.length > 0 && formattedPosts.length > 0) { + return this.emailService.sendEmailForSubscribers(subscribersList.join(', '), formattedPosts); + } else { + return of(null); + } + }) + ); + }) + ); + + + constructor( private http: HttpService, private shared: SharedService, @@ -95,6 +135,11 @@ export class WpPublisherService{ private emailService: EmailService ){} + private formatDate(inputDate) { + // Parse the input date and format it to the desired output + return DateTime.fromISO(inputDate).toFormat('MMMM d, yyyy'); + } + private tagsIds(tags: string[]): Observable{ const tagsIds$: Observable = of(tags).pipe( switchMap(tags => iif(()=> !!tags.length, this.createManyTags(tags), of([]))), diff --git a/apps/triage/src/app/app.controller.ts b/apps/triage/src/app/app.controller.ts index dcd5bff6..6f32938d 100644 --- a/apps/triage/src/app/app.controller.ts +++ b/apps/triage/src/app/app.controller.ts @@ -50,4 +50,17 @@ export class AppController { return new HttpException(e.message, 500) } } + // test end point for UW + // @Get('radio-messages') + // @ApiTags('Radio Messages') + // async testRadioMessages(){ + // try{ + // const created: number = await this.appService.pullRadioMessages(); + // return created; + // console.log('Items created: ', created); + // } catch(e){ + // throw new HttpException(e.message, 500); + // } + + // } } diff --git a/apps/triage/src/app/app.module.ts b/apps/triage/src/app/app.module.ts index eebb18fa..2f2916a1 100644 --- a/apps/triage/src/app/app.module.ts +++ b/apps/triage/src/app/app.module.ts @@ -13,7 +13,6 @@ import { PerspectiveClientModule } from '@iverify/perspective-client/src'; import { UnitedwaveClientModule } from '@iverify/unitedwave-client'; import { ApiClientModule, ApiClientService } from '@iverify/api-client/src'; import { TranslateService } from './TranslateService/TranslateService'; -import { S3Module } from '@iverify/s3/src/lib/s3.module'; @Module({ imports: [ HttpModule, diff --git a/apps/triage/src/app/app.service.ts b/apps/triage/src/app/app.service.ts index 49344447..4538d508 100644 --- a/apps/triage/src/app/app.service.ts +++ b/apps/triage/src/app/app.service.ts @@ -44,32 +44,41 @@ export class AppService { startTime = lastMeedanReport[0].node?.tasks?.edges?.find(task => task.node?.label === this.config.originalPostTimeField).node?.first_response_value } } - let list = await this.unitedwaveClient.getPosts(startTime).toPromise(); - let createdItems = []; - while(list && list.length !== 0) { - this.logger.log(`${list.length} posts found from radio. Creating Meedan Check items...`); - let lastTime; - - for (let i = list.length - 1; i >= 0; i--) { - this.logger.log('Creating item...') - const post = list[i] - const item = await this.checkClient.createItemFromRadio(post?.clip_url, post?.clip_name, post?.source_text, post?.date_reported).toPromise(); - console.log('item: ', item) - if(!item.error) createdItems = [...createdItems, item]; - lastTime = post?.date_reported - } - this.logger.log('United wave response', JSON.stringify(list)) - if (lastTime) { - list = await this.unitedwaveClient.getPosts(lastTime).toPromise(); - } - else { - list = [] + const postsCount = await this.unitedwaveClient.getPostsCount().toPromise(); + this.logger.log('Latest unitedwaveClient count', postsCount) + const postsPerPage = 50; + const pageCount = Math.ceil(Number(postsCount) / postsPerPage); + const pageIndex = pageCount - 1; + let createdItems = []; + let createdPosts = []; + for(let page = pageIndex ; page >=0 ; page --) { + const list = await this.unitedwaveClient.getPosts(page,startTime).toPromise(); + for (let i = list.length - 1; i >= 0; i--) { + const post = list[i]; + //check duplication + const isDuplicate = this.isDuplicatePost(post, createdPosts); + if (!isDuplicate) { + const item = await this.checkClient.createItemFromRadio(post?.clip_url, post?.clip_name, post?.source_text, post?.date_reported).toPromise(); + if(!item.error) { + createdItems = [...createdItems, item]; + createdPosts = [...createdPosts, post]; + } + } } - } + } this.logger.log(`Created ${createdItems.length} items.`) return createdItems.length; } + private isDuplicatePost(post, createdPosts) { + return createdPosts.some((createdPost) => + createdPost.clip_url === post?.clip_url && + createdPost.clip_name === post?.clip_name && + createdPost.source_text === post?.source_text && + createdPost.date_reported === post?.date_reported + ); + } + async analyze(startDate: string, endDate: string): Promise { try{ const lists = await this.ctClient.getLists().toPromise(); @@ -92,7 +101,6 @@ export class AppService { for(const post of uniqueToxicPosts){ this.logger.log('Creating item...') const item = await this.checkClient.createItem(post.postUrl, post.toxicScores).toPromise(); - console.log('item: ', item) if(!item.error) createdItems = [...createdItems, item]; } this.logger.log(`Created ${createdItems.length} items.`) @@ -113,7 +121,6 @@ export class AppService { endDate - ${endDate}`); this.logger.log(`Max post scan limit - ${this.config.postScanLimit}`) const res = await this.ctClient.getPosts(listId, pagination.count, pagination.offset, startDate, endDate,token).toPromise(); - //console.log('getToxicPostsByList', res) this.logger.log(`Received ${res.posts.length} posts. Analyzing...`) let postsCount = 0; for(const post of res['posts']){ diff --git a/apps/triage/src/main.ts b/apps/triage/src/main.ts index 9e0f7452..ef824f43 100644 --- a/apps/triage/src/main.ts +++ b/apps/triage/src/main.ts @@ -7,17 +7,22 @@ import { Logger } from '@nestjs/common'; import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger'; import { NestFactory } from '@nestjs/core'; import { AppModule } from './app/app.module'; -//import * as fs from 'fs'; +import * as fs from 'fs'; async function bootstrap() { - // const httpsOptions = { - // key: fs.readFileSync('private.key'), - // cert: fs.readFileSync('certificate.crt'), - // }; - // const app = await NestFactory.create(AppModule ,{ - // httpsOptions, - // }); - const app = await NestFactory.create(AppModule); + const is_ssl = process.env.IS_SSL === 'true'; + let app; + if (is_ssl) { + const httpsOptions = { + key: fs.readFileSync('private.key'), + cert: fs.readFileSync('certificate.crt'), + }; + app = await NestFactory.create(AppModule, { + httpsOptions, + }); + } else { + app = await NestFactory.create(AppModule); + } app.enableCors(); const globalPrefix = 'triage'; app.setGlobalPrefix(globalPrefix); diff --git a/libs/email/src/lib/email.service.ts b/libs/email/src/lib/email.service.ts index a2c53276..7981e618 100644 --- a/libs/email/src/lib/email.service.ts +++ b/libs/email/src/lib/email.service.ts @@ -8,7 +8,6 @@ export class EmailService { constructor(private mailerService: MailerService) {} async sendCsvReport(data: Article[], date: string) { - // const articles = JSON.stringify(data); // const keys = [ // 'DB Id', @@ -42,9 +41,12 @@ export class EmailService { // 'Notes' // ] const csv = await converter.json2csvAsync(data); - const mailingList = process.env.EMAIL_LIST ? process.env.EMAIL_LIST.split(',') : ['admin@iverify-config.org']; + const mailingList = process.env.EMAIL_LIST + ? process.env.EMAIL_LIST.split(',') + : ['admin@iverify-config.org']; let env = process.env.ENV === 'prod' ? 'SL' : 'SL - test'; - if(process.env && process.env.EMAIL_SUBJECT_COUNTRY) env = process.env.EMAIL_SUBJECT_COUNTRY; + if (process.env && process.env.EMAIL_SUBJECT_COUNTRY) + env = process.env.EMAIL_SUBJECT_COUNTRY; await this.mailerService.sendMail({ to: mailingList, from: 'admin@iverify-config.org', @@ -52,37 +54,1169 @@ export class EmailService { text: 'CSV report', attachments: [ { - filename: `iverify-publications-${date}.csv`, - content: csv + filename: `iverify-publications-${date}.csv`, + content: csv, }, - ] + ], }); } - async submittedFactCheckContent(email: string,factCheckedLink:string ): Promise { + async submittedFactCheckContent( + email: string, + title: string, + factCheckedLink: string, + date: string + ): Promise { try { + let htmlContent = `
+
+
+
+
+ + +
+ + + + + + +
+ + + + + + +
+ + + + + + +
+ + + + + + +
+

Bonjour,

+

 

+

+ Vous avez récemment souscrit à notre service de notifications pour être informé lorsque du contenu est vérifié par l’equipe iVerify. +

+

 

+

+ Nous vous informons que le contenu que vous aviez signalé ou suivi a été fact-checké. Vous pouvez consulter les résultats de notre analyse en suivant le lien ci-dessous : +

+
+
+
`; + htmlContent += `
+
+
+ + + + + + + + + + + + + + + + + + +
+
+ ${title} + > +
+ +
+ + + + + + +
+ En savoir plus... +
+
+
+
+
`; + + htmlContent += ` + + + + + +
+ + + + + + +
+ + + + + + +
+

+ Nous vous remercions pour votre engagement envers la vérification des informations et vous encourageons à partager ces résultats avec vos contacts sur les réseaux sociaux afin de contribuer à la diffusion d'informations fiables. +

+

 

+

+ Cordialement,
L’équipe de + vérification des faits iVerify +

+
+
+
+ + + + + + +
+ + + + + + +
+ + + + + + +
+
+
+ + + + + + +
+ + + + + + +
+ + + + + + + + + + +
+ iVerify RÉPUBLIQUE DÉMOCRATIQUE DU CONGO +
+ Voir en ligne +
+
+
+
+ + +
+
+
+
+
+
+
`; await this.mailerService.sendMail({ to: email, subject: 'NOTIFICATION EMAIL FOR SUBMITTED FACT-CHECKED CONTENT', - text: `Bonjour, + html: htmlContent, + }); + console.log('Email sent successfully'); + } catch (error) { + console.error('Error sending email:', error); + throw new Error('Email sending failed'); + } + } - Vous avez récemment souscrit à notre service de notifications pour être informé lorsque du contenu est vérifié par l’equipe iVerify. + async sendEmailForSubscribers(email: string, lists: any): Promise { + try { + let htmlContent = `
+
+
+
+
+ - Nous vous informons que le contenu que vous aviez signalé ou suivi a été fact-checké. Vous pouvez consulter les résultats de notre analyse en suivant le lien ci-dessous : +
+ + + +
+ + + + + + +
+ + + + + + +
+ + + + + + +
+

Bonjour,

+

 

+

+ Merci de vous être abonné à notre + service de notifications pour suivre + les dernières vérifications effectuées + par l’équipe iVerify. +

+

 

+

+ Voici les contenus qui ont été + fact-checkés aujourd'hui : +

+
+
+
`; + for (const list of lists) { + if (list.thumbnail !== '') { + htmlContent += ` + + + + + + +
+ + + + + + +
+
+
+
+ + + + + + +
+ + + +
+
+
+
+
+ + + + + + + + + + + + +
+ ${list.date} +
+ + ${list.title} + +
+ + + + + + +
+ + En savoir plus... + +
+
+
+
+
+
+
`; + } else { + htmlContent += `
+
+
+ + + + + - ${factCheckedLink} + + + - Nous vous remercions pour votre engagement envers la vérification des informations et vous encourageons à partager ces résultats avec vos contacts sur les réseaux sociaux afin de contribuer à la diffusion d'informations fiables. + + + + + + + + +
+ ${list.date} +
+ ${list.title} + > +
+ +
+ + + + + + +
+ En savoir plus... +
+
+
+
+
`; + } + } + + htmlContent += ` + + + + + +
+ + + + + + +
+ + + + + + +
+

+ Nous vous remercions pour votre + engagement dans la lutte contre la + désinformation et vous invitons à + partager ces résultats sur vos réseaux + sociaux pour contribuer à la diffusion + d'informations fiables. +

+

 

+

+ Cordialement,
L’équipe de + vérification des faits iVerify +

+
+
+
+ + + + + + +
+ + + + + + +
+ + + + + + +
+
+
+ + + + + + +
+ + + + + + +
+ + + + + + +
+ iVerify RÉPUBLIQUE DÉMOCRATIQUE DU CONGO +
+
+
+ + + +
+
+ + +
+ `; + await this.mailerService.sendMail({ + bcc: email, + subject: 'DAILY FACT-CHECKED CONTENT NOTIFICATION', + html: htmlContent, + }); - Cordialement, - L’équipe de vérification des faits iVerify`, - }); console.log('Email sent successfully'); } catch (error) { console.error('Error sending email:', error); throw new Error('Email sending failed'); } } - } - diff --git a/libs/unitedwave-client/src/lib/config.ts b/libs/unitedwave-client/src/lib/config.ts index 36d13a7a..58352399 100644 --- a/libs/unitedwave-client/src/lib/config.ts +++ b/libs/unitedwave-client/src/lib/config.ts @@ -9,7 +9,6 @@ export class UnitedwaveClientConfig{ readonly endpoints = { search: `${this.apiBase}/clips/search`, + count: `${this.apiBase}/clips/count` } - - } diff --git a/libs/unitedwave-client/src/lib/unitedwave-client.service.ts b/libs/unitedwave-client/src/lib/unitedwave-client.service.ts index 28164997..02eb1612 100644 --- a/libs/unitedwave-client/src/lib/unitedwave-client.service.ts +++ b/libs/unitedwave-client/src/lib/unitedwave-client.service.ts @@ -14,21 +14,37 @@ export class UnitedwaveClientService{ let year = date.getFullYear(); let month = String(date.getMonth() + 1).padStart(2, '0'); // Months are 0-based, so add 1 let day = String(date.getDate()).padStart(2, '0'); - + // Get time components let hours = String(date.getHours()).padStart(2, '0'); let minutes = String(date.getMinutes()).padStart(2, '0'); let seconds = String(date.getSeconds()).padStart(2, '0'); - + // Format the date and time in the desired format return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; } - - - getPosts(startDate?: string){ - this.logger.log('Query United Wave posts from ', startDate) + getPostsCount(filter?:string) { + let query = this.config.endpoints.count + `?user[name]=${this.config.username}&user[secret]=${this.config.password}`; + if(filter) { + query += `&clip[filters]=${filter}` + } + return this.http.post(query).pipe( + map(res => res.data), + retry(3), + catchError(err => { + this.logger.error(`Error fetching posts: `, err.message); + throw new HttpException(err.message, 500); + }) + ) + } + + getPosts(page?: number,startDate?: string){ + this.logger.log('Query United Wave posts page ', page.toString()) let query = this.config.endpoints.search + `?user[name]=${this.config.username}&user[secret]=${this.config.password}`; + if (page) { + query += `&page=${page}` + } if (startDate) { query += `&clip[from_date]=${startDate}` } diff --git a/libs/wp-client/src/lib/config.ts b/libs/wp-client/src/lib/config.ts index 16526a06..59489e01 100644 --- a/libs/wp-client/src/lib/config.ts +++ b/libs/wp-client/src/lib/config.ts @@ -10,8 +10,8 @@ export class WpConfig{ tags: `${this.apiBase}/tags`, categories: `${this.apiBase}/categories?per_page=20`, media: `${this.apiBase}/media`, - currentUser: `${this.apiBase}/users/me` - + currentUser: `${this.apiBase}/users/me`, + subscribers: `${this.apiBase}/newsletter/v1/get_subscribers`, } readonly authParams = { diff --git a/libs/wp-client/src/lib/wp-client.service.ts b/libs/wp-client/src/lib/wp-client.service.ts index 5c697664..866f91f6 100644 --- a/libs/wp-client/src/lib/wp-client.service.ts +++ b/libs/wp-client/src/lib/wp-client.service.ts @@ -55,6 +55,48 @@ export class WpClientService{ ); } + getPostsFromDate(date?: string){ + const start = new Date(); + start.setHours(start.getHours() - 24); + const startDate = date ?? start.toISOString().split('.')[0]; + console.log('getPostsFromDate', startDate); + return this.http.get(this.config.endpoints.posts + '?after=' + startDate, this.auth).pipe( + map(res => res.data), + catchError(err => { + console.log('Error getting post', err) + throw new HttpException(err.message, 500); + }) + ); + } + + getPostsThumbnail(id){ + return this.http.get(this.config.endpoints.media + '/' + id, this.auth).pipe( + map(res => res.data), + catchError(err => { + console.log('Error getting post', err) + throw new HttpException(err.message, 500); + }) + ); + } + + + getWPSubscribers():Observable { + const key = process.env.SUBSCRIBE_API_KEY + const options = { + params: { + api_key: key, + }, + ...this.auth + }; + return this.http.get(this.config.endpoints.subscribers, options).pipe( + map(res => res.data), + catchError(err => { + console.log('Error getting post', err) + throw new HttpException(err.message, 500); + }) + ); + } + getPostByTitle(title: string){ const params = {title}; @@ -68,7 +110,7 @@ export class WpClientService{ } getPostByCheckId(check_id: string){ - const params = {check_id}; + const params = {meta_key : 'check_id', meta_value : check_id}; return this.http.get(this.config.endpoints.posts, {params, ...this.auth}).pipe( map(res => res.data), catchError(err => {