diff --git a/packages/backend/src/apps/twitter/actions.ts b/packages/backend/src/apps/twitter/actions.ts new file mode 100644 index 00000000..cabbb1c7 --- /dev/null +++ b/packages/backend/src/apps/twitter/actions.ts @@ -0,0 +1,9 @@ +import CreateTweet from './actions/create-tweet'; + +export default class Actions { + createTweet: any + + constructor(connectionData: any) { + this.createTweet = new CreateTweet(connectionData) + } +} diff --git a/packages/backend/src/apps/twitter/actions/create-tweet.ts b/packages/backend/src/apps/twitter/actions/create-tweet.ts new file mode 100644 index 00000000..cfaeb1aa --- /dev/null +++ b/packages/backend/src/apps/twitter/actions/create-tweet.ts @@ -0,0 +1,27 @@ +import TwitterApi from 'twitter-api-v2'; + +export default class CreateTweet { + client: any + parameters: any + + constructor(connectionData: any, parameters: any) { + this.client = new TwitterApi({ + appKey: connectionData.consumerKey, + appSecret: connectionData.consumerSecret, + accessToken: connectionData.accessToken, + accessSecret: connectionData.accessSecret + }); + + this.parameters = parameters; + } + + async run() { + const response = await this.client.currentUser(); + const username = response.screen_name; + + const userTimeline = await this.client.v1.userTimelineByUsername(username); + const fetchedTweets = userTimeline.tweets; + + return fetchedTweets[0]; + } +} diff --git a/packages/backend/src/apps/twitter/index.ts b/packages/backend/src/apps/twitter/index.ts index 837cbc7f..251848d4 100644 --- a/packages/backend/src/apps/twitter/index.ts +++ b/packages/backend/src/apps/twitter/index.ts @@ -1,12 +1,15 @@ import Authentication from './authentication'; import Triggers from './triggers'; +import Actions from './actions'; export default class Twitter { authenticationClient: any triggers: any + actions: any constructor(connectionData: any) { this.authenticationClient = new Authentication(connectionData); this.triggers = new Triggers(connectionData); + this.actions = new Actions(connectionData); } } diff --git a/packages/backend/src/apps/twitter/info.json b/packages/backend/src/apps/twitter/info.json index 4818080a..b0909e42 100644 --- a/packages/backend/src/apps/twitter/info.json +++ b/packages/backend/src/apps/twitter/info.json @@ -226,5 +226,19 @@ "key": "userTweet", "description": "Will be triggered when a specific user tweet something new." } + ], + "actions": [ + { + "name": "Create Tweet", + "key": "createTweet", + "description": "Will create a tweet.", + "parameters" : [ + { + "name": "Message", + "key": "message", + "required": true + } + ] + } ] } diff --git a/packages/backend/src/db/migrations/20211122140336_create_flows.ts b/packages/backend/src/db/migrations/20211122140336_create_flows.ts new file mode 100644 index 00000000..693c8d27 --- /dev/null +++ b/packages/backend/src/db/migrations/20211122140336_create_flows.ts @@ -0,0 +1,15 @@ +import { Knex } from "knex"; + +export async function up(knex: Knex): Promise { + return knex.schema.createTable('flows', (table) => { + table.increments('id'); + table.string('name'); + table.integer('user_id').references('id').inTable('users'); + + table.timestamps(true, true); + }); +}; + +export async function down(knex: Knex): Promise { + return knex.schema.dropTable('flows'); +} diff --git a/packages/backend/src/db/migrations/20211122140612_add_flow_id_to_steps.ts b/packages/backend/src/db/migrations/20211122140612_add_flow_id_to_steps.ts new file mode 100644 index 00000000..fb9f6b88 --- /dev/null +++ b/packages/backend/src/db/migrations/20211122140612_add_flow_id_to_steps.ts @@ -0,0 +1,17 @@ +import { Knex } from "knex"; + +export async function up(knex: Knex): Promise { + return knex.schema.table('steps', (table) => { + table + .integer('flow_id') + .references('id') + .inTable('flows'); + }); +} + + +export async function down(knex: Knex): Promise { + return knex.schema.table('steps', (table) => { + table.dropColumn('flow_id'); + }); +} diff --git a/packages/backend/src/graphql/mutations/create-connection.ts b/packages/backend/src/graphql/mutations/create-connection.ts index cc97ab62..b7c63a23 100644 --- a/packages/backend/src/graphql/mutations/create-connection.ts +++ b/packages/backend/src/graphql/mutations/create-connection.ts @@ -11,6 +11,7 @@ type Params = { } const createConnectionResolver = async (params: Params, req: RequestWithCurrentUser) => { const app = App.findOneByKey(params.key); + const connection = await Connection.query().insert({ key: params.key, data: params.data, diff --git a/packages/backend/src/graphql/mutations/create-flow.ts b/packages/backend/src/graphql/mutations/create-flow.ts new file mode 100644 index 00000000..35a53684 --- /dev/null +++ b/packages/backend/src/graphql/mutations/create-flow.ts @@ -0,0 +1,18 @@ +import Flow from '../../models/flow'; +import flowType from '../types/flow'; +import RequestWithCurrentUser from '../../types/express/request-with-current-user'; + +const createFlowResolver = async (req: RequestWithCurrentUser) => { + const flow = await Flow.query().insert({ + userId: req.currentUser.id + }); + + return flow; +} + +const createFlow = { + type: flowType, + resolve: (_: any, _params: any, req: RequestWithCurrentUser) => createFlowResolver(req) +}; + +export default createFlow; diff --git a/packages/backend/src/graphql/root-mutation.ts b/packages/backend/src/graphql/root-mutation.ts index a5f616de..28ea87c3 100644 --- a/packages/backend/src/graphql/root-mutation.ts +++ b/packages/backend/src/graphql/root-mutation.ts @@ -5,6 +5,7 @@ import updateConnection from './mutations/update-connection'; import resetConnection from './mutations/reset-connection'; import verifyConnection from './mutations/verify-connection'; import deleteConnection from './mutations/delete-connection'; +import createFlow from './mutations/create-flow'; import createStep from './mutations/create-step'; import executeStep from './mutations/execute-step'; @@ -17,6 +18,7 @@ const rootMutation = new GraphQLObjectType({ resetConnection, verifyConnection, deleteConnection, + createFlow, createStep, executeStep } diff --git a/packages/backend/src/graphql/types/flow.ts b/packages/backend/src/graphql/types/flow.ts new file mode 100644 index 00000000..5509cf56 --- /dev/null +++ b/packages/backend/src/graphql/types/flow.ts @@ -0,0 +1,10 @@ +import { GraphQLObjectType, GraphQLString } from 'graphql'; + +const flowType = new GraphQLObjectType({ + name: 'Flow', + fields: { + name: { type: GraphQLString } + } +}) + +export default flowType; diff --git a/packages/backend/src/models/flow.ts b/packages/backend/src/models/flow.ts new file mode 100644 index 00000000..04e3f27b --- /dev/null +++ b/packages/backend/src/models/flow.ts @@ -0,0 +1,31 @@ +import Base from './base' +import Step from './step' + +class Flow extends Base { + id!: number + userId!: number + + static tableName = 'flows'; + + static jsonSchema = { + type: 'object', + + properties: { + id: { type: 'integer' }, + userId: { type: 'integer' } + } + } + + static relationMappings = () => ({ + steps: { + relation: Base.HasManyRelation, + modelClass: Step, + join: { + from: 'flows.id', + to: 'steps.flow_id', + }, + } + }) +} + +export default Flow; diff --git a/packages/backend/src/models/step.ts b/packages/backend/src/models/step.ts index 6dc01156..fad3d37c 100644 --- a/packages/backend/src/models/step.ts +++ b/packages/backend/src/models/step.ts @@ -1,4 +1,5 @@ import Base from './base' +import Flow from './flow' enum StepEnumType { 'trigger', @@ -28,6 +29,17 @@ class Step extends Base { parameters: { type: 'object' }, } } + + static relationMappings = () => ({ + flow: { + relation: Base.BelongsToOneRelation, + modelClass: Flow, + join: { + from: 'step.flow_id', + to: 'flows.id', + }, + } + }) } export default Step;