[ABANDONDED] Set of "apps" for the Flexor social network.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

145 lines
3.9 KiB

5 years ago
  1. import {
  2. FastifyInstance,
  3. RouteShorthandOptions,
  4. Plugin,
  5. DefaultQuery,
  6. DefaultParams,
  7. DefaultHeaders,
  8. DefaultBody,
  9. JSONSchema,
  10. } from 'fastify'
  11. import { Server, IncomingMessage, ServerResponse } from 'http'
  12. import request from 'request'
  13. import { PluginOptions, GiphyResponse } from '../../types'
  14. interface FetchOptions {
  15. url: string
  16. params?: string[][]
  17. method?: string
  18. }
  19. const paramsToString = (params: string[][]) => params.map(p => p.join('=')).join('&')
  20. const giphyGifSchema: JSONSchema = {
  21. type: 'object',
  22. properties: {
  23. type: { type: 'string' },
  24. id: { type: 'string' },
  25. slug: { type: 'string' },
  26. url: { type: 'string' },
  27. bitly_url: { type: 'string' },
  28. embed_url: { type: 'string' },
  29. title: { type: 'string' },
  30. images: {
  31. type: 'object',
  32. properties: {
  33. fixed_height: {
  34. type: 'object',
  35. properties: {
  36. url: { type: 'string' },
  37. },
  38. },
  39. fixed_height_still: {
  40. type: 'object',
  41. properties: {
  42. url: { type: 'string' },
  43. },
  44. },
  45. fixed_height_downsampled: {
  46. type: 'object',
  47. properties: {
  48. url: { type: 'string' },
  49. },
  50. },
  51. },
  52. },
  53. },
  54. }
  55. async function fetch<T = any>(options: FetchOptions) {
  56. const { url, params = [], method = 'get' } = options
  57. const uri = params.length > 0 ? `${url}?${paramsToString(params)}` : url
  58. return new Promise<T>((resolve, reject) => {
  59. request({
  60. uri,
  61. method,
  62. json: true,
  63. }, function(error, response, body) {
  64. if (error) {
  65. reject(error)
  66. return
  67. }
  68. resolve(body)
  69. })
  70. })
  71. }
  72. function gifHomeRoute(server: FastifyInstance<Server, IncomingMessage, ServerResponse>) {
  73. const options: RouteShorthandOptions = {
  74. schema: {
  75. response: {
  76. 200: {
  77. type: 'array',
  78. items: giphyGifSchema,
  79. },
  80. },
  81. },
  82. }
  83. server.get<DefaultQuery, DefaultParams, DefaultHeaders, DefaultBody>('/api/gifs/home', options, async (request, reply) => {
  84. const response = await fetch<GiphyResponse>({
  85. url: `${process.env.GIPHY_API_ENDPOINT!}/v1/gifs/trending`,
  86. params: [['api_key', process.env.GIPHY_API_KEY!], ['limit', '20']],
  87. })
  88. return response.data
  89. })
  90. }
  91. function gifSearchRoute(server: FastifyInstance<Server, IncomingMessage, ServerResponse>) {
  92. interface Query {
  93. q: string
  94. }
  95. const options: RouteShorthandOptions = {
  96. schema: {
  97. querystring: {
  98. type: 'object',
  99. properties: {
  100. q: { type: 'string' },
  101. },
  102. },
  103. response: {
  104. 200: {
  105. type: 'array',
  106. items: giphyGifSchema,
  107. },
  108. },
  109. },
  110. }
  111. server.get<Query, DefaultParams, DefaultHeaders, DefaultBody>('/api/gifs/search', options, async (request, reply) => {
  112. const q = request.query.q ? request.query.q.trim() : ''
  113. if (q.length < 3) {
  114. reply.code(400)
  115. return
  116. }
  117. const response = await fetch<GiphyResponse>({
  118. url: `${process.env.GIPHY_API_ENDPOINT!}/v1/gifs/search`,
  119. params: [['api_key', process.env.GIPHY_API_KEY!], ['limit', '20'], ['q', q]],
  120. })
  121. return response.data
  122. })
  123. }
  124. const plugin: Plugin<Server, IncomingMessage, ServerResponse, PluginOptions> = async server => {
  125. gifHomeRoute(server)
  126. gifSearchRoute(server)
  127. }
  128. export default plugin