Skip to content

Commit

Permalink
feat: implement description metatag for transition page in a naive way
Browse files Browse the repository at this point in the history
  • Loading branch information
xming13 committed Sep 19, 2020
1 parent dd34f56 commit d6f620a
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 1 deletion.
15 changes: 14 additions & 1 deletion src/server/controllers/RedirectController.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Express from 'express'
import { inject, injectable } from 'inversify'
import { escape } from 'lodash'
import { gaTrackingId, logger } from '../config'
import { NotFoundError } from '../util/error'
import parseDomain from '../util/domain'
Expand Down Expand Up @@ -68,10 +69,11 @@ export class RedirectController implements RedirectControllerInterface {
return
}

// Find longUrl to redirect to.
// Find longUrl to redirect to and description.
try {
const {
longUrl,
description,
visitedUrls,
redirectType,
} = await this.redirectService.redirectFor(
Expand All @@ -95,6 +97,9 @@ export class RedirectController implements RedirectControllerInterface {
const rootDomain: string = parseDomain(longUrl)

res.status(200).render(TRANSITION_PATH, {
metaTagDescription: RedirectController.renderMetaTagDescription(
description,
),
escapedLongUrl: RedirectController.encodeLongUrl(longUrl),
rootDomain,
gaTrackingId,
Expand Down Expand Up @@ -127,6 +132,14 @@ export class RedirectController implements RedirectControllerInterface {
private static encodeLongUrl(longUrl: string) {
return longUrl.replace(/["]/g, encodeURIComponent)
}

private static renderMetaTagDescription(description: string | null) {
if (!description) {
return ''
}

return `<meta name="description" content="${escape(description)}" />`
}
}

export default RedirectController
19 changes: 19 additions & 0 deletions src/server/repositories/UrlRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,25 @@ export class UrlRepository implements UrlRepositoryInterface {
}
}

/**
* Retrieves the description of the short url from the database.
* @param {string} shortUrl Short url.
* @returns The description of the short url.
*/
public getDescription: (shortUrl: string) => Promise<string> = async (
shortUrl,
) => {
const url = await Url.findOne({
where: { shortUrl, state: StorableUrlState.Active },
})
if (!url) {
throw new NotFoundError(
`shortUrl not found in database:\tshortUrl=${shortUrl}`,
)
}
return url.description
}

public plainTextSearch: (
query: string,
order: SearchResultsSortOrder,
Expand Down
8 changes: 8 additions & 0 deletions src/server/repositories/interfaces/UrlRepositoryInterface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ export interface UrlRepositoryInterface {
*/
getLongUrl: (shortUrl: string) => Promise<string>

/**
* Looks up the description given a shortUrl from the database.
* @param {string} shortUrl The shortUrl.
* @returns Promise that resolves to the description.
* @throws {NotFoundError}
*/
getDescription: (shortUrl: string) => Promise<string>

/**
* Performs plain text search on Urls based on their shortUrl and
* description. The results are ranked in order of relevance based
Expand Down
4 changes: 4 additions & 0 deletions src/server/services/RedirectService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,16 @@ export class RedirectService implements RedirectServiceInterface {

// Find longUrl to redirect to
const longUrl = await this.urlRepository.getLongUrl(shortUrl)
// Find description of the shortUrl
const description = await this.urlRepository.getDescription(shortUrl)

// Update clicks and click statistics in database.
this.linkStatisticsService.updateLinkStatistics(shortUrl, userAgent)

if (this.crawlerCheckService.isCrawler(userAgent)) {
return {
longUrl,
description,
visitedUrls: pastVisits,
redirectType: RedirectType.Direct,
}
Expand All @@ -81,6 +84,7 @@ export class RedirectService implements RedirectServiceInterface {

return {
longUrl,
description,
visitedUrls: newVisits,
redirectType: renderTransitionPage
? RedirectType.TransitionPage
Expand Down
1 change: 1 addition & 0 deletions src/server/services/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export enum RedirectType {
export type RedirectResult = {
visitedUrls: string[]
longUrl: string
description: string | null
redirectType: RedirectType
}

Expand Down
1 change: 1 addition & 0 deletions src/server/views/transition-page.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0">
<%- metaTagDescription %>
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta http-equiv="Content-Language" content="en">
<meta charset="UTF-8">
Expand Down

0 comments on commit d6f620a

Please sign in to comment.