add twitter connect, accomplish other tasks
This commit is contained in:
parent
35c319d311
commit
5d2a3af490
@ -4,20 +4,23 @@
|
||||
"name": "First Activity1",
|
||||
"description": "This is the first test activity",
|
||||
"tasks": [{
|
||||
"task": "TwitterFollow",
|
||||
"task": "TwitterConnect",
|
||||
"params": {}
|
||||
}, {
|
||||
"task": "TwitterFollow",
|
||||
"params": {"time": 6, "failRate": 60}
|
||||
}, {
|
||||
"task": "TwitterRetweet",
|
||||
"params": {}
|
||||
"params": {"time": 6, "failRate": 60}
|
||||
}, {
|
||||
"task": "DiscordJoin",
|
||||
"params": {}
|
||||
}, {
|
||||
"task": "DiscordRole",
|
||||
"params": {}
|
||||
"params": {"time": 6, "failRate": 60}
|
||||
}, {
|
||||
"task": "UpdateScore",
|
||||
"params": {}
|
||||
"params": {"score": [100, 20]}
|
||||
}],
|
||||
"startTime": 1702628292366,
|
||||
"endTime": 1705220292366
|
||||
|
@ -2,7 +2,8 @@ import { ZError } from "common/ZError";
|
||||
import BaseController, { ROLE_ANON } from "common/base.controller";
|
||||
import { role, router } from "decorators/router";
|
||||
import { all } from "deepmerge";
|
||||
import { ActivityUser, TaskStatusEnum } from "models/ActivityUser";
|
||||
import { ActivityInfo } from "models/ActivityInfo";
|
||||
import { ActivityUser, TaskStatus, TaskStatusEnum } from "models/ActivityUser";
|
||||
import { join } from 'path'
|
||||
const fs = require('fs')
|
||||
|
||||
@ -30,14 +31,16 @@ const parseCurrentTask = (user: typeof ActivityUser, task: string) => {
|
||||
}
|
||||
let preEnd = true;
|
||||
let currentTask = null;
|
||||
let nextTask = null;
|
||||
for (let taskData of user.taskProgress) {
|
||||
if (taskData.id === task) {
|
||||
currentTask = taskData;
|
||||
break;
|
||||
}
|
||||
if (taskData.status !== 2) {
|
||||
if (taskData.status !== 2 && !currentTask) {
|
||||
preEnd = false;
|
||||
break;
|
||||
}
|
||||
if (currentTask && !nextTask) {
|
||||
nextTask = taskData;
|
||||
}
|
||||
}
|
||||
if (!preEnd) {
|
||||
@ -46,7 +49,20 @@ const parseCurrentTask = (user: typeof ActivityUser, task: string) => {
|
||||
if (!currentTask) {
|
||||
throw new ZError(13, 'task not found')
|
||||
}
|
||||
return {preEnd, currentTask}
|
||||
return {preEnd, currentTask, nextTask}
|
||||
}
|
||||
|
||||
const parseNextTask = async (
|
||||
user: typeof ActivityUser,
|
||||
activity: typeof ActivityInfo,
|
||||
task: TaskStatus) => {
|
||||
let Task = require('../tasks/' + task.id);
|
||||
if (!Task.default.auto) {
|
||||
return true
|
||||
}
|
||||
let taskInstance = new Task.default({user, activity});
|
||||
let result = await taskInstance.execute({});
|
||||
return result
|
||||
}
|
||||
export default class TasksController extends BaseController {
|
||||
|
||||
@ -69,7 +85,7 @@ export default class TasksController extends BaseController {
|
||||
if (!user.taskProgress || user.taskProgress.length === 0) {
|
||||
for (let task of activity.tasks) {
|
||||
if (allTasks.has(task.task)) {
|
||||
user.taskProgress.push({id: task.task, status: 0, time: 0})
|
||||
user.taskProgress.push({id: task.task, status: 0})
|
||||
}
|
||||
}
|
||||
await user.save();
|
||||
@ -94,11 +110,17 @@ export default class TasksController extends BaseController {
|
||||
let user = req.user;
|
||||
let activity = req.activity;
|
||||
let { task } = req.params;
|
||||
let { currentTask } = parseCurrentTask(user, task);
|
||||
let { currentTask, nextTask } = parseCurrentTask(user, task);
|
||||
if (currentTask.status !== TaskStatusEnum.RUNNING) {
|
||||
throw new ZError(11, 'task not begin');
|
||||
}
|
||||
if (currentTask.status !== TaskStatusEnum.SUCCESS) {
|
||||
let Task = require('../tasks/' + task);
|
||||
let taskInstance = new Task.default({user, activity});
|
||||
await taskInstance.check();
|
||||
let result = await taskInstance.execute({});
|
||||
if (result) {
|
||||
await parseNextTask(user, activity, nextTask);
|
||||
}
|
||||
}
|
||||
return currentTask
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ export class TaskStatus {
|
||||
@prop()
|
||||
timeFinish: number
|
||||
@prop({ type: mongoose.Schema.Types.Mixed })
|
||||
params: any
|
||||
data: any
|
||||
}
|
||||
|
||||
interface ActivityUserClass extends Base, TimeStamps {}
|
||||
@ -34,6 +34,8 @@ interface ActivityUserClass extends Base, TimeStamps {}
|
||||
@index({ address: 1, activity: 1 }, { unique: true })
|
||||
@index({ inviteCode: 1, activity: 1 }, { unique: true })
|
||||
@index({ inviteUser: 1, activity: 1 }, { unique: false })
|
||||
@index({ twitterId: 1 }, { unique: true, partialFilterExpression: { twitterId: { $exists: true } } })
|
||||
@index({ discordId: 1 }, { unique: true, partialFilterExpression: { discordId: { $exists: true } } })
|
||||
@modelOptions({ schemaOptions: { collection: 'activity_user', timestamps: true }, options: { allowMixed: Severity.ALLOW } })
|
||||
@pre<ActivityUserClass>('save', async function () {
|
||||
if (!this.inviteCode) {
|
||||
@ -68,6 +70,11 @@ class ActivityUserClass extends BaseModule {
|
||||
@prop()
|
||||
public comment?: string
|
||||
|
||||
@prop()
|
||||
public twitterId?: string
|
||||
@prop()
|
||||
public discordId: string
|
||||
|
||||
@prop()
|
||||
public lastLogin?: Date
|
||||
|
||||
|
@ -1,14 +1,35 @@
|
||||
import { checkDiscord } from "services/oauth.svr";
|
||||
import { ITask } from "./base/ITask";
|
||||
import { ZError } from "common/ZError";
|
||||
import { TaskStatusEnum } from "models/ActivityUser";
|
||||
|
||||
export default class DiscordJoin extends ITask {
|
||||
static desc = 'join discord'
|
||||
static show: boolean = true
|
||||
|
||||
async execute(data: any) {
|
||||
// do nothing
|
||||
}
|
||||
async check(data: any) {
|
||||
// do nothing
|
||||
let { address } = this.params.user
|
||||
let res = await checkDiscord(address)
|
||||
console.log(res);
|
||||
if (res.status !== 200) {
|
||||
throw new ZError(11, 'discord check failed')
|
||||
}
|
||||
if (res.data.errcode) {
|
||||
throw new ZError(res.data.errcode, res.data.errmsg)
|
||||
}
|
||||
let task = this.params.user.taskProgress.find(t => t.id === this.constructor.name)
|
||||
if (res.data.data.userid && task.status !== TaskStatusEnum.SUCCESS) {
|
||||
task.status = TaskStatusEnum.SUCCESS
|
||||
task.timeFinish = Date.now()
|
||||
task.data = res.data.data
|
||||
task.discordId = res.data.data.userid
|
||||
try {
|
||||
await this.params.user.save()
|
||||
} catch(err) {
|
||||
throw new ZError(100, 'discord already binded')
|
||||
}
|
||||
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,25 @@
|
||||
import { ZError } from "common/ZError";
|
||||
import { ITask } from "./base/ITask";
|
||||
import { TaskStatusEnum } from "models/ActivityUser";
|
||||
|
||||
export default class DiscordRole extends ITask {
|
||||
static desc = 'acquire discord role'
|
||||
static show: boolean = true
|
||||
async execute(data: any) {
|
||||
// do nothing
|
||||
}
|
||||
async check(data: any) {
|
||||
// do nothing
|
||||
let task = this.params.user.taskProgress.find(t => t.id === this.constructor.name)
|
||||
let cfg = this.params.activity.tasks.find(t => t.task === this.constructor.name)
|
||||
let time = cfg.params.time;
|
||||
if (Date.now() - task.timeStart < time * 1000) {
|
||||
throw new ZError(11, 'check discord role failed')
|
||||
}
|
||||
let num = Math.random() * 100
|
||||
if (num < cfg.params.failRate) {
|
||||
throw new ZError(12, 'check discord role failed')
|
||||
}
|
||||
task.status = TaskStatusEnum.SUCCESS
|
||||
task.timeFinish = Date.now()
|
||||
task.data = {}
|
||||
await this.params.user.save()
|
||||
return true
|
||||
}
|
||||
|
||||
|
36
src/tasks/TwitterConnect.ts
Normal file
36
src/tasks/TwitterConnect.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import { checkTwitter } from "services/oauth.svr";
|
||||
import { ITask } from "./base/ITask";
|
||||
import { ActivityUser, TaskStatusEnum } from "models/ActivityUser";
|
||||
import { ZError } from "common/ZError";
|
||||
|
||||
export default class TwitterConnect extends ITask {
|
||||
static desc = 'twitter connect'
|
||||
static show: boolean = true
|
||||
|
||||
async execute(data: any) {
|
||||
let { address } = this.params.user
|
||||
let res = await checkTwitter(address)
|
||||
console.log(res);
|
||||
if (res.status !== 200) {
|
||||
throw new ZError(11, 'twitter check failed')
|
||||
}
|
||||
if (res.data.errcode) {
|
||||
throw new ZError(res.data.errcode, res.data.errmsg)
|
||||
}
|
||||
let task = this.params.user.taskProgress.find(t => t.id === this.constructor.name)
|
||||
if (res.data.data.userid && task.status !== TaskStatusEnum.SUCCESS) {
|
||||
task.status = TaskStatusEnum.SUCCESS
|
||||
task.timeFinish = Date.now()
|
||||
task.data = res.data.data
|
||||
task.twitterId = res.data.data.userid
|
||||
try {
|
||||
await this.params.user.save()
|
||||
} catch(err) {
|
||||
throw new ZError(100, 'twitter already binded')
|
||||
}
|
||||
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
@ -1,31 +1,25 @@
|
||||
import { checkTwitter } from "services/oauth.svr";
|
||||
import { ITask } from "./base/ITask";
|
||||
import { ActivityUser, TaskStatusEnum } from "models/ActivityUser";
|
||||
import { TaskStatusEnum } from "models/ActivityUser";
|
||||
import { ZError } from "common/ZError";
|
||||
|
||||
export default class TwitterFollow extends ITask {
|
||||
static desc = 'twitter follow'
|
||||
static show: boolean = true
|
||||
async execute(data: any) {
|
||||
// do nothing
|
||||
}
|
||||
async check(data: any) {
|
||||
let { address } = this.params.user
|
||||
let res = await checkTwitter(address)
|
||||
console.log(res);
|
||||
if (res.status !== 200) {
|
||||
throw new ZError(11, 'twitter check failed')
|
||||
}
|
||||
if (res.data.errcode) {
|
||||
throw new ZError(res.data.errcode, res.data.errmsg)
|
||||
}
|
||||
let task = this.params.user.taskProgress.find(t => t.id === this.constructor.name)
|
||||
if (res.data.data.userid && task.status !== TaskStatusEnum.SUCCESS) {
|
||||
task.status = TaskStatusEnum.SUCCESS
|
||||
task.timeFinish = Date.now()
|
||||
task.params = res.data.data
|
||||
await this.params.user.save()
|
||||
let cfg = this.params.activity.tasks.find(t => t.task === this.constructor.name)
|
||||
let time = cfg.params.time;
|
||||
if (Date.now() - task.timeStart < time * 1000) {
|
||||
throw new ZError(11, 'follow failed')
|
||||
}
|
||||
let num = Math.random() * 100
|
||||
if (num < cfg.params.failRate) {
|
||||
throw new ZError(12, 'follow failed')
|
||||
}
|
||||
task.status = TaskStatusEnum.SUCCESS
|
||||
task.timeFinish = Date.now()
|
||||
task.data = {}
|
||||
await this.params.user.save()
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,25 @@
|
||||
import { ZError } from "common/ZError";
|
||||
import { ITask } from "./base/ITask";
|
||||
import { TaskStatusEnum } from "models/ActivityUser";
|
||||
|
||||
export default class TwitterRetweet extends ITask {
|
||||
static desc = 'twitter retweet'
|
||||
static show: boolean = true
|
||||
async execute(data: any) {
|
||||
// do nothing
|
||||
}
|
||||
async check(data: any) {
|
||||
// do nothing
|
||||
let task = this.params.user.taskProgress.find(t => t.id === this.constructor.name)
|
||||
let cfg = this.params.activity.tasks.find(t => t.task === this.constructor.name)
|
||||
let time = cfg.params.time;
|
||||
if (Date.now() - task.timeStart < time * 1000) {
|
||||
throw new ZError(11, 'retweet failed')
|
||||
}
|
||||
let num = Math.random() * 100
|
||||
if (num < cfg.params.failRate) {
|
||||
throw new ZError(12, 'retweet failed')
|
||||
}
|
||||
task.status = TaskStatusEnum.SUCCESS
|
||||
task.timeFinish = Date.now()
|
||||
task.data = {}
|
||||
await this.params.user.save()
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,23 @@
|
||||
import { ActivityUser, TaskStatus } from "models/ActivityUser";
|
||||
import { ITask } from "./base/ITask";
|
||||
import { TaskCfg } from "models/ActivityInfo";
|
||||
|
||||
export default class UpdateScore extends ITask {
|
||||
static desc = 'update invite score'
|
||||
static show: boolean = false
|
||||
static auto: boolean = true
|
||||
async execute(data: any) {
|
||||
// do nothing
|
||||
}
|
||||
async check(data: any) {
|
||||
// do nothing
|
||||
let task = this.params.user.taskProgress.find((t: TaskStatus) => t.id === this.constructor.name)
|
||||
let cfg = this.params.activity.tasks.find((t: TaskCfg) => t.task === this.constructor.name)
|
||||
let scores = cfg.params.scores;
|
||||
for (let i = 0, l = scores.length; i < l; i++) {
|
||||
let score = scores[i]
|
||||
let user = await ActivityUser.findById(this.params.user.inviteUser)
|
||||
if (user) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -2,11 +2,11 @@
|
||||
export abstract class ITask {
|
||||
static desc: string
|
||||
static show: boolean = true
|
||||
static auto: boolean = false
|
||||
params: any
|
||||
constructor(params: any) {
|
||||
// do nothing
|
||||
this.params = params
|
||||
}
|
||||
abstract execute(data: any): Promise<void>
|
||||
abstract check(data: any): Promise<boolean>
|
||||
abstract execute(data: any): Promise<boolean>
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user