APIs & Integrations

RMandhan
Member

Custom workflow action

Hello,

 

I have created one custom app in node.js to create a custom workflow action and I have successfully integrated that app with the HubSpot public app. I have also installed this public app in Test HubSpot Account and it is visible in connected apps section in settings section. I have to use this installed public app in workflow. I have checked this app in connected apps section in workflow action section but it is not available there. It is not visible in workflow section. Is there any way to show the workflow custom action in the workflow section ?

5 Replies 5
zomer
Participant

Custom workflow action

Did you figure this out? I'm experiencing the same issue where the custom action is not visible in the test account.

0 Upvotes
RMandhan
Member

Custom workflow action

Yes , I found the solution for this,  You need to add published : true key and value in you workflow action definition. Like this -

 

//
{
"actionUrl":"https://webhook.site/94d09471-6f4c-4a7f-bae2-c9a585dd41e0",
"objectTypes":[
"CONTACT"
],
"inputFields":[
{
"typeDefinition":{
"name":"staticInput",
"type":"string",
"fieldType":"text"
},
"supportedValueTypes":[
"STATIC_VALUE"
],
"isRequired":true
},
{
"typeDefinition":{
"name":"objectInput",
"type":"string",
"fieldType":"text"
},
"supportedValueTypes":[
"OBJECT_PROPERTY"
],
"isRequired":true
},
{
"typeDefinition":{
"name":"optionsInput",
"type":"enumeration",
"fieldType":"select",
"optionsUrl":"https://webhook.site/94d09471-6f4c-4a7f-bae2-c9a585dd41e0"
},
"supportedValueTypes":[
"STATIC_VALUE"
]
}
],
"inputFieldDependencies":[
{
"dependencyType":"SINGLE_FIELD",
"dependentFieldNames":[
"objectInput"
],
"controllingFieldName":"staticInput"
}
],
"outputFields":[
{
"typeDefinition":{
"name":"myOutput",
"type":"string",
"fieldType":"text"
},
"supportedValueTypes":[
"STATIC_VALUE"
]
}
],
"objectRequestOptions":{
"properties":[
"email"
]
},
"labels":{
"en":{
"inputFieldLabels":{
"staticInput":"Static Input",
"objectInput":"Object Property Input",
"optionsInput":"External Options Input"
},
"actionName":"My Extension",
"actionDescription":"My Extension Description",
"appDisplayName":"My App Display Name",
"actionCardContent":"My Action Card Content"
}
},
"functions":[
{
"functionType":"POST_ACTION_EXECUTION",
"functionSource":"exports.main = (event, callback) => {\r\n callback({\r\n outputFields: {\r\n myOutput: \"example output value\"\r\n }\r\n });\r\n}"
},
{
"functionType":"POST_FETCH_OPTIONS",
"functionSource":"exports.main = (event, callback) => {\r\n callback({\r\n \"options\": [{\r\n \"label\": \"Big Widget\",\r\n \"description\": \"Big Widget\",\r\n \"value\": \"10\"\r\n },\r\n {\r\n \"label\": \"Small Widget\",\r\n \"description\": \"Small Widget\",\r\n \"value\": \"1\"\r\n }\r\n ]\r\n });\r\n}"
}
],

published : true
}

0 Upvotes
YusriM
Member

Custom workflow action

Hi @RMandhan - how are you testing the action? I have a test account where I installed my test app, but I can't create workflows without upgrading my test account where the app is installed.

0 Upvotes
Jaycee_Lewis
Community Manager
Community Manager

Custom workflow action

Hi, @RMandhan 👋 Thanks for including all those details. 

 

One question that I don't see answered in your post, have you created your custom workflow action as per the guide here: Custom Workflow Actions?

 

Thanks! — Jaycee

linkedin

Jaycee Lewis

Developer Community Manager

Community | HubSpot

0 Upvotes
RMandhan
Member

Custom workflow action

Hello @Jaycee_Lewis 

Yes , I have created the workflow action as per he custom workflow action guide.

Below is the code -

 

// server.js
const express = require('express');
const https = require('https');
const fs = require('fs');
const customActionHandler = require('./actionHandler');
const bodyParser = require('body-parser');
const axios = require('axios');
require('dotenv').config();

const options = {
key: fs.readFileSync('./server.key'),
cert: fs.readFileSync('./server.cert')
};

// Create an Express app
const app = express();

const hubspot = require('@hubspot/api-client');
const hubspotClient = new hubspot.Client({"developerApiKey":process.env.HUBSPOT_API_KEY});

const appId = process.env.APP_ID;
const limit = undefined;
const after = undefined;
const archived = false;

app.use(bodyParser.urlencoded({
extended: true
}));


app.get('/generate_refresh_token', (req, res) => {
// Generate refresh and initial access token.

let code = req.query.code;
if(code != " ")
{
console.log('Code'+code);
let url = "https://api.hubapi.com/oauth/v1/token";
let postData = {
grant_type:"authorization_code",
client_id:process.env.CLIENT_ID,
client_secret:process.env.CLIENT_SECRTET,
redirect_uri:"https://localhost:3000/generate_refresh_token",
code: code
};
axios.post(url, postData, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
}})
.then(response => {
// Handle the API response
console.log(response);
//return response;
res.redirect('https://localhost:3000/create_custom_action');
})
.catch(error => {
// Handle errors
console.error(error);
});
}
});

app.get('/create_custom_action', (req, res) => {
async function call_api(){

const ExtensionActionDefinitionInput = {
actionUrl: "https://localhost:3000/create_custom_action",
inputFields: [
{
"typeDefinition": {
"name": "widgetName",
"type": "string",
"fieldType": "text"
},
"supportedValueTypes": ["STATIC_VALUE"],
"isRequired": true
},
{
"typeDefinition": {
"name": "widgetColor",
"type": "enumeration",
"fieldType": "select",
"options": [
{ "value": "red", "label": "Red" },
{ "value": "blue", "label": "Blue" },
{ "value": "green", "label": "Green" }
]
},
"supportedValueTypes": ["STATIC_VALUE"]
},
{
"typeDefinition": {
"name": "widgetOwner",
"type": "enumeration",
"referencedObjectType": "OWNER"
},
"supportedValueTypes": ["STATIC_VALUE"]
},
{
"typeDefinition": {
"name": "widgetQuantity",
"type": "number"
},
"supportedValueTypes": ["OBJECT_PROPERTY"]
}
],
labels: {
"en": {
"actionName": "Create Widget - Example 1",
"actionDescription": "This action will create a new widget in our system. So cool!",
"actionCardContent": "Create widget {{widgetName}}",
"inputFieldLabels": {
"widgetName": "Widget Name",
"widgetColor": "Widget Color",
"widgetOwner": "Widget Owner",
"widgetQuantity": "Widget Quantity"
},
"inputFieldDescriptions": {
"widgetName": "Enter the full widget name. I support <a href=\"https://hubspot.com\">links</a> too.",
"widgetColor": "This is the color that will be used to paint the widget."
}
}
},
objectTypes: ["CONTACT", "DEAL"]
};


var output_response = {
error : "Something went wrong"
}
try {
const apiResponse = await hubspotClient.automation.actions.definitionsApi.create(appId, ExtensionActionDefinitionInput);
//console.log(JSON.stringify(apiResponse, null, 2));
output_response = JSON.stringify(apiResponse, null, 2);

} catch (e) {
e.message === 'HTTP request failed'
? console.error(JSON.stringify(e.response, null, 2))
: console.error(e)

output_response = JSON.stringify(e.response, null, 2);
}

res.json(output_response);
}

call_api();

});

const server = https.createServer(options, app);
const port = 3000; // or any other port you prefer

server.listen(port, () => {
console.log(`Server running on https://localhost:${port}`);
});

 

Thanks & Regards,

Richa Mandhan

0 Upvotes