我正在通过zapier-cli创建一个zapier应用-我遇到了create
操作的问题:
这是应用程序代码:
const authentication = require('./authentication');
const response = require('./creates/response');
const workspace = require('./triggers/workspace');
const form = require('./triggers/form');
const includeAccessTokenHeader = (request, z, bundle) => {
if(bundle.authData.access_token) {
request.headers = request.headers || {};
request.headers['Authorization'] = `Bearer ${bundle.authData.access_token}`
}
}
const tokenRefreshIf401 = (response, z, bundle) => {
if(bundle.authData.access_token) {
if(response.status === 401) {
throw new z.errors.RefreshAuthError('Access token needs refreshing');
}
}
return response;
}
// We can roll up all our behaviors in an App.
const App = {
// This is just shorthand to reference the installed dependencies you have. Zapier will
// need to know these before we can upload
version: require('./package.json').version,
platformVersion: require('zapier-platform-core').version,
authentication: authentication,
// beforeRequest & afterResponse are optional hooks into the provided HTTP client
beforeRequest: [
//includeAccessTokenHeader
],
afterResponse: [
tokenRefreshIf401
],
// If you want to define optional resources to simplify creation of triggers, searches, creates - do that here!
resources: {
},
// If you want your trigger to show up, you better include it here!
triggers: {
[workspace.key]: workspace,
[form.key]: form
},
// If you want your searches to show up, you better include it here!
searches: {
},
// If you want your creates to show up, you better include it here!
creates: {
[response.key]: response
}
};
// Finally, export the app.
module.exports = App;
以下是响应动作:
const questionFields = require('../fields/questions');
const createResponse = (z, bundle) => {
z.console.log("Final input to be sent", bundle.inputData);
const options = {
url: 'https://sametrica-zapier.free.beeceptor.com/my/api/path',
method: 'POST',
headers: {
'Accept': 'application/json',
'content-type': 'application/json',
'Authorization': `Bearer ${bundle.authData.access_token}`
},
body: bundle.inputData
}
// You may return a promise or a normal data structure from any perform method.
return z.request(options)
.then((response) => {
response.throwForStatus();
return z.JSON.parse(response.content);
});
};
// We recommend writing your creates separate like this and rolling them
// into the App definition at the end.
module.exports = {
key: 'response',
// You'll want to provide some helpful display labels and descriptions
// for users. Zapier will put them into the UX.
noun: 'Response',
display: {
label: 'Create Response',
description: 'Creates a new response.'
},
// `operation` is where the business logic goes.
operation: {
inputFields: [
{
key: 'workspace',
required: true,
dynamic: 'get_workspaces.id.name',
altersDynamicFields: true,
},
{
key: 'form',
required: true,
dynamic: 'get_forms.id.title_en',
altersDynamicFields: true,
},
questionFields.fetchQuestions
],
perform: createResponse,
// In cases where Zapier needs to show an example record to the user, but we are unable to get a live example
// from the API, Zapier will fallback to this hard-coded sample. It should reflect the data structure of
// returned records, and have obviously dummy values that we can show to any user.
sample: {
id: 1,
createdAt: 1472069465,
name: 'Best Spagetti Ever',
authorId: 1,
directions: '1. Boil Noodles\n2.Serve with sauce',
style: 'italian'
},
// If the resource can have fields that are custom on a per-user basis, define a function to fetch the custom
// field definitions. The result will be used to augment the sample.
// outputFields: () => { return []; }
// Alternatively, a static field definition should be provided, to specify labels for the fields
outputFields: [
{key: 'id', label: 'ID'},
{key: 'createdAt', label: 'Created At'},
{key: 'name', label: 'Name'},
{key: 'directions', label: 'Directions'},
{key: 'authorId', label: 'Author ID'},
{key: 'style', label: 'Style'}
]
}
};
这是触发问题的地方:
const makeField = (question, z) => {
let field = {
key: question.id,
label: question.title_en,
required: (question.is_optional === 0),
};
return field;
switch(question.question_type.type) {
case 'multiple_fields':
let newField = {
key: question.id,
label: question.title_en,
//required: (question.is_optional === 0),
children: makeMultipleFieldsField(question)
};
z.console.log("Multiple Field", newField);
return newField;
break;
default:
return field;
}
};
const makeRadioField = (question) => {
let choices = question.options.map(option => {
return {
key: option.id,
label: option.title_en
}
});
return {
choices
};
};
const makeMultipleFieldsField = (question) => {
let children = question.options.map(option => {
return {
key: option.id,
label: option.title_en
}
});
return children;
}
const fetchQuestions = async function(z, bundle) {
z.console.log("Check if inputData has form @ fetchQuestions", bundle.inputData);
const options = {
url: `http://my-endpoint.ca/api/forms/${bundle.inputData.form}/respond`,
method: 'GET',
headers: {
'Accept': 'application/json',
'content-type': 'application/json',
'Authorization': `Bearer ${bundle.authData.access_token}`
}
}; // EO options
let response = await z.request(options);
response.throwForStatus();
const result = z.JSON.parse(response.content);
let fieldArray = [];
// get pages
const pages = result.pages;
pages.forEach(function(page) {
const sections = page.sections;
sections.forEach(function(section) {
const questions = section.questions;
questions.forEach(function(question) {
// fieldArray.push({
// key: question.id,
// label: question.title_en,
// type: 'string'
// });
let field = makeField(question, z);
fieldArray.push(field);
}); // EO forEach questions
}); // EO forEach sections
}); // EO forEach pages
z.console.log("Fields Array", fieldArray);
return fieldArray;
} // EO fetchForms()
module.exports = {
makeField,
makeRadioField,
fetchQuestions
}
我得到的错误是:
'int' object has no attribute 'replace'