Building Your Startup: Delivering the Meeting Invitation

Final product image
What You'll Be Creating


This tutorial is part of the Building Your Startup With PHP series on Envato Tuts+. In this series, I'm guiding you through launching a startup from concept to reality using my Meeting Planner app as a real-life example. Every step along the way, I'll release the Meeting Planner code as open-source examples you can learn from. I'll also address startup-related business issues as they arise.

What Does This Episode Cover?

In this tutorial, we'll cover emailing the invitation to the participant, implementing the basic appearance of its content, and considering the construction of links for recipients so they can respond.

All of the code for Meeting Planner is written in the Yii2 Framework for PHP. If you'd like to learn more about Yii2, check out my parallel series Programming With Yii2 at Envato Tuts+.

Just a reminder, I do participate in the comment threads below. I'm especially interested if you have different approaches, additional ideas, or want to suggest topics for future tutorials. You can also reach me on Twitter @reifman.

Requirements to Deliver Invitations

It's exciting to reach this stage of delivering the first invitations, but it still requires a lot of work. In the last episode, I updated the meeting views so they could support either the organizer or participants. 

Most of the work in this episode will focus on creating HTML emails in Yii and delivering these programmatically. However, as I began to write the code for this, I ran into all of the complexities that the system must soon support. For example, all the links in the invitations needed to securely authenticate participants while considering that they've never registered for Meeting Planner. Some of this I'll save for the next episode.

Essentially, we have to make the application aware of who's viewing the meeting page and then customize the appearance and commands available. Yii makes most of this pretty easy, but there's a lot of detail involved.

A Brief Caveat About the User Experience

Let me say up front, there is a lot of user experience rework and polish that will need to be done iteratively over time on the way to creating the minimum viable product (MVP). Most of what I'm building right now is core functionality to get the alpha running for actual usage. I know it looks rough in places and won't always seem as intuitive as you want. There are also coding inefficiencies that will need to be optimized in the future.

Please feel free to post your thoughts and comments below, and I will take them into account for ongoing work. 

Here are some of the challenges that arose with this episode's work:

  • The basic design and contents of the invitation email
  • How will invitations be delivered? e.g. which email platform or provider?
  • Which linked commands will be offered in the email? And would the organizer be able to limit some of the powers given to participants?
  • Functional response to linked commands within the invitation email
  • Managing the visits from invited users that haven't yet signed up, e.g. what they can access and cannot?
  • Handling the user experience for collecting friendly names from attendees
  • Logging responses to the meeting invitation and then building the monitoring and notification capacity to inform the organizer
  • Planning the infrastructure for future emails showing updates as meeting configurations change and as the time nears (and passes), e.g. change notifications, meeting reminders, accepting replies as new notes, etc.

As I wrote the code for this episode, I built some infrastructure for some of the above items and left some of them to discuss in future episodes. To begin, let's dive into the invitation design.

The Invitation Design and Contents

Initially, I had to ask, what should be included in the email? Obviously, there would be the standard fields:

  • To
  • From
  • Subject (you're invited to a meeting!)
  • Message body
  • Footer

The body contents will need to include:

  • The meeting details
  • Proposed places
  • Proposed dates and times

And, depending on the organizer's settings, which command links should be presented? Here are some questions that came up. Should we allow recipients to:

  • Accept every option, i.e. all places, dates and times are acceptable
  • Accept all places or all dates and times separately
  • Accept specific places and specific dates and times individually
  • See maps for prospective places and ultimately websites and Yelp links
  • Post a note back to the organizer for the meeting view
  • Suggest a new place or date and time
  • Choose a place or a date and time
  • Finalize the meeting

Finally, the footer will need to support:

  • Alpha notice with a request for feedback
  • Option to block the sender
  • Option to unsubscribe from future Meeting Planner invitations
  • The company details and contact information

I know it can be difficult to visualize all of this—this wasn't an easy episode to build for. Here's an example of the invitation that I ultimately built:

Meeting Planner Invitation Example

For now, I used the commands acceptable and reject to indicate to the participant that they are simply indicating whether or not a place or date and time works for them or not. However, for simplicity, I offered accept all places and timesaccept all places and accept all times to manage this in quicker steps.

All of this is loosely based on the actual meeting invitation form from the last episode. Below, you can see the portion of the invitation which offers configuration of places and times:

Meeting Planner Invitation - View of Places and Times

Note that the email provides some of the advanced functionality that was built in the last episode to allow organizers to offer enhanced levels of control to participants such as suggesting new places and times, choosing the final place and time, etc.

Meeting Planner Invitation - Updating Your Meeting Settings

It became obvious to me very quickly that investing more in designing the email and offering simpler configurations of the invitation would be required in the future. Again, I'll have to save this for future episodes. 

As an example, one of my first alpha testing friends suggested that they wished they could indicate that some places only worked on certain dates and times and vice versa. Ultimately, I might need to unify places and dates & times into one model of choices.

For now, let's review how I delivered the above invitation as it is.

Delivering the Invitation

Meeting Planner Invitation - The Command Bar with Send

What happens when the organizer clicks Send? Initially, I expected that I would have to write directly to the Mailgun API, which I've explored in earlier Envato Tuts+ tutorials. However, Yii2's support for email is quite rich, and I was able to leverage its native view support for email layouts (both HTML and text) and simply deliver them using my Mailgun SMTP account authentication. This even supports attaching future event files (.ics) for importing meetings into calendars.

Note: I'm a big fan of Mailgun, but I've also done development for them as a consultant and written for their blog and Envato Tuts+.

Before continuing, I encourage you to take a quick look at Yii2's Mailing documentation. It offers an excellent overview. 

First, I added more detailed SwiftMailer configuration settings to /common/config/main-local.php:

This enabled Yii's SwiftMailer component to deliver my emails via Mailgun's basic SMTP service. 

You'll need to obtain your Mailgun SMTP settings from its control panel for your domain:

Meeting Planner Invitation - Mailgun SMTP Settings

Of course, you also have to make sure SwiftMailer is part of your composer.json file configuration before running composer update:

Next, I created the view file configuration for SwiftMailer to use. First, there has to be a master layout for both HTML and text. Then, there have to be individual content files for each as well:

Meeting Planner Invitation - The Folder and Files in Mail Layouts

Not all of this is fully documented for Yii, so hopefully this example will offer some guidance. Note that the finalize-html and -text view files were added later for a future episode.

Typically, the layouts/html.php file is quite simple:

However, I added a lot to it to begin working with the styling and formatting of HTML emails offered to the open-source community by Mailchimp.

Yii's SwiftMailer will generally automatically convert your HTML view to text-compatible views for you. Most likely, I'll want a shorter, simpler text view for invitations, but for now, I'm going to delay reviewing the text-based email results of my code.

In the Meeting.php model, I've written a send function that gathers all the data needed to build my invitation view shown above. For now, I'm leaving out parts related to the next episode for building command links. Basically, I use Yii::$app->mailer compose() and send():

Those functions build a message using our HTML layout and view and then pass off the resulting messages with personalized data to Mailgun's SMTP service. We're able to use Yii's implementation of its MVC model for email delivery.

Problems With Composer

As I've used Composer with Yii, I've often run into a lot of problems with it that can be hard to track down. Most regularly, it's related to the “yiisoft/yii2-composer” plugin requires composer-plugin-api 1.0.0 error, but this time, I ran into a problem updating Mailgun. Recent versions of the Mailgun API require current updates to guzzle. An earlier Yii plugin used in MeetingPlanner required a fixed, out of date version of guzzle. So, I had to configure composer to use an alias. 

Essentially, I instructed composer to sync the latest version of guzzle but tell the application it was using an older version. In composer.json, an alias looks like this:

I'm instructing it to install "guzzlehttp/guzzle":"6.2.0 as 4.2.3" and that makes everything function well, at least in this case. Sometimes developers of plugins require specific versions of libraries to operate properly. Composer mostly is useful, but sometimes it sure is fun.

Updating Meeting Creation 

As I experimented with invitations, I decided to customize the meeting creation view to more clearly support a subject field. This allows users to write a subject line as if they were sending an email to invite someone to a meeting without Meeting Planner. The UX for this will need to be iterated and simplified more over time.

Meeting Planner Invitation - Create a Meeting

This provides the ideal subject line in the email for the meeting invitation. Of course, to provide this, I had to extend the Meeting model.

I created a new migration called extend_meeting_table_add_subject which added the subject field:

And I had to add support for the new field to the meeting _form.php file and the model.

Here's an excerpt from what's added to the Meeting.php model:

An Updated Map Page for Places

Initially, my invitation map links went directly to Google Maps, but I realized it would be better to link them to an embedded map view at Meeting Planner which was part of the Meeting invitation. In my case, I created a view of the map with a Return to Meeting button:

Meeting Planner Invitation - Viewing a Place within a Meeting Invitation

For this, I created a new view built on /views/place/view.php. Here is /views/meeting/viewplace.php:

What's Next?

As you can see, getting to the first email invitation raised all kinds of issues and required a lot of small to medium sized updates. But, with the basic foundation for them complete, we can contemplate the complexity of what's been created. In other words, what is needed next:

  • Authenticated command links. When a participant clicks a command link within the email, how will we authenticate them, especially if they've never registered with our application?
  • Finalizing the meeting based on responses. As the participants make choices and the organizer is ready to finalize the meeting, what changes and updates are necessary to support that?
  • Monitoring the process of changes made by participants to the invitation. How will we monitor changes to the meeting details and choose when to notify organizers and participants?
  • Notifying the organizer and participant of changes. What should we tell them, and what options should be offered when we notify them?
  • Building Calendar files (.ics) for import to Google Calendar, Outlook and Apple Calendar with the invitation details. Once the meeting is finalized, we can send a downloadable .ics file.
  • Building a view of a meeting that's fully finalized. What should the meeting details look like when it no longer needs to offer commands for choosing places and times? But, also, what commands are needed for rescheduling, time shifting, canceling, changing location or date and time, etc.?

The next episode will explore some of these questions, focusing on the links within the invitation that recipients will want to respond to despite initially never having registered with Meeting Planner before. Other issues will have to wait a bit longer.

I'm also beginning to experiment with WeFunder based on the implementation of the SEC's new crowdfunding rules. Please consider following our profile. I may write about this more as part of this series.

Watch for upcoming tutorials in my Building Your Startup With PHP series—I hope you agree this is getting kind of exciting!

Please feel free to add your questions and comments below; I generally participate in the discussions. You can also reach me on Twitter @reifman.

Related Links



Related Articles