123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- import { Score } from '../../db/models'
- import { ScoreData } from '../../db/models/Score'
- import { sleep } from '../../utils'
- import chainService from '../chainService'
- import difyService, {
- CompletionMessagesPayload,
- DifyRateLimitExceedError,
- } from '../difyService'
- import {
- makePaginate,
- PaginateOptions,
- PaginationConnection,
- } from 'sequelize-cursor-pagination'
- async function getCompletionMessages(
- payload: CompletionMessagesPayload
- ): Promise<Score> {
- const { query, onUpdate, signature, address } = payload
- const signatureRowExist = await Score.findOne({ where: { signature } })
- if (signatureRowExist) {
- const { messageId } = signatureRowExist
- const words = signatureRowExist.answer.split(' ').map((word) => ` ${word}`)
- if (words[0]) {
- words[0] = words[0].trim()
- }
- for (const word of words) {
- const data = { event: 'message', messageId, signature, answer: word }
- const message = JSON.stringify(data)
- onUpdate(`data: ${message}\n\n`)
- await sleep(20)
- }
- const data = { event: 'message_end', messageId, signature }
- const message = JSON.stringify(data)
- onUpdate(`data: ${message}\n\n`)
- return signatureRowExist
- }
- const checkResult = await chainService.checkTxIsSendBananaToBlackhole(
- address,
- signature
- )
- if (!checkResult.success) {
- throw new Error('Invalid transaction signature')
- }
- const scoreId = Score.getScoreId(query)
- const exist = await Score.findOne({ where: { scoreId } })
- if (exist) {
- const { messageId } = exist
- const words = exist.answer.split(' ').map((word) => ` ${word}`)
- if (words[0]) {
- words[0] = words[0].trim()
- }
- for (const word of words) {
- const data = { event: 'message', messageId, signature, answer: word }
- const message = JSON.stringify(data)
- onUpdate(`data: ${message}\n\n`)
- await sleep(20)
- }
- const data = { event: 'message_end', messageId, signature }
- const message = JSON.stringify(data)
- onUpdate(`data: ${message}\n\n`)
- const row = await Score.create({
- address,
- signature,
- scoreId: exist.scoreId,
- query: exist.query,
- answer: exist.answer,
- messageId,
- score: exist.score,
- scoreText: exist.scoreText,
- })
- return row
- }
- try {
- const { answer, messageId } =
- await difyService.getCompletionMessagesByFetchAPI(payload)
- const [scoreText, score] = Score.getScore(answer)
- const row = await Score.create({
- address,
- signature,
- scoreId,
- query,
- answer,
- messageId,
- score,
- scoreText,
- })
- return row
- } catch (e) {
- if (e instanceof DifyRateLimitExceedError) {
- const { serveAt } = e
- const intime = Math.ceil((serveAt - Date.now()) / 1000)
- throw new Error(
- `Master is talking with other guys, please try after ${intime}s.`
- )
- }
- throw e
- }
- }
- // console.log(Tweet.rawAttributes)
- let paginate: (
- this: unknown,
- queryOptions: PaginateOptions<Score>
- ) => Promise<PaginationConnection<Score>>
- async function paginateScoreByOrder(
- after?: string,
- limit = 10
- ): Promise<PaginationConnection<ScoreData>> {
- if (!paginate) {
- paginate = makePaginate(Score)
- }
- const secondResult = await paginate({
- order: [['id', 'DESC']],
- limit,
- after,
- })
- const ret: PaginationConnection<ScoreData> = {
- ...secondResult,
- edges: secondResult.edges.map((edge) => ({
- cursor: edge.node.id,
- node: edge.node.getData(),
- })),
- }
- return ret
- }
- async function getScoreById(id: number): Promise<Score> {
- const row = await Score.findByPk(id)
- if (!row) {
- throw new Error('Score not found')
- }
- return row
- }
- const scoreService = {
- getCompletionMessages,
- paginateScoreByOrder,
- getScoreById,
- }
- export default scoreService
|