Try it out
Apps
Blog
About
Contact
Developers
Docs
Login
Developers
ask@obindo.com
Written by
Chuck
Ask me what's going on in your obindo dashboard.
//#region PRIVATE set my oauth2 credentials var webhookUrl= 'https://connect.obindo.com/webhooks/slack'; var imageUrl= 'https://connect.obindo.com/images/slacktopus%2040.png'; var appEmailAddress= 'chuck@obindohq.com'; var connectAPIHost = 'https://connect.obindo.com'; var invalidDomains = ['gmail.com', 'outlook.com', 'yahoo.com', 'hotmail.com', 'comcast.net'] obindo.getRouting= function() { return { account: appEmailAddress }; } // PARSING // { source, text } source= subject, text, or question function getMention() { if (validText(message.strippedText)) return getMentionFromText(message.strippedText); if (validText(message.text)) return getMentionText(message.text); if (validText(message.subject)) return { source: 'subject', text: message.subject }; return { text: '', source: 'text' }; function validText(s) { return (s && s.length > 0); } } //return source = text (whole text) or = question (Hey Obindo) if found function getMentionFromText(s) { var text= s.replace(/\r/g,'').replace(/\n/g,'\n\n'); var pGreet= new RegExp(/(^|\n)(hey |hi |hello |say |ask |@)obindo ?[—,\:\-]?\s+/ig); text= text.replace(pGreet, replaceGreeting); var ltext= text.toLowerCase(); var p= new RegExp(/(^|\n| )(hey |hi |hello |say |ask |@)obindo\b/gi); var m; var lastMention= ''; while (m= p.exec(text)) { if (isValidMatch(m)) lastMention= util.trim(getLine(m.index)); } return (lastMention == '' ) ? { source: 'text', text: s } : { source: 'question', text: lastMention }; function getLine(index) { var start= text.lastIndexOf('\n',index+1); var end= text.indexOf('\n', index+1); if (start < 0) start= 0; return (end < 0) ? text.substring(start) : text.substring(start, end); } function isValidMatch(m) { var i= ltext.indexOf('obindo', m.index); if (i < 0) return false; //shouldn't happen var i2= ltext.indexOf('obindo.com', m.index); return (i != i2); } function replaceGreeting(s) { return util.trim(s) + ' '; } } function getAction(mention,ccs) { //gcalendar app request if 1. date found 2. scheduling word found if (mention.source == 'question' && util.getDates(mention.text).length > 0) { var p= new RegExp(/\b(schedule|meeting|calendar|event|remind)\b/gi); if (p.test(mention.text)) { var sel= { title: message.subject, datetime: mention.text }; if (ccs.length > 0) sel.attendees= ccs; return { type: 'app', app: 'gcalendar', subject: mention.text, metadata: { source: 'getstarted', selections: sel } }; } } return { type: 'question', text: mention.text }; } function getCcs() { var arr= []; addCcs(message.to); addCcs(message.cc); return arr; function addCcs(users) { if (!users) return; for (var i=0; i < users.length; i++) addCc(users[i]); } function addCc(user) { if (user.emailAddress.indexOf('@obindo.com') < 0) arr.push(user); } } // ADDING APP MESSAGE function sendToApp(action) { var m= createAppMessage(action); addMessage(m); } function createAppMessage(action) { var name= action.app; var appemail= name + '@obindo.com'; var m= { from: message.from, to: [{emailAddress: appemail }], inbox: appemail , currentJob: 'METADATAPARSER', sentDate: message.sentDate, subject: action.subject, sentDateOffset: message.sentDateOffset, sentDateText: message.sentDateText }; if (message.fullText) m.text= message.fullText; if (message.html) m.html= message.html; if (action.metadata) m.metadata= action.metadata; return m; } function addMessage(m) { var args= { url: 'https://www.obindo.com/api/v1/messages', header: { "Authorization": "Basic " + obindoAuth }, checkHttpStatus: false }; //addMessage only, status might not be 200 if (message.files && message.files.length > 0) { var arrContent= []; args.args= []; for (var i=0; i < message.files.length; i++) { var file= message.files[i]; var name= getFilename(file.name, i); var content= { name: name, originalName: file.name }; if (file.embedId) content.embedId= file.embedId; arrContent.push(content); args.args.push({ value: file, fileName: name, contentType: file.contentType }); } if (!m.metadata) m.metadata= {}; m.metadata.contentMap= arrContent; args.args.splice(0, 0, { value: util.stringify(m) }); } else { args.body= util.stringify(m); args.header["Content-Type"]= "application/json"; } var response= post(args); return util.jsonify(response.text).message; function getFilename(name, i) { var index= (name) ? name.lastIndexOf('.') : -1; return (index >= 0) ? i + name.substring(index) : i + ''; } } // BOT RESPONSES function getBotResponse(text, user) { var args= { emailAddress: user.emailAddress, text: text, userName: '' }; var response= post({ url: webhookUrl, body: util.stringify(args), header: { "Content-Type": "application/json", "Authorization": "Bearer " + connectAuth }}); if (response.status != 200) return ''; return util.jsonify(response.text); } function getDefaultResponse() { return '<p style="margin: 0px; padding: 0px;">Sorry, I don\'t have anything for you on that right now!</p> ' + '<p>Just as a reminder, whenever you need something, email me at ask@obindo.com. You can ask me things like this:</p> ' + '<p>Hey Obindo, what should I know about rocket ships?<br> ' + 'Hey Obindo, what\'s the latest on the space station?<br> ' + 'Hey Obindo, who should I talk to about Mars?</p> ' + '<p>And when you want to teach me something new, email me at save@obindo.com ' + 'and put the name of the topic you are describing in the subject line.</p>'; } function cleanHtml(h) { if (h == '') return ''; var html= h.replace(/^Hi[ \w]*[,!]\s*/g, ''); html= html.replace(/\<([^\|]+)\|([^>]+)>/ig, cleanLinks); html= html.replace(/( *\n)+/g,'\n</p><p>'); return '<p style="margin: 0px; padding: 0px;">' + html + '</p>'; function cleanLinks(s, url, text) { return '<a href="'+ url + '" style="text-decoration: none; color: #13948a;">' + text +'</a>'; } } function getSubject(o) { if (o.resultsFound !== undefined) { //summary, important, people, updates var wordCount= getWordCount(o.topic); var topicPhrase= (wordCount >=1 && wordCount <= 5) ? o.topic : 'that'; if (!o.resultsFound) return 'I couldn\'t find anything on '+ topicPhrase +' for you'; else if (wordCount > 0) // topic exists return 'I found some information on ' + topicPhrase + ' for you'; else return 'Here\'s what I know'; } //badrequest, text, nouser, confused if (o.type == 'confused') return 'I didn\'t understand your question'; else if (o.type == 'text') return 'Here\'s what I know'; else return 'I couldn\'t find anything on that for you'; function getWordCount(text) { return (!text) ? 0 : util.trim(text).replace(/\s+/g,' ').split(' ').length; } } function isValidResponse(r) { return (r && r.text && r.text.length > 0 && r.type && r.type != 'badrequest' && r.type != 'nouser' && r.type != 'confused'); } function sendResponse(text,ccs) { var args= { to: message.from, fromName: 'Obindo', template: 'app', html: '', templateFields: { recipientName: message.from.name, templateKey: 'email-template-ask', user: { name: 'Obindo', imageUrl: imageUrl } } }; if (ccs.length > 0) args.cc= ccs; var response= getBotResponse(text, message.from); args.response= response; args.subject= getSubject(response); if (isValidResponse(response)) { args.html= cleanHtml(response.text); if (args.html != '' && response.resultsFound !== undefined && !response.resultsFound) { args.html+= '<p>But would you like to teach me about this topic? Just email me at ' + 'save@obindo.com, put the name of this topic in the subject line, ' + 'and I\'ll learn this for next time.</p>'; } } if (args.html == '') //not valid or cleanHtml returned empty args.html= getDefaultResponse(); sendEmail(args); } function getUser() { if (!message || !message.from || !message.from.emailAddress) return {"error" : "Invalid email address"}; var args= { url: connectAPIHost+'/api/users', header: { "Authorization": "Bearer " + connectAuth }}; args.args = {}; args.args.emailAddress = message.from.emailAddress; var response= get(args); var o = util.jsonify(response.text); if (o && o.user) return o.user; return null; } function isValidFromAddress(emailAddress) { if (!emailAddress) return false; for (var i=0; i<invalidDomains.length; i++) { if (emailAddress.toLowerCase().indexOf('@'+invalidDomains[i]) > -1) return false; } return true; } function getInvalidEmailAddressBody() { return '<p style="margin: 0px; padding: 0px;">'+ 'My job is to help you share information with others in your company '+ '-- but you sent me that message from your personal inbox so I couldn\'t '+ 'figure out where that should go.</p>' + '<p>Could you resend me that from your work email?</p> '; } function getNewUserBody() { return '<p style="margin: 0px; padding: 0px;">'+ 'Thanks for your message! Now come <a style="text-decoration: none; color: #13948a;" '+ 'href="https://connect.obindo.com">check out</a> '+ 'the knowledge base I\'m building for your organization! '+ '(And let\'s chat in Slack too!)</p>'; } function sendInvalidEmailAddressResponse() { var args= { to: message.from, fromName: 'Obindo', template: 'app', html: '', templateFields: { recipientName: message.from.name, templateKey: 'email-template-ask', user: { name: 'Obindo', imageUrl: imageUrl } } }; var response= getInvalidEmailAddressBody(); args.response= response; args.subject= 'Could you resend me that from your work email?'; args.html= response sendEmail(args); } function sendNewUserResponse() { var args= { to: message.from, fromName: 'Obindo', template: 'app', html: '', templateFields: { recipientName: message.from.name, templateKey: 'email-template-ask', user: { name: 'Obindo', imageUrl: imageUrl } } }; var response= getNewUserBody(); args.response= response; args.subject= 'Thanks for your message!'; args.html= response sendEmail(args); } $(function() { if (!isValidFromAddress(message.from.emailAddress)) { sendInvalidEmailAddressResponse(); return; } var ccs= getCcs(); var mention= getMention(); if (mention.source != 'question') return; //ignore unless "hey obindo" etc is found var action= getAction(mention,ccs); if (action.type == 'app') sendToApp(action); else if (action.type == 'question') sendResponse(action.text,ccs); });