[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.

161 lines
4.6 KiB

5 years ago
4 years ago
5 years ago
4 years ago
5 years ago
  1. // api.go
  2. // Copyright (C) 2020 Dwayne Harris
  3. // This program is free software: you can redistribute it and/or modify
  4. // it under the terms of the GNU General Public License as published by
  5. // the Free Software Foundation, either version 3 of the License, or
  6. // (at your option) any later version.
  7. // This program is distributed in the hope that it will be useful,
  8. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. // GNU General Public License for more details.
  11. // You should have received a copy of the GNU General Public License
  12. // along with this program. If not, see <https://www.gnu.org/licenses/>.
  13. import {
  14. FastifyInstance,
  15. RouteShorthandOptions,
  16. Plugin,
  17. DefaultQuery,
  18. DefaultParams,
  19. DefaultHeaders,
  20. DefaultBody,
  21. JSONSchema,
  22. } from 'fastify'
  23. import { Server, IncomingMessage, ServerResponse } from 'http'
  24. import request from 'request'
  25. import { PluginOptions, GiphyResponse } from '../types'
  26. interface FetchOptions {
  27. url: string
  28. params?: string[][]
  29. method?: string
  30. }
  31. const paramsToString = (params: string[][]) => params.map(p => p.join('=')).join('&')
  32. const giphyGifSchema: JSONSchema = {
  33. type: 'object',
  34. properties: {
  35. type: { type: 'string' },
  36. id: { type: 'string' },
  37. slug: { type: 'string' },
  38. url: { type: 'string' },
  39. bitly_url: { type: 'string' },
  40. embed_url: { type: 'string' },
  41. title: { type: 'string' },
  42. images: {
  43. type: 'object',
  44. properties: {
  45. fixed_height: {
  46. type: 'object',
  47. properties: {
  48. url: { type: 'string' },
  49. },
  50. },
  51. fixed_height_still: {
  52. type: 'object',
  53. properties: {
  54. url: { type: 'string' },
  55. },
  56. },
  57. fixed_height_downsampled: {
  58. type: 'object',
  59. properties: {
  60. url: { type: 'string' },
  61. },
  62. },
  63. },
  64. },
  65. },
  66. }
  67. async function fetch<T = any>(options: FetchOptions) {
  68. const { url, params = [], method = 'get' } = options
  69. const uri = params.length > 0 ? `${url}?${paramsToString(params)}` : url
  70. return new Promise<T>((resolve, reject) => {
  71. request({
  72. uri,
  73. method,
  74. json: true,
  75. }, function(error, _, body) {
  76. if (error) {
  77. reject(error)
  78. return
  79. }
  80. resolve(body)
  81. })
  82. })
  83. }
  84. function gifHomeRoute(server: FastifyInstance<Server, IncomingMessage, ServerResponse>) {
  85. const options: RouteShorthandOptions = {
  86. schema: {
  87. response: {
  88. 200: {
  89. type: 'array',
  90. items: giphyGifSchema,
  91. },
  92. },
  93. },
  94. }
  95. server.get<DefaultQuery, DefaultParams, DefaultHeaders, DefaultBody>('/api/gifs/home', options, async (request, reply) => {
  96. const response = await fetch<GiphyResponse>({
  97. url: `${process.env.GIPHY_API_ENDPOINT!}/v1/gifs/trending`,
  98. params: [['api_key', process.env.GIPHY_API_KEY!], ['limit', '20']],
  99. })
  100. return response.data
  101. })
  102. }
  103. function gifSearchRoute(server: FastifyInstance<Server, IncomingMessage, ServerResponse>) {
  104. interface Query {
  105. q: string
  106. }
  107. const options: RouteShorthandOptions = {
  108. schema: {
  109. querystring: {
  110. type: 'object',
  111. properties: {
  112. q: { type: 'string' },
  113. },
  114. },
  115. response: {
  116. 200: {
  117. type: 'array',
  118. items: giphyGifSchema,
  119. },
  120. },
  121. },
  122. }
  123. server.get<Query, DefaultParams, DefaultHeaders, DefaultBody>('/api/gifs/search', options, async (request, reply) => {
  124. const q = request.query.q ? request.query.q.trim() : ''
  125. if (q.length < 3) {
  126. reply.code(400)
  127. return
  128. }
  129. const response = await fetch<GiphyResponse>({
  130. url: `${process.env.GIPHY_API_ENDPOINT!}/v1/gifs/search`,
  131. params: [['api_key', process.env.GIPHY_API_KEY!], ['limit', '20'], ['q', q]],
  132. })
  133. return response.data
  134. })
  135. }
  136. const plugin: Plugin<Server, IncomingMessage, ServerResponse, PluginOptions> = async server => {
  137. gifHomeRoute(server)
  138. gifSearchRoute(server)
  139. }
  140. export default plugin