Skip to content
This repository was archived by the owner on Sep 20, 2024. It is now read-only.

Commit afd2136

Browse files
Merge pull request #1 from jonchurch/pr-handover-rebase
Fixes for Botkit v0.6
2 parents 953f26b + d42f1f2 commit afd2136

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+4773
-1168
lines changed

CODE_OF_CONDUCT.md

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Contributor Covenant Code of Conduct
2+
3+
## Our Pledge
4+
5+
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
6+
7+
## Our Standards
8+
9+
Examples of behavior that contributes to creating a positive environment include:
10+
11+
* Using welcoming and inclusive language
12+
* Being respectful of differing viewpoints and experiences
13+
* Gracefully accepting constructive criticism
14+
* Focusing on what is best for the community
15+
* Showing empathy towards other community members
16+
17+
Examples of unacceptable behavior by participants include:
18+
19+
* The use of sexualized language or imagery and unwelcome sexual attention or advances
20+
* Trolling, insulting/derogatory comments, and personal or political attacks
21+
* Public or private harassment
22+
* Publishing others' private information, such as a physical or electronic address, without explicit permission
23+
* Other conduct which could reasonably be considered inappropriate in a professional setting
24+
25+
## Our Responsibilities
26+
27+
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
28+
29+
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
30+
31+
## Scope
32+
33+
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
34+
35+
## Enforcement
36+
37+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [email protected]. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
38+
39+
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
40+
41+
## Attribution
42+
43+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
44+
45+
[homepage]: http://contributor-covenant.org
46+
[version]: http://contributor-covenant.org/version/1/4/

CONTRIBUTING.md

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ possible with your report. If you can, please include:
2121

2222
## Submitting Pull Requests
2323

24+
* Pull requests should contain a concise topic and detailed accompanying text that clearly indentifies both the purpose and justification for acceptance of any changes.
2425
* Create, or link to an existing issue identifying the need driving your PR request. The issue can contain more details of the need for the PR as well as host debate as to which course of action the PR will take that will most serve the common good.
2526
* Include screenshots and animated GIFs in your pull request whenever possible.
2627
* Follow the JavaScript coding style with details from `.jscsrc` and `.editorconfig` files and use necessary plugins for your text editor.

__test__/lib/Botkit.test.js

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ jest.mock('../../lib/TwilioSMSBot', () => 'twiliosms');
1010
jest.mock('../../lib/BotFramework', () => 'botframework');
1111
jest.mock('../../lib/CiscoSparkbot', () => 'spark');
1212
jest.mock('../../lib/ConsoleBot', () => 'console');
13+
jest.mock('../../lib/Teams', () => 'teams');
1314

1415
beforeEach(() => {
1516
jest.clearAllMocks();
@@ -24,5 +25,6 @@ test('exports bot interfaces', () => {
2425
expect(botkit.twiliosmsbot).toBe('twiliosms');
2526
expect(botkit.botframeworkbot).toBe('botframework');
2627
expect(botkit.sparkbot).toBe('spark');
28+
expect(botkit.teamsbot).toBe('teams');
2729
expect(botkit.consolebot).toBe('console');
2830
});

bin/cli.js

+239
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
#!/usr/bin/env node
2+
3+
var Vorpal = require('vorpal');
4+
var chalk = Vorpal().chalk;
5+
var exec = require('child_process').exec
6+
var fs = require('fs');
7+
8+
var botkit = Vorpal()
9+
10+
var platforms = ['web', 'teams', 'spark', 'slack', 'facebook'];
11+
var platform_src = [{
12+
platform: 'web',
13+
artifact: 'https://github.com/howdyai/botkit-starter-web.git',
14+
directory: 'botkit-starter-web'
15+
},
16+
{
17+
platform: 'teams',
18+
artifact: 'https://github.com/howdyai/botkit-starter-teams.git',
19+
directory: 'botkit-starter-teams'
20+
},
21+
{
22+
platform: 'spark',
23+
artifact: 'https://github.com/howdyai/botkit-starter-ciscospark.git',
24+
directory: 'botkit-starter-ciscospark'
25+
},
26+
{
27+
platform: 'slack',
28+
artifact: 'https://github.com/howdyai/botkit-starter-slack.git',
29+
directory: 'botkit-starter-slack'
30+
},
31+
{
32+
platform: 'facebook',
33+
artifact: 'https://github.com/howdyai/botkit-starter-facebook.git',
34+
directory: 'botkit-starter-facebook'
35+
}
36+
];
37+
38+
var bot_vars;
39+
40+
41+
function makeDirname(name) {
42+
43+
var dirname = name.toLowerCase().replace(/\s+/g, '_');
44+
return dirname;
45+
}
46+
47+
function askBotName(i) {
48+
return new Promise(function(resolve, reject) {
49+
var self = i;
50+
if (bot_vars.name) {
51+
resolve(bot_vars.name);
52+
} else {
53+
self.prompt({
54+
type: 'input',
55+
name: 'name',
56+
message: chalk.bold('What would you like to name your bot?\n> ')
57+
}, function(result) {
58+
if (result.name) {
59+
bot_vars.name = result.name;
60+
resolve(result.name);
61+
} else {
62+
reject({});
63+
}
64+
});
65+
}
66+
});
67+
}
68+
69+
70+
function askBotPlatform(i) {
71+
return new Promise(function(resolve, reject) {
72+
var self = i;
73+
if (bot_vars.platform) {
74+
resolve(bot_vars.platform);
75+
} else {
76+
self.prompt({
77+
type: 'list',
78+
choices: platforms,
79+
name: 'platform',
80+
message: 'What platform will this bot live on?'
81+
}, function(result) {
82+
if (result.platform) {
83+
bot_vars.platform = result.platform;
84+
resolve(bot_vars.platform);
85+
} else {
86+
reject({});
87+
}
88+
});
89+
}
90+
});
91+
}
92+
93+
94+
function askStudioKey(i) {
95+
return new Promise(function(resolve, reject) {
96+
var self = i;
97+
if (bot_vars.studio_token) {
98+
resolve(bot_vars.studio_token);
99+
} else {
100+
self.prompt({
101+
type: 'input',
102+
name: 'studio_token',
103+
message: chalk.bold('(Optional) Please enter your Botkit Studio token. Get one from https://studio.botkit.ai\n> ')
104+
}, function(result) {
105+
if (result.studio_token) {
106+
bot_vars.studio_token = result.studio_token;
107+
resolve(bot_vars.studio_token);
108+
} else {
109+
resolve();
110+
}
111+
});
112+
}
113+
});
114+
}
115+
116+
117+
function getBotInput(self, bot_vars) {
118+
return new Promise(function(resolve, reject) {
119+
askBotName(self).then(function(name) {
120+
self.log(`Your bot shall be called ${name}!`);
121+
askBotPlatform(self).then(function(platform) {
122+
self.log(`We will build for the ${platform} platform!`);
123+
askStudioKey(self).then(function(key) {
124+
if (key) {
125+
self.log(`Botkit Studio APIs enabled!`);
126+
} else {
127+
self.log(`Your bot will not use Botkit Studio.`);
128+
}
129+
resolve(bot_vars);
130+
}).catch(reject);
131+
}).catch(reject);
132+
}).catch(reject);
133+
});
134+
}
135+
136+
function buildBotKit(i, bot_vars, cb) {
137+
var self = i;
138+
if (fs.existsSync(bot_vars.name)) {
139+
self.log('A bot called ' + bot_vars.name + ' already exist in this directory. Please try again with a different name.');
140+
cb();
141+
} else {
142+
self.log('Installing Botkit...')
143+
var target = platform_src.filter(function(p) {
144+
return p.platform === bot_vars.platform;
145+
});
146+
if (target.length > 0) {
147+
var now = new Date();
148+
var temp_folder_name = String(now.getTime());
149+
var folder_name = makeDirname(bot_vars.name);
150+
var action = 'git clone ' + target[0].artifact + ' ' + folder_name + '&& cd ' + folder_name + ' && npm install'
151+
exec(action, function(err, stdout, stderr) {
152+
if (err) {
153+
self.log('An error occured. You may already have that starter kit installed.');
154+
self.log('Error:', err);
155+
156+
cb();
157+
} else {
158+
self.log('Installing dependencies...');
159+
if (bot_vars.studio_token) {
160+
writeStudioToken(self, bot_vars, function() {
161+
self.log(chalk.bold('Installation complete! To start your bot, type:'));
162+
self.log('cd ' + folder_name + ' && node .');
163+
cb();
164+
});
165+
} else {
166+
self.log(chalk.bold('Installation complete! To start your bot, type:'));
167+
self.log('cd ' + folder_name + ' && node .');
168+
cb();
169+
}
170+
}
171+
});
172+
} else {
173+
bot_vars.platform = null;
174+
self.log('Please try again with a valid platform.');
175+
cb();
176+
}
177+
}
178+
}
179+
180+
function writeStudioToken(i, bot_vars, cb) {
181+
var self = i;
182+
self.log('Writing Botkit Studio token...')
183+
var dotenvfile = makeDirname(bot_vars.name) + '/.env'
184+
var line_replacement = 'studio_token=' + bot_vars.studio_token;
185+
fs.readFile(dotenvfile, 'utf8', function(err, data) {
186+
if (err) {
187+
self.log('An error occured: There was a problem reading ' + dotenvfile);
188+
cb();
189+
} else {
190+
var results = data.replace(/studio_token=/g, line_replacement);
191+
fs.writeFile(dotenvfile, results, 'utf8', function(err) {
192+
if (err) {
193+
self.log('An error occured: There was a problem writing ' + dotenvfile);
194+
cb();
195+
} else {
196+
self.log('Your Botkit Studio token has been written to ' + dotenvfile);
197+
cb();
198+
}
199+
});
200+
}
201+
})
202+
}
203+
204+
205+
botkit
206+
.command('new')
207+
.option('-n, --name [name]', 'Name of your Bot')
208+
.option('-p, --platform [platform]', 'Primary messaging platform')
209+
.option('-k, --studio_token [studio_token]', 'API token from Botkit Studio')
210+
.description('Configure a new Botkit-powered application')
211+
.action(function(args, cb) {
212+
var self = this;
213+
switch (args.obj) {
214+
default:
215+
case 'bot':
216+
bot_vars = {};
217+
if (args.options.name) {
218+
bot_vars.name = args.options.name
219+
}
220+
if (args.options.platform) {
221+
bot_vars.platform = args.options.platform;
222+
}
223+
if (args.options.studio_token) {
224+
bot_vars.studio_token = args.options.studio_token
225+
}
226+
getBotInput(self, bot_vars).then(function(res) {
227+
buildBotKit(self, bot_vars, cb);
228+
}).catch(function(err) {
229+
cb();
230+
});
231+
break;
232+
}
233+
});
234+
235+
236+
botkit
237+
.delimiter(chalk.magenta('botkit $'))
238+
.show()
239+
.parse(process.argv)

0 commit comments

Comments
 (0)