Lunch–Hold the Bunch

I have known about LunchBunch since the day its development started—even before that, really, when its concept was one outcome of several days of brainstorming between Matt, Ryan, and Brandon (The Bunch) early last April. I must admit, however, that I have not loved LunchBunch since the day it started. (Which is probably bad, considering Matt is my fiancé.)

I had my hesitations. From the moment the idea first sprung into existence, to the moment I saw the beta-testing release, even until the moment that the live app was on my phone and in my hands—I was hesitant. I was not hesitant that LunchBunch would succeed and be used by many people—only that it would be used by me.

Ask Matt, and he will tell you that throughout the development of LunchBunch, I have been both his biggest fan and his most annoying critic. I was skeptical.

“My friends won’t use LunchBunch.”

“My school is too small, and we only have one place to eat. We usually just walk in and find somebody.”

“I usually eat by myself if I only have a few minutes in between classes.”

I wouldn’t call myself Negative Nancy, but I wanted to be sure that LunchBunch would achieve what it needed to for the audience it was meant to. Some days I didn’t like the colors; some days I thought the swiping function between screens was too slow. (In fact, the last time I was with Matt, he confessed that he only asks me about LunchBunch when he is feeling particularly open-minded and patient.)

The date was November 10, 2015, and LunchBunch had been available for download for three days–-but I hadn’t used it yet. “It isn’t practical for me,” I thought. It was 5:00pm, and I was hungry—but it was dark, raining and I was considering eating microwave popcorn for dinner instead of walking six cold, lonely minutes to the Dining Commons at school.

Then, it occurred to me that now would be the perfect time to try this LunchBunch thing. I started broadcasting to my mere 12 buddies, and to my surprise, three of them were also broadcasting. I wrote an invitation for 5:07pm at the Dining Commons, and suddenly, I was eating a meal with eight friends—all because of LunchBunch. That night, not only were we eating a meal initiated by LunchBunch, but so were at least two other groups of people in the same room!

Since the launch of LunchBunch, I have been the recipient of admiration, applause, and constructive criticism on behalf of The Bunch, and it has been incredible to see people all over using something on their personal phones that The Bunch dreamt of, created and now actually exists. Thanks to LunchBunch, people are easily partaking in meals together, and enjoying one of the most valuable aspects of community—whether that is in a large corporation or a small university (or anything in between).

Happy LunchBunching!

Sincerely,
Megan (kind of) from The Bunch

HTTP Verbs

APIs often support different methods (HTTP verbs) that communicate to the client/server what kind of action is taken at that endpoint. The two most common methods are GET and POST. There are several others (PUT, DELETE, HEAD, OPTIONS, TRACE, CONNECT), but we’re going to focus on GET and POST today.

Endpoints that employ GET do exactly that–they get information from the server and return the results to the requester. Endpoints that use POST usually make changes to the backend in some way–inserting, updating, or deleting something in the database for example. GET is called an idempotent method because its effect on the backend is the same whether the endpoint is hit once or multiple times. This can be true for POST requests too (e.g. /logout where username=”broberts” can be called one time or 100 times, and broberts–and only broberts–will be logged out), but in general, POST is not an idempotent method. RESTful APIs are stateless, so if you use GET at one endpoint, you should get the same response if you hit that endpoint again with the same parameters.

It’s important to note that HTTP methods don’t have special properties–from a functionality standpoint, anything you can do with GET you can do with POST (and vice versa). But that doesn’t mean that you should. One of the reasons it’s good not to make all your endpoints use GET is link prefetching. Browsers might prefetch pages (any GET request) that it thinks a user will visit soon. If your logout endpoint is prefetched, then users’ browsers might be logging them out via link prefetching as soon as they log in!

For more information, W3Schools has some great documentation that provides a closer look at the differences between GET and POST.

Happy coding!
Ryan from The Bunch

Productivity Tools

tools

Teamwork requires effective communication, clear divisions of responsibility, and efficient workflows. When it comes to productivity tools, there are so many options that sometimes more work can be put into picking the right one than into actually completing the project! I’ve put together a list of three great tools that could make your next project a little bit easier to manage. Hopefully, it helps to narrow your search!

Trello

Whether you are working solo, with a partner, or with a whole team, Trello breaks down projects into tasks that are easy to manage and track. The online interface and mobile app feature a board containing lists. You create a card for each task and place it in the list associated with that task. For example, LunchBunch has a list for new features. Some cards on that list might be “Add Buddy from Contacts” and “Emoji Support”. Users can add a description and due date to the card, and anyone on the team can comment on the card to share their thoughts. Cards can be assigned to a user to make it easy to see who is responsible for which tasks. The card owner creates checklists to update as the task nears completion. Trello is very easy to use and great for keeping projects on track.

Google Apps for Work

Gmail is the most-popular email service in the world, and Google Apps for Work allows you to use Gmail with your own domain name which gives your business a more-professional appearance. While the pricing is worth it for that reason alone, it also comes with 30GB of Google Drive space and a bunch of other integrations that come with Gmail accounts. For example, included are Google Hangouts (which is great for internal meetings and meetings outside of your company), Google Calendar, and Google Docs. Google Docs documents, spreadsheets, presentations, forms, and drawings don’t count towards your 30GB of Drive storage, which is a nice bonus!

You can use Google Voice with your account as well. Google Voice gives you a phone number (for free!) that you can attach to your existing work, home, and/or cell phone(s). You can schedule different phones to ring and configure multiple voicemail greetings depending on the time of day, who’s calling, etc.

Google Apps for Work is a must-have for any small business, and Google Voice is a nice feature to separate personal and work calls.

Slack

Of all the tools we use at LunchBunch, Slack is my favorite. “Slack is a messaging app for teams that is on a mission to make your working life simpler, more pleasant, and more productive.” This is how Slack describes itself on its website, and I think that sums it up very well. Communication is organized in channels. So your business might have separate channels for marketing, sales, design, and development. This way, team members can join discussions that they need to be part of, and all of the messages stay organized.

Slack also offers features for sharing files and has plenty of third-party integrations–including Trello and Google Apps for Work–which make it a powerful service. The desktop application and mobile app make team communication extremely efficient. Additionally, the free tier is remarkably generous, and it doesn’t expire.

 
A list of only three services is pretty short, but I think these are great solutions for teams of all sizes and needs. Do you have any favorite tools your team likes to use? Let me know in the comments below!

Sincerely,
Ryan from The Bunch

Rate-Limiting Decorators

Decorators are great for APIs because they cleanly abstract shared functionality from different endpoints. Rate limiting is a great use case for decorators and should be incorporated into just about every API. Rate limiting ensures that there aren’t too many calls originating from the same user/IP address/etc. in a given timeframe. This can prevent the server or database from getting bogged down with spammy requests.

Let’s look at an example. Your application is a math API and has an endpoint /get_fibonacci for computing the nth element of the Fibonacci sequence. This is a computationally expensive operation, and you know that users don’t need to hit this endpoint more than a few times per day. That is, if a user is calling it multiple times in a short window, either there’s an error in the application that is causing that function to be called many times, or the user is abusing the API. Either way, the overloaded server is doing more work than is necessary, and we can prevent this with rate limiting.

To be safe, let’s allow each user call this endpoint 10 times every 5 minutes. If we only expect 2 or 3 calls every 24 hours, this should be plenty, and legitimate users won’t be locked out. If the application has a login system, you can limit based on username. Otherwise, IP address, user agent, or some other identifying data will work. You will need to store a dictionary that maps each user to the number of calls in the past 5 minutes. If you are looking for code to use in your project, you might want to check out a complete example (← code snippet uses Flask).

For an easier code example, let’s say we want to limit API calls by time of day instead of rate–calls are allowed only between midnight and noon. (There’s a use case for that, right?…🙂) This would be our code:

@app.route("/get_fibonacci", methods=["GET"])
@ratelimit
def fibonacci():
    n = int(flask.request.args["n"])
    a = 0
    b = 1
    while b < n:
        a = b
        b = a + b
    return str(b)

def ratelimit(func):
    def ratelimit_wrapper(*args, **kwargs):
        if datetime.datetime.utcnow().time().hour > 12:
            return "Sorry, please try again tomorrow in the AM!"
        return func(*args, **kwargs)
    return ratelimit_wrapper

Then navigate to {host}/get_fibonacci?n=5 to see it in action.

This means that before the given Fibonacci number is computed, the decorator checks to see if the current time is before or after noon. If it’s after noon, the error message is returned to the user. Otherwise, the fibonacci() function runs and returns the result to the requester.

Here’s a line-by-line description of everything that’s going on:

  • 1. This function can be accessed via GET at {host/application_root}/get_fibonacci
  • 2. Attaches the ratelimit decorator to this endpoint (more accurately, it wraps this function with the ratelimit function)
  • 3. Function definition
  • 4. Extract GET parameter from the URL
  • 5/6. Initialize first two elements of the Fibonacci sequence
  • 7. Repeat until we find the nth element
  • 8/9. Get the next element in the sequence
  • 10. Return the nth element (View function expects a string response)
  • 12. Decorator definition
  • 13. Wrapper function that surrounds the decorator–accepts any arguments
  • 14. Check the time in case it’s after noon
  • 15. This is returned to the requester without ever calling fibonacci() if it’s after noon
  • 16. It’s before noon, so return the output of the original function
  • 17. Return this decorator wrapper

Decorators can be confusing at first, but they’re powerful and great for writing simple, clean code. If you have any questions, please let me know in the comments below!

Happy coding!
Ryan from The Bunch

LunchBunch Dictionary

dictionary

When you’re learning something new, sometimes it’s nice to have a cheat sheet to reference, so we’ve compiled a list of some LunchBunch terms to help you keep track. Some of these terms are self-explanatory, but we included them for completeness and to make you aware of all of the current features.

  • Buddy: Users you are connected with in LunchBunch. To become buddies, one of you must send the other a buddy request, and the other must accept it.
  • Bunch: Buddies are organized into bunches. A bunch can have one or more members, and no one can see your bunches except for you. When you broadcast or create an invitation, you can select bunches and/or buddies, so bunches make it easier to choose multiple buddies quickly.
  • Broadcast: When you are hungry, you use broadcasting to let specific bunches/buddies know. In order to see who else is hungry, three conditions need to be met: 1.) you must be buddies, 2.) you must both be hungry, and 3.) you must both be broadcasting to each other. This means that buddies you aren’t broadcasting to will never see that you are hungry. When selecting bunches to broadcast to, you can lock or hide individual buddies. Locking and hiding buddies allows you to override bunch selection.
    • Locked Buddy: This buddy will be broadcast to–even if he or she isn’t a member of a selected bunch.
    • Hidden Buddy: This buddy will not be broadcast to–even if he or she is a member of selected bunch.
  • Invitation: Sending an invitation initiates a message thread for organizing a meal. Invited members can RSVP, send messages, and modify the invitation (unless it is locked).
    • RSVP: Invitation members can RSVP “going” or “not going”, which will automatically send a message to the invitation members. To see who is going, you can scroll through past messages or check the invitation members list where their RSVPs are listed.
    • Message: Text messages (with emoji support! 🎉 🙌) can be sent between invitation members for communication beyond RSVP–location details, etc. or just chatting! Automatic messages are sent when members RSVP, when the time/location of the invitation is modified, and when users are added to the invitation.
    • Modify Invitation: Assuming that the user who created the invitation didn’t lock it, invitation members can change the time and/or location of the invitation and/or invite other users. Only buddies can be added to an invitation, but they do not need to be buddies with everyone in the invitation.
    • Locked Invitation: When you create an invitation, you have the option to lock it to prevent members from editing details. If you lock an invitation, only you can change the time, location, and invitee list. You can also lock/unlock an invitation after you create it.

Still have questions? Is there another term we should add? Please let us know in the comments below!

Sincerely,
Ryan from The Bunch

Extending Application

As you develop your Android application, you may find it necessary for certain libraries or settings to be initialized on app startup, rather than during normal application use. This can be done simply by extending the Application class. Simply create a class and have it extend Application, and in the onCreate() method, just initialize the library:

@Override
    public void onCreate() {
        super.onCreate();
        /* Initialization of some cool library */
        SomeLibrary.init();
    }

Now, after we’ve created this class, we need to tell our application to use it! That’s simple too. Just put

android:name=".mypackagename.MyClassThatExtendsApplication"

inside your application tag in your AndroidManifest.xml. This will tell your application to use the class you’ve defined as your Application class, and the OnCreate() method will be run, making sure your app is configured correctly. Another great use case for this is setting up a crash report library. The library will want to start listening for crashes immediately, so the best place to set that up is in the Application class.

Happy coding!
Brandon from The Bunch

What does LunchBunch do with Phone Numbers?

While optional, adding your phone number to your LunchBunch account is encouraged for account security and for helping friends find you more easily.

In the event that you forget your password, LunchBunch will send you a security code via text message. This is an easy and secure way to help you regain access to your account if you get locked out. Without adding your phone number to your LunchBunch profile, there is no way to reset your account password if it is lost.

The easiest way to add friends as LunchBunch buddies is to add from contacts. Using this feature, you can scroll through the contacts on your phone to see who has a LunchBunch account and send a buddy request with a single tap. If your contact does not have a LunchBunch account, you can invite them to join from within the app. By adding your phone number to your LunchBunch account, friends with your number will easily be able to add you as a buddy.

LunchBunch takes security and privacy very seriously. We never give or sell information like your phone number to any third parties. The only time you should receive text messages from LunchBunch is when you are verifying your number or reseting your password; we don’t send text messages for marketing purposes. Adding your phone number to your LunchBunch account is optional–though encouraged–and used only for the purposes described in this blog post.

If you have any questions about phone numbers and your LunchBunch account, please let us know in the comments below!

Sincerely,
Ryan from The Bunch

AWS SES Domain Verification

Amazon Web Services offers a lot of services. The documentation is usually comprehensive and easy to follow, but sometimes there are a few “gotchas” when working with resources outside of AWS–especially with AWS Simple Email Service (SES).

If you’re having trouble verifying your domain, here are a few things to check:

  1. When updating the domain’s DNS records with your DNS provider, make sure that you type the full name and value of each record (TXT and CNAME records if you opt for DKIM [which is recommended for verifying the sender’s identity when emails from “*@yourdomain.com” are received]). The names/values are long and the table cells overflow, so if you double-click on the text to copy/paste it, you might not be copying the entire name/value because it contains periods, etc. that will terminate highlighting on double-click. (Kind of embarrassing, but this happened to me, and I didn’t notice for 24 hours…)
  2. The AWS documentation says, “If your DNS provider does not allow DNS record names to contain underscores, you can omit _amazonses from the TXT record name.” Some DNS providers (for example, Namecheap) allow underscores but automatically append the domain to the end of record names (or hosts in Namecheap). So _amazonses.lunchbunch.me should be _amazonses, and <mykey>._domainkey.lunchbunch.me should be <mykey>._domainkey with no domain appended. (After an additional 48 hours, I realized that this was why my verification was still pending…)
  3. Finally, although the documentation says that the verification process could take up to 72 hours, it usually won’t take more than one hour. And you can check if it’s working much faster than that (within a couple of minutes); after you’ve updated your DNS records, visit this page to see if the changes have been pushed through–just replace “lunchbunch.me” with your domain name. (DNS updates likely will be picked up by Google before AWS, though you may have to submit this form a few times until a server with the updated records processes your request.)

If none of these suggestions help, please refer to Amazon SES Domain Verification Problems, or let me know in the comments below!

Happy coding!
Ryan from The Bunch

Our First Bug

Bugs are an inevitable part of software engineering. Mobile app development has plenty, and that’s why you get update notifications for your downloaded apps so often. Building software is a very iterative process, and while there are many ways to mitigate the risk of bugs, they are nearly impossible to eradicate completely.

Testing for bugs always should be a priority, but in the late stages of LunchBunch development, we were in such a hurry to release the app publicly that we almost decided not to give it to beta testers first! If you’re thinking about creating your own app, let me be the first to tell you that you need to have beta testers use your app and provide feedback before your public launch. There weren’t any critical bugs (things that affected many users or made the app unusable), but there were a lot of little things that we discovered in the feedback–things like notifications not showing when the app was open, layout issues, and missing features. There are a lot of things that are easy to miss when you’re so intimately familiar with the app, and this is why it is super important to get people outside of your team to use the app and find bugs for you.

So besides little things that were easy to fix, we did have one bug that stood out: there was one beta tester who couldn’t send invitations to her buddies. We were a little concerned, but we were primarily just confused because it seemed to be working for everyone except for her. “What is different about this user? What makes her unique from all of the other beta testers?” we wondered. I had no idea what the problem could be, but I thought a good place to start looking was her phone–which OS (Android/iOS) and which version it was running, check if she was logged in to multiple devices, and other stuff like that. Nothing raised any flags, so I thought I’d check her name next–maybe there was an apostrophe in it or some other special character that might mess with the software. (As a side note, because of the way information is stored in software, apostrophes sometimes create issues. But my last name is O’Dowd, so I always take care of apostrophe-related issues; I was going to be pretty disappointed if that was the problem!) Unfortunately (but fortunately for my pride), this too turned up nothing.

I went back through our logs to see what information was coming into the server to check for errors. That’s when I noticed it…the beta tester’s username was capitalized in some places but all lowercase in other places! Because the username was stored lowercase in one place and capitalized in another, the app and the LunchBunch server weren’t communicating correctly; when the phone tried to send the invitation, the server got confused because it couldn’t find the username in its database! Once we confirmed that this was, in fact, the issue preventing the tester from sending invitations, we sent out a fix that would prevent the same thing from happening again.

This is a great example to reinforce the importance of testing–and specifically, the importance of having external users test the app. We (The Bunch) never put a capital letter in any of our test usernames, and we probably wouldn’t have thought to try that either. Developers don’t know how users are going to use the software, but beta testing makes it easy to catch these artifacts before the app goes public.

Have a funny experience with a bug you’ve seen in an app? Let us know in the comments below!

Sincerely,
Ryan from The Bunch