11import { ValidationError } from 'apollo-server-errors' ;
22import type { EntityManager } from 'typeorm' ;
33import { generateShortId } from '../ids' ;
4- import { UNKNOWN_SOURCE } from '../entity/Source' ;
4+ import { Source , SourceType , UNKNOWN_SOURCE } from '../entity/Source' ;
55import { Post , PostOrigin , PostType } from '../entity/posts/Post' ;
66import { SocialTwitterPost } from '../entity/posts/SocialTwitterPost' ;
77import { markdown } from './markdown' ;
@@ -30,6 +30,7 @@ export interface TwitterReferencePost {
3030 contentHtml ?: string | null ;
3131 image ?: string | null ;
3232 videoId ?: string | null ;
33+ authorUsername ?: string | null ;
3334}
3435
3536export interface TwitterMappingResult {
@@ -41,9 +42,7 @@ export interface TwitterMappingResult {
4142export interface TwitterReferenceUpsertParams {
4243 entityManager : EntityManager ;
4344 reference : TwitterReferencePost ;
44- sourceId ?: string | null ;
4545 language ?: string | null ;
46- isPrivate ?: boolean ;
4746}
4847
4948const getStringOrUndefined = ( value ?: string | null ) : string | undefined => {
@@ -270,6 +269,7 @@ const extractTwitterReference = (
270269 contentHtml : getStringOrUndefined ( reference . content_html ) ,
271270 image : pickPrimaryImage ( reference . media || [ ] ) ,
272271 videoId : pickPrimaryVideoId ( reference . media || [ ] ) ,
272+ authorUsername : getStringOrUndefined ( reference . author_username ) ,
273273 } ;
274274} ;
275275
@@ -374,12 +374,38 @@ export const mapTwitterSocialPayload = ({
374374 } ;
375375} ;
376376
377+ const resolveSourceByTwitterUsername = async ( {
378+ entityManager,
379+ authorUsername,
380+ } : {
381+ entityManager : EntityManager ;
382+ authorUsername ?: string | null ;
383+ } ) : Promise < { id : string ; isPrivate : boolean } | undefined > => {
384+ if ( ! authorUsername ) {
385+ return undefined ;
386+ }
387+
388+ const matchedSource = await entityManager
389+ . getRepository ( Source )
390+ . createQueryBuilder ( 'source' )
391+ . select ( [ 'source.id' , 'source.private' ] )
392+ . where ( 'source.type = :type' , { type : SourceType . Machine } )
393+ . andWhere ( 'LOWER(source.twitter) = :twitter' , {
394+ twitter : authorUsername . toLowerCase ( ) ,
395+ } )
396+ . getOne ( ) ;
397+
398+ if ( ! matchedSource ) {
399+ return undefined ;
400+ }
401+
402+ return { id : matchedSource . id , isPrivate : matchedSource . private } ;
403+ } ;
404+
377405export const upsertTwitterReferencedPost = async ( {
378406 entityManager,
379407 reference,
380- sourceId,
381408 language,
382- isPrivate = false ,
383409} : TwitterReferenceUpsertParams ) : Promise < string | undefined > => {
384410 const referenceUrl = getStringOrUndefined ( reference . url ) ;
385411 if ( ! referenceUrl ) {
@@ -425,7 +451,12 @@ export const upsertTwitterReferencedPost = async ({
425451 getStringOrUndefined ( reference . contentHtml ) ||
426452 ( content ? markdown . render ( content ) : undefined ) ;
427453 const visible = ! ! ( title || content ) ;
428- const referenceSourceId = sourceId || UNKNOWN_SOURCE ;
454+ const resolvedSource = await resolveSourceByTwitterUsername ( {
455+ entityManager,
456+ authorUsername : reference . authorUsername ,
457+ } ) ;
458+ const referenceSourceId = resolvedSource ?. id || UNKNOWN_SOURCE ;
459+ const isPrivate = resolvedSource ?. isPrivate ?? true ;
429460
430461 const repository = entityManager . getRepository ( SocialTwitterPost ) ;
431462
0 commit comments