Fetch favicon from url

This commit is contained in:
Hongbo Wu 2022-09-28 19:02:29 +08:00
parent 4aceac5f04
commit a6795b380a
8 changed files with 34 additions and 2 deletions

View file

@ -247,6 +247,8 @@ export interface SearchItem {
labels?: Label[]
highlights?: Highlight[]
wordsCount?: number
siteName?: string
siteIcon?: string
}
const keys = ['_id', 'url', 'slug', 'userId', 'uploadFileId', 'state'] as const

View file

@ -1644,6 +1644,7 @@ export type SearchItem = {
readingProgressPercent: Scalars['Float'];
savedAt: Scalars['Date'];
shortId?: Maybe<Scalars['String']>;
siteIcon?: Maybe<Scalars['String']>;
siteName?: Maybe<Scalars['String']>;
slug: Scalars['String'];
state?: Maybe<ArticleSavingRequestStatus>;
@ -4160,6 +4161,7 @@ export type SearchItemResolvers<ContextType = ResolverContext, ParentType extend
readingProgressPercent?: Resolver<ResolversTypes['Float'], ParentType, ContextType>;
savedAt?: Resolver<ResolversTypes['Date'], ParentType, ContextType>;
shortId?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
siteIcon?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
siteName?: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
slug?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
state?: Resolver<Maybe<ResolversTypes['ArticleSavingRequestStatus']>, ParentType, ContextType>;

View file

@ -1170,6 +1170,7 @@ type SearchItem {
readingProgressPercent: Float!
savedAt: Date!
shortId: String
siteIcon: String
siteName: String
slug: String!
state: ArticleSavingRequestStatus

View file

@ -899,6 +899,7 @@ export const searchResolver = authorized<
publishedAt: validatedDate(r.publishedAt),
ownedByViewer: r.userId === claims.uid,
pageType: r.pageType || PageType.Highlights,
siteIcon: r.siteIcon && createImageProxyUrl(r.siteIcon, 32, 32),
} as SearchItem,
cursor: endCursor,
}

View file

@ -60,7 +60,7 @@ export const subscriptionsResolver = authorized<
return {
subscriptions: subscriptions.map((s) => ({
...s,
icon: s.icon && createImageProxyUrl(s.icon, 260, 260),
icon: s.icon && createImageProxyUrl(s.icon, 32, 32),
})),
}
} catch (error) {

View file

@ -1495,6 +1495,7 @@ const schema = gql`
readAt: Date
savedAt: Date!
highlights: [Highlight!]
siteIcon: String
}
type SearchItemEdge {

View file

@ -12,6 +12,8 @@ import { Page } from '../elastic/types'
import { addLabelToPage } from './labels'
import { saveSubscription } from './subscriptions'
import { NewsletterEmail } from '../entity/newsletter_email'
import { fetchFavicon } from '../utils/parser'
import { updatePage } from '../elastic/pages'
interface NewsletterMessage {
email: string
@ -22,7 +24,6 @@ interface NewsletterMessage {
unsubMailTo?: string
unsubHttpUrl?: string
newsletterEmail?: NewsletterEmail
icon?: string
}
// Returns true if the link was created successfully. Can still fail to
@ -68,6 +69,15 @@ export const saveNewsletterEmail = async (
return false
}
if (!page.siteIcon) {
// fetch favicon if not already set
const favicon = await fetchFavicon(page.url)
if (favicon) {
page.siteIcon = favicon
await updatePage(page.id, { siteIcon: favicon }, saveCtx)
}
}
// creates or updates subscription
const subscription = await saveSubscription({
userId: newsletterEmail.user.id,

View file

@ -621,3 +621,18 @@ export const parseEmailAddress = (from: string): addressparser.EmailAddress => {
}
return { name: '', address: from }
}
export const fetchFavicon = async (
url: string
): Promise<string | undefined> => {
try {
// get the correct url if it's a redirect
const response = await axios.head(url)
const realUrl = response.request.res.responseUrl
const domain = new URL(realUrl).hostname
return `https://api.faviconkit.com/${domain}/32`
} catch (e) {
console.log('Error fetching favicon', e)
return undefined
}
}