Skip to content

Commit

Permalink
feat: introduce the /newsletter endpoint to subscribe users to dcl ne… (
Browse files Browse the repository at this point in the history
#705)

* feat: introduce the /newsletter endpoint to subscribe users to dcl newsletter

* feat: add source parameter and tests to the Model
  • Loading branch information
juanmahidalgo committed Sep 8, 2023
1 parent 68fb230 commit 5cdd3fd
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 0 deletions.
49 changes: 49 additions & 0 deletions src/Newsletter/Newsletter.model.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import nodefetch from 'node-fetch'
import { env } from 'decentraland-commons'
import { Newsletter } from './Newsletter.model'

jest.mock('node-fetch', () => jest.fn())
jest.mock('decentraland-commons', () => ({
env: {
get: jest.fn(),
},
}))

describe('Newsletter', () => {
beforeEach(() => {
;(env.get as jest.Mock).mockReturnValue('mockValue')
})

afterEach(() => {
jest.resetAllMocks()
})

it('should subscribe the email successfully', async () => {
const mockEmail = '[email protected]'
const mockResponse = { success: true }
;(nodefetch as unknown as jest.Mock).mockResolvedValue({
json: jest.fn().mockResolvedValue(mockResponse),
})

const result = await Newsletter.subscribe(mockEmail)
expect(result).toEqual(mockResponse)
})

it('should return null if the API call results in an error', async () => {
const mockEmail = '[email protected]'
;(nodefetch as unknown as jest.Mock).mockRejectedValue(new Error('API Error'))

const result = await Newsletter.subscribe(mockEmail)
expect(result).toBeNull()
})

it('should return null if there is an exception', async () => {
const mockEmail = '[email protected]'
;(nodefetch as unknown as jest.Mock).mockImplementation(() => {
throw new Error('Exception while fetching')
})

const result = await Newsletter.subscribe(mockEmail)
expect(result).toBeNull()
})
})
42 changes: 42 additions & 0 deletions src/Newsletter/Newsletter.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import nodefetch from 'node-fetch'
import { env } from 'decentraland-commons'
import { SubscriptionResponse } from './Newsletter.types'

const NEWSLETTER_SERVICE_URL = env.get('NEWSLETTER_SERVICE_URL', '')
const NEWSLETTER_PUBLICATION_ID = env.get('NEWSLETTER_PUBLICATION_ID', '')
const NEWSLETTER_SERVICE_API_KEY = env.get('NEWSLETTER_SERVICE_API_KEY', '')

export namespace Newsletter {
export async function subscribe(
email: string,
source = 'Builder'
): Promise<SubscriptionResponse | null> {
try {
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
Authorization: `Bearer ${NEWSLETTER_SERVICE_API_KEY}`,
},
body: JSON.stringify({
email,
reactivate_existing: true,
send_welcome_email: false,
utm_source: source,
utm_campaign: 'Builder',
utm_medium: 'organic',
}),
}
const response = await nodefetch(
`${NEWSLETTER_SERVICE_URL}/publications/${NEWSLETTER_PUBLICATION_ID}/subscriptions`,
options
)

return response.json()
} catch (error) {
console.error(error)
return null
}
}
}
15 changes: 15 additions & 0 deletions src/Newsletter/Newsletter.router.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Request } from 'express'
import { server } from 'decentraland-server'
import { Router } from '../common/Router'
import { Newsletter } from './Newsletter.model'

export class NewsletterRouter extends Router {
mount() {
this.router.post('/newsletter', server.handleRequest(this.subscribe))
}

async subscribe(req: Request) {
const email = req.body.email
return Newsletter.subscribe(email)
}
}
3 changes: 3 additions & 0 deletions src/Newsletter/Newsletter.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export type SubscriptionResponse = {
id: string
}
3 changes: 3 additions & 0 deletions src/Newsletter/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './Newsletter.types'
export * from './Newsletter.model'
export * from './Newsletter.router'
2 changes: 2 additions & 0 deletions src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { db } from './database'
import { ExpressApp } from './common/ExpressApp'
import { withLogger } from './middleware'
import { ProjectByCoordRouter } from './Project'
import { NewsletterRouter } from './Newsletter'
import { errorHandler } from './common/errorHandler'

const SERVER_PORT = env.get('SERVER_PORT', '5000')
Expand Down Expand Up @@ -68,6 +69,7 @@ new AnalyticsRouter(app).mount()
new TiersRouter(app).mount()
new NFTRouter(app).mount()
new LANDRouter(app).mount()
new NewsletterRouter(app).mount()

app.use(errorHandler)

Expand Down

0 comments on commit 5cdd3fd

Please sign in to comment.