diff --git a/Gemfile.lock b/Gemfile.lock index 21e469e..d1f13e0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,125 +8,139 @@ GIT GEM remote: https://rubygems.org/ specs: - activemodel (3.2.8) - activesupport (= 3.2.8) - builder (~> 3.0.0) - activeresource (3.2.8) - activemodel (= 3.2.8) - activesupport (= 3.2.8) - activesupport (3.2.8) - i18n (~> 0.6) - multi_json (~> 1.0) - addressable (2.3.2) - akami (1.2.0) + activemodel (4.1.8) + activesupport (= 4.1.8) + builder (~> 3.1) + activeresource (4.0.0) + activemodel (~> 4.0) + activesupport (~> 4.0) + rails-observers (~> 0.1.1) + activesupport (4.1.8) + i18n (~> 0.6, >= 0.6.9) + json (~> 1.7, >= 1.7.7) + minitest (~> 5.1) + thread_safe (~> 0.1) + tzinfo (~> 1.1) + addressable (2.3.6) + akami (1.2.2) gyoku (>= 0.4.0) - nokogiri (>= 1.4.0) + nokogiri awesome_print (1.2.0) - bigcommerce (0.8.2) + bigcommerce (0.8.4) activesupport json rest-client - builder (3.0.3) - coderay (1.0.8) - coffee-script (2.2.0) + builder (3.2.2) + coderay (1.1.0) + coffee-script (2.3.0) coffee-script-source execjs - coffee-script-source (1.3.3) - diff-lcs (1.1.3) - eventmachine (1.0.0) - evernote-thrift (1.22.2) - execjs (1.4.0) - multi_json (~> 1.0) - faraday (0.8.4) - multipart-post (~> 1.1) - faraday_middleware (0.8.8) - faraday (>= 0.7.4, < 0.9) - flexmock (0.9.0) - flowdock (0.3.0) + coffee-script-source (1.8.0) + diff-lcs (1.2.5) + eventmachine (1.0.3) + evernote-thrift (1.25.1) + execjs (2.2.2) + faraday (0.9.0) + multipart-post (>= 1.2, < 3) + faraday_middleware (0.9.1) + faraday (>= 0.7.4, < 0.10) + flexmock (1.3.3) + flowdock (0.5.0) httparty (~> 0.7) multi_json gyoku (1.0.0) builder (>= 2.1.2) - haml (3.1.7) - hashie (1.2.0) - highrise (3.0.3) - activeresource (~> 3.0) - hipchat (0.7.0) - httparty + haml (4.0.6) + tilt + hashie (3.3.2) + highrise (3.2.1) + activeresource (>= 3.2.13) + hipchat (1.4.0) httparty - htmlentities (4.3.1) - httmultiparty (0.3.10) + htmlentities (4.3.2) + httmultiparty (0.3.16) httparty (>= 0.7.3) + mimemagic multipart-post http_parser.rb (0.5.3) - httparty (0.9.0) - multi_json (~> 1.0) - multi_xml + httparty (0.13.3) + json (~> 1.8) + multi_xml (>= 0.5.2) httpi (2.0.2) rack - i18n (0.6.1) - jaconda (2.0.2) + i18n (0.6.11) + jaconda (2.0.3) activeresource (>= 2.3.5) - json (1.7.5) - kgio (2.8.0) - libv8 (3.16.14.3) + json (1.8.1) + kgio (2.9.2) + libv8 (3.16.14.7) mab (0.0.3) - mail (2.4.4) - i18n (>= 0.4.0) - mime-types (~> 1.16) - treetop (~> 1.4.8) - method_source (0.8.1) - mime-types (1.19) - mock_redis (0.6.2) - multi_json (1.3.6) - multi_xml (0.5.1) - multipart-post (1.1.5) - nokogiri (1.5.5) + mail (2.6.3) + mime-types (>= 1.16, < 3) + method_source (0.8.2) + mime-types (2.4.3) + mimemagic (0.2.1) + mini_portile (0.6.1) + minitest (5.4.3) + mock_redis (0.13.2) + multi_json (1.10.1) + multi_xml (0.5.5) + multipart-post (2.0.0) + netrc (0.9.0) + nokogiri (1.6.5) + mini_portile (~> 0.6.0) nori (2.0.4) oauth (0.4.7) - polyglot (0.3.3) - pry (0.9.10) - coderay (~> 1.0.5) - method_source (~> 0.8) - slop (~> 3.3.1) - rack (1.4.1) - rack-protection (1.2.0) + pry (0.10.1) + coderay (~> 1.1.0) + method_source (~> 0.8.1) + slop (~> 3.4) + rack (1.5.2) + rack-protection (1.5.3) rack - rack-test (0.6.1) + rack-test (0.6.2) rack (>= 1.0) - rake (0.9.2.2) - redis (3.0.2) - redis-namespace (1.2.1) - redis (~> 3.0.0) + rails-observers (0.1.2) + activemodel (~> 4.0) + rake (10.4.2) + redis (3.1.0) + redis-namespace (1.5.1) + redis (~> 3.0, >= 3.0.4) ref (1.0.5) - rest-client (1.6.7) - mime-types (>= 1.16) - restforce (1.4.2) - faraday (~> 0.8.4) + rest-client (1.7.2) + mime-types (>= 1.16, < 3.0) + netrc (~> 0.7) + restforce (1.5.1) + faraday (~> 0.9.0) faraday_middleware (>= 0.8.8) - hashie (>= 1.2.0, < 2.1) + hashie (>= 1.2.0, < 4.0) json (>= 1.7.5, < 1.9.0) roxml (3.3.1) activesupport (>= 2.3.0) nokogiri (>= 1.3.3) - rspec (2.5.0) - rspec-core (~> 2.5.0) - rspec-expectations (~> 2.5.0) - rspec-mocks (~> 2.5.0) - rspec-core (2.5.2) - rspec-expectations (2.5.0) - diff-lcs (~> 1.1.2) - rspec-mocks (2.5.0) - ruby-trello (0.5.1) - activemodel + rspec (3.1.0) + rspec-core (~> 3.1.0) + rspec-expectations (~> 3.1.0) + rspec-mocks (~> 3.1.0) + rspec-core (3.1.7) + rspec-support (~> 3.1.0) + rspec-expectations (3.1.2) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.1.0) + rspec-mocks (3.1.3) + rspec-support (~> 3.1.0) + rspec-support (3.1.2) + ruby-trello (1.1.2) + activemodel (>= 3.2.0) addressable (~> 2.3) json oauth (~> 0.4.5) - rest-client (~> 1.6.7) - rubyzoho (0.1.7) - httmultiparty (>= 0.3.8) + rest-client (~> 1.7.2) + rubyzoho (0.2.0) + activemodel + httmultiparty multipart-post - roxml (>= 3.3.1) + roxml savon (2.1.0) akami (~> 1.2.0) builder (>= 2.1.2) @@ -136,34 +150,33 @@ GEM nori (~> 2.0.3) wasabi (~> 3.0.0) simple_oauth (0.1.9) - sinatra (1.3.2) - rack (~> 1.3, >= 1.3.6) - rack-protection (~> 1.2) - tilt (~> 1.3, >= 1.3.3) + sinatra (1.4.5) + rack (~> 1.4) + rack-protection (~> 1.4) + tilt (~> 1.3, >= 1.3.4) sinatra-initializers (0.1.4) - slop (3.3.3) - therubyracer (0.12.0) + slop (3.6.0) + therubyracer (0.12.1) libv8 (~> 3.16.14.0) ref - thor (0.16.0) - tilt (1.3.3) - tinder (1.9.1) - eventmachine (>= 0.12.0, < 2) - faraday (~> 0.8) - faraday_middleware (~> 0.8) - hashie (~> 1.0) - json (~> 1.6) - mime-types (~> 1.16) - multi_json (~> 1.0) - multipart-post (~> 1.1) + thor (0.19.1) + thread_safe (0.3.4) + tilt (1.4.1) + tinder (1.10.1) + eventmachine (~> 1.0) + faraday (~> 0.9.0) + faraday_middleware (~> 0.9) + hashie (>= 1.0) + json (~> 1.8.0) + mime-types + multi_json (~> 1.7) twitter-stream (~> 0.1) - treetop (1.4.10) - polyglot - polyglot (>= 0.3.1) twitter-stream (0.1.16) eventmachine (>= 0.12.8) http_parser.rb (~> 0.5.1) simple_oauth (~> 0.1.4) + tzinfo (1.2.2) + thread_safe (~> 0.1) unicorn (3.7.0) kgio (~> 2.3) rack diff --git a/Hacknight.md b/Hacknight.md deleted file mode 100644 index c15f899..0000000 --- a/Hacknight.md +++ /dev/null @@ -1,131 +0,0 @@ -### Welcome - -Good Evening Hackers! - -Thank you for choosing to hack on SupportBee API/Platform. We hope you will have a great time building apps on top of SupportBee. - -SupportBee is the easiest way to manage customer support emails. The customers of the company using SupportBee will contact them via email which are forwarded to SupportBee. These emails are converted to _tickets_. Multiple people can login to the same shared inbox where they can and reply to these tickets. The tickets can be assigned to different agents. They can be categoried using labels. The workflow is very similar to Gmail. - -### API and App Platform - -We have a JSON REST API. It powers our own frontend. So it can do whatever our own frontend can do. The API docs can be found here https://developers.supportbee.com/api. We care about [developer experience](https://www.youtube.com/watch?v=V3rQWpnykyY) so we built an app platform over our API. Our platform takes care of all the setup required to use an API. For example: Authentication. It lets you concentrate on the app itself. You can learn more about the platform here: https://developers.supportbee.com - -For this HackNight we are opening up our staging environment. - -Until recently, some of the capabilities that the platform offer were untestable as they would need access to our core application codebase. For the first time, at this Hacknight, we are introducing a new way to test your apps as they are built. This is still in alpha, so we have deployed it on our staging server. So to test the apps you are writing please do the following: - -- Go to https://reminderhawk.com . This is our staging server. -- Sign up for a SupportBee account. -- By default, your SupportBee account connects to a App Platform running locally on the staging server. -- Follow the instructions here: https://developers.supportbee.com/platform/overview to run the App Platform locally. -- One you have the platform running, you have to expose the platfrom the internet so our staging server can interact with it. You can achieve this using https://forwardhq.com/. On signup, follow the instruction to forward a localhost port. You will also get a URL through which your locally running app platfrom can be accessed. -- Shout out to one of us and we will enable the URL for you. -- Now your local app platform can commnicate with the staging server. - -## What can you do? - -### WRAPPERS - -In the last hackathon, the guys from HasGeek built an awsome Python wrapper. https://github.com/sivaa/supportbee-python -If you are in the mood for refactoring, you extract a Ruby wrapper out of the App Platform code. Are you a Mobile Developer? How about an sdk for Android/IOS. We will compile all of them and make a page out of it. You will retain all the credits :) - -### Widgets - -Innovate on creation of ticket creation widgets. We have very simple web widget to create a ticket. How about a way to send crash reports to SupportBee from a mobile app? - -### Apps -+ NLP on our push events -+ Google Calendar Integration - -### Hack on the App Platform - -Improve the capabilites of the platform itself! Pair program with us if you want to know how our platform works! - -## Chat with us -https://scrollback.io/supportbee-community - -## Goodies - -We have many TShirts, Stickers to give away. Our favourite hacker gets a lunch invite to our cozy office (PS: We have an awesome cook!). - - - - - -## Hacking on SupportBee's App Platform - -### Installing Ruby - -#### Installing Ruby on Windows - -+ Download Ruby 1.9.3 from http://rubyinstaller.org/ - - - - - -+ Double click and run the ruby installer. Ignore the security warning. - - - -+ The executable is a typical Windows Installer. In the Installation Options screen, tick the options `Add Ruby executables in your PATH`, `Associate .rb and .rbw files with this Ruby installation`. - - - -+ Ensure ruby 1.9.3 in installed by running `ruby -v` -``` -ruby -v -``` -in the command prompt - - - -### Setting up the App Platform - -Extensive instructions to run the app platform are available [here](https://developers.supportbee.com/platform/overview). - -For the impatient ones.. - -+ Clone the App Platform (https://github.com/SupportBee/SupportBee-Apps/) - -``` -git clone https://github.com/SupportBee/SupportBee-Apps/ -``` - -+ Bundler is a great tool to manage gems (libraries in ruby are called gems) in ruby projects. Install bundler. - -``` -gem install bundler -``` - -+ Install App Platform dependencies - -``` -bundle install -``` - -+ Copy the default config files - -``` -cp config/omniauth.platform.example.yml config/omniauth.platform.yml -``` - -+ Rackup! The server runs on port 9292 - -``` -% rackup -Preparing Assets... -[2014-07-04 17:33:56] INFO WEBrick 1.3.1 -[2014-07-04 17:33:56] INFO ruby 1.9.3 (2013-11-22) [x86_64-darwin13.0.2] -[2014-07-04 17:33:56] INFO WEBrick::HTTPServer#start: pid=86474 port=9292 -``` - -### Register your SupportBee - -We have repurposed our staging servers for the Hacknight. Head out to http://reminderhawk.com/ and create your SupportBee. - -### Talk to us - -We're around. We are looking forward to talk about our API, pair program with you and get you started with a demo app using our app platform. - -## Happy Hacking! Bee Awesome! diff --git a/apps/github/github.rb b/apps/github/github.rb index 86f827c..053cd0c 100644 --- a/apps/github/github.rb +++ b/apps/github/github.rb @@ -34,6 +34,14 @@ def orgs [200, fetch_orgs] end + # TODO: Move to a gem + def api_url(resource = "", params = {}) + url = URI("https://api.github.com/#{resource}") + url.query = to_query(params.merge(default_api_params)) + + url.to_s + end + private def fetch_orgs @@ -57,21 +65,19 @@ def orgs_url end def projects_url - if payload.overlay and org = payload.overlay.org - api_url("orgs/#{org}/repos") + resource = if payload.overlay and org = payload.overlay.org + "orgs/#{org}/repos" else - api_url('user/repos') + 'user/repos' end + + api_url(resource, per_page: 100) end def token token = settings.oauth_token || settings.token end - def api_url(resource="") - "https://api.github.com/#{resource}?access_token=#{token}" - end - def create_issue(issue_title, description, repo) response = http_post "https://api.github.com/repos/#{repo}/issues?access_token=#{token}" do |req| req.body = {:title => issue_title, :body => description, :labels => ['supportbee']}.to_json @@ -86,5 +92,14 @@ def comment_on_ticket(ticket, html) ticket.comment(:html => html) end + def default_api_params + { access_token: token } + end + + def to_query(query_params) + query_params.reduce("") do |query, (k, v)| + query + "#{k}=#{v}&" # Not url encoding params for now. Just move to a gem. + end.chop + end end end diff --git a/apps/mailchimp/assets/images/icon.png b/apps/mailchimp/assets/images/icon.png new file mode 100644 index 0000000..fb313e5 Binary files /dev/null and b/apps/mailchimp/assets/images/icon.png differ diff --git a/apps/mailchimp/assets/images/screenshot.png b/apps/mailchimp/assets/images/screenshot.png new file mode 100644 index 0000000..8583a89 Binary files /dev/null and b/apps/mailchimp/assets/images/screenshot.png differ diff --git a/apps/mailchimp/assets/javascripts/mailchimp.js.coffee b/apps/mailchimp/assets/javascripts/mailchimp.js.coffee new file mode 100644 index 0000000..8e870b4 --- /dev/null +++ b/apps/mailchimp/assets/javascripts/mailchimp.js.coffee @@ -0,0 +1,38 @@ +MailChimp = {} +MailChimp.Views = {} + +option_tag = (list) -> + "" + +MailChimp.Views.Overlay = SB.Apps.BaseView.extend( + + events: { + 'click a.submit': 'submit_form' + } + + initialize: -> + SB.Apps.BaseView.prototype.initialize.call(this) + _.bindAll this, 'load_lists', 'render_list' + @setup_selectors() + @populate_lists() + + setup_selectors: -> + @lists_selector = @$("[name='lists_select']") + + populate_lists: -> + @lists = new SB.Apps.BaseCollection([], app: @app, endpoint: 'lists') + @lists.on 'reset', @load_lists + @lists.fetch() + + load_lists: -> + @lists.each @render_list + + render_list: (list) -> + @lists_selector.append option_tag(list) + + submit_form: -> + @post 'button', @$('form').toJSON() + +) + +return MailChimp diff --git a/apps/mailchimp/assets/views/button/overlay.hbs b/apps/mailchimp/assets/views/button/overlay.hbs new file mode 100644 index 0000000..47ca923 --- /dev/null +++ b/apps/mailchimp/assets/views/button/overlay.hbs @@ -0,0 +1,16 @@ +
diff --git a/apps/mailchimp/config.yml b/apps/mailchimp/config.yml new file mode 100644 index 0000000..624468a --- /dev/null +++ b/apps/mailchimp/config.yml @@ -0,0 +1,29 @@ +name: Mailchimp +slug: mailchimp +access: public + +description: "MailChimp Integration with SupportBee. +User Story +Lets say a user requests for a feature and it would be available in the next upcoming release. For this you will have to track and record the users who requested this(or similar) feature. You can create a campaign in MailChimp and select the list of users whom you'd like to announce regarding the release(feature made available). + +For achieving this purpose, you can push a user to a list in mailchimp right from SupportBee. +" + +category: Integration + +tags: +- mailchimp +- announcement + +developer: + name: Swaroop SM + email: swaroop.striker@gmail.com + twitter: "@smswaroop" + github: swaroopsm + +action: + button: + overlay: true + screens: + - ticket + label: Send To MailChimp diff --git a/apps/mailchimp/mailchimp.rb b/apps/mailchimp/mailchimp.rb new file mode 100644 index 0000000..498bffd --- /dev/null +++ b/apps/mailchimp/mailchimp.rb @@ -0,0 +1,88 @@ +module Mailchimp + module ActionHandler + def button + ticket = payload.tickets.first + + begin + add_to_list(ticket) + rescue Exception => e + return [ 500, e.message ] + end + + [200, "Success"] + end + + # End point to fetch all the lists + def lists + begin + all_lists = get_lists + + return [ 200, all_lists ] + rescue Exception => e + return [ 500, e.message ] + end + end + end +end + +module Mailchimp + class Base < SupportBeeApp::Base + + # Define Settings + string :api_key, :required => true, :hint => 'Get you API key at: http://kb.mailchimp.com/article/where-can-i-find-my-api-key' + + # Return all lists from MailChimp + def get_lists + response = http_post api_url("/lists/list.json") do |req| + req.body = { 'apikey' => settings.api_key }.to_json + req.headers['Content-Type'] = 'application/json' + end + + return handle_response(response) + end + + # Return the list id that was was given by the user as an input + def list_id + payload.overlay.lists_select + end + + # Add requester email to a list + def add_to_list(ticket) + response = http_post api_url("/lists/subscribe") do |req| + req.body = { 'apikey' => settings.api_key, 'id' => list_id, 'email' => ticket.requester.email, 'name' => ticket.requester.name }.to_json + req.headers['Content-Type'] = 'application/json' + end + + return handle_response(response) + end + + private + + # Helper to make the mailchimp API url + def api_url(path) + splitted = settings.api_key.to_s.split("-") + version = "2.0" + + if splitted.length == 2 + ds = splitted[1] + return "https://#{ds}.api.mailchimp.com/#{version}#{path}" + end + + raise "Invalid API key format" + + end + + # Helper method to handle mailchimp response + def handle_response(response) + response_body = response.body + + if response_body['data'] + return response_body['data'] + end + + raise response_body['error'] + end + + end +end + diff --git a/apps/moxtra/assets/images/icon.png b/apps/moxtra/assets/images/icon.png new file mode 100644 index 0000000..63982e5 Binary files /dev/null and b/apps/moxtra/assets/images/icon.png differ diff --git a/apps/moxtra/assets/images/screenshot.png b/apps/moxtra/assets/images/screenshot.png new file mode 100644 index 0000000..72ac28a Binary files /dev/null and b/apps/moxtra/assets/images/screenshot.png differ diff --git a/apps/moxtra/assets/views/button/overlay.hbs b/apps/moxtra/assets/views/button/overlay.hbs new file mode 100644 index 0000000..0c28a03 --- /dev/null +++ b/apps/moxtra/assets/views/button/overlay.hbs @@ -0,0 +1,24 @@ + + +