{"id":3658,"date":"2025-05-06T02:02:35","date_gmt":"2025-05-06T06:02:35","guid":{"rendered":"https:\/\/techministry.blog\/?p=3658"},"modified":"2025-05-06T02:02:35","modified_gmt":"2025-05-06T06:02:35","slug":"building-a-digital-roster-serving-board-using-companion-and-the-planning-center-services-api","status":"publish","type":"post","link":"https:\/\/techministry.blog\/?p=3658","title":{"rendered":"Building a digital roster\/serving board using Companion and the Planning Center Services API"},"content":{"rendered":"\n<p>If you\u2019re involved in tech ministry and like to tinker, chances are you\u2019ve heard of \u2014 and maybe even used \u2014 <a href=\"http:\/\/micboard.io\">micboard.io<\/a>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/techministryblog.wordpress.com\/wp-content\/uploads\/2025\/03\/image.png?w=1024\" alt=\"\" class=\"wp-image-3660\" \/><figcaption class=\"wp-element-caption\">This is Micboard.<\/figcaption><\/figure>\n\n\n\n<p>Straight from their website, &#8220;<em>Micboard simplifies microphone monitoring and storage for artists, engineers, and volunteers. View battery, audio, and RF levels from any device on the network.<\/em>&#8221; It&#8217;s a neat tool and has helped a lot of teams over the years.<\/p>\n\n\n\n<p>I always liked the idea of Micboard because it would be a great way to show who is serving that day. We tried to implement it at my church but eventually moved away from it, mainly because it hadn\u2019t been updated in quite a while (over 6 years now), and we needed some additional features. Specifically, we were looking for integration with Planning Center Services \u2014 something that could automatically pull assignments from an interface our team was already familiar with. And &#8211; something we could use for more than just people on stage.<\/p>\n\n\n\n<p>At first, I forked the Micboard repo (since it\u2019s open-source) and started making improvements, cleaning up some code, and tweaking it to run more easily on modern MacOS systems. But pretty quickly, I realized I had too much on my plate to maintain a whole fork long-term.<\/p>\n\n\n\n<p>Fast forward a year or so. I came across a few posts on some Facebook groups that I was in where people were using my <a href=\"https:\/\/techministry.blog\/2024\/12\/20\/streamlining-electron-app-development-with-ai-building-a-virtual-stream-deck-for-bitfocus-companion-using-the-satellite-api\/\">ScreenDeck<\/a> project to essentially create a <em>Micboard style<\/em> interface using Companion.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img decoding=\"async\" src=\"https:\/\/techministryblog.wordpress.com\/wp-content\/uploads\/2025\/03\/screenshot-2025-03-26-at-12.13.09e280afam.png?w=680\" alt=\"\" class=\"wp-image-3665\" style=\"width:770px;height:auto\" \/><figcaption class=\"wp-element-caption\">I wish I had my own Acoustic Bear.<\/figcaption><\/figure>\n\n\n\n<p>What I loved about this approach is that it leveraged something we were already using \u2014 Companion \u2014 and could still be viewed from anywhere on the network, just like Micboard. Plus, Companion supports a lot more devices beyond just Shure systems.<\/p>\n\n\n\n<p>Even better, this opened the door to that Planning Center integration I had wanted without introducing a bunch of extra overhead \u2014 we were already using the PCO module to control our LIVE service plans!<\/p>\n\n\n\n<p>One thing I\u2019ve wanted for a while was a <strong>digital roster<\/strong> \u2014 something simple to show who\u2019s serving each day, helping everyone put names to faces across band, tech, safety, and more. A \u201cServing Board,\u201d if you will.<\/p>\n\n\n\n<p>About a year ago, I had modified the PCO module to pull scheduled people into variables \u2014 showing their names and assigned roles. I recently took it further by adding a feedback: <strong>\u201cShow Person Photo based on Position Name.\u201d<\/strong><\/p>\n\n\n\n<p>Now, the module pulls the photo from the person\u2019s assignment, converts it into a PNG, and stores it internally as a base64 image \u2014 which can be shown directly on a button.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><img decoding=\"async\" src=\"https:\/\/techministryblog.wordpress.com\/wp-content\/uploads\/2025\/04\/screenshot-2025-04-26-at-9.16.29e280afpm.png?w=657\" alt=\"\" class=\"wp-image-3831\" style=\"width:657px;height:auto\" \/><\/figure>\n<\/div>\n\n\n<p>Pretty cool &#8211; and it looks like this:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img decoding=\"async\" src=\"https:\/\/techministryblog.wordpress.com\/wp-content\/uploads\/2025\/04\/screenshot-2025-04-26-at-9.19.10e280afpm.png?w=83\" alt=\"\" class=\"wp-image-3833\" \/><figcaption class=\"wp-element-caption\">Say &#8220;hi&#8221;, Adam.<\/figcaption><\/figure>\n<\/div>\n\n\n<p>But I didn\u2019t want to stop there \u2014 I wanted the person\u2019s <strong>status<\/strong> (Confirmed, Unconfirmed, or Declined in PCO) to show too.<\/p>\n\n\n\n<p>Using the <em>companion-module-utils<\/em> library (thanks to another awesome Companion dev!), I added a simple colored border overlay for statuses.<\/p>\n\n\n\n<p>A few extra lines of code later:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img decoding=\"async\" src=\"https:\/\/techministryblog.wordpress.com\/wp-content\/uploads\/2025\/04\/screenshot-2025-04-26-at-9.17.02e280afpm.png?w=655\" alt=\"\" class=\"wp-image-3835\" \/><\/figure>\n<\/div>\n\n\n<p>And you can get this look!<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img decoding=\"async\" src=\"https:\/\/techministryblog.wordpress.com\/wp-content\/uploads\/2025\/04\/screenshot-2025-04-26-at-9.19.20e280afpm.png?w=83\" alt=\"\" class=\"wp-image-3837\" \/><figcaption class=\"wp-element-caption\">Thanks for confirming!<\/figcaption><\/figure>\n<\/div>\n\n\n<p>At this point, it was looking great \u2014 but I started thinking:<\/p>\n\n\n\n<p><em><strong>What if I don\u2019t want to redo all my buttons every week? What if my teams and roles change?<\/strong><\/em><\/p>\n\n\n\n<p>So I added a new option: a <strong>generic \u201cposition number\u201d approach.<\/strong><\/p>\n\n\n\n<p>You can now pick a position number in the plan (or within a specific team) \u2014 and the module will automatically pull the right person\u2019s info, week to week, without you having to manually reconfigure anything.<\/p>\n\n\n\n<p>For example:<\/p>\n\n\n\n<p>\u2022 Pick <strong>any number<\/strong> across the entire plan.<\/p>\n\n\n\n<p>\u2022 Or pick a number <strong>within a specific team<\/strong>, like Band or Tech.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img decoding=\"async\" src=\"https:\/\/techministryblog.wordpress.com\/wp-content\/uploads\/2025\/04\/screenshot-2025-04-26-at-9.31.07e280afpm.png?w=661\" alt=\"\" class=\"wp-image-3841\" \/><figcaption class=\"wp-element-caption\">With this option, you can choose any number, regardless of the team.<\/figcaption><\/figure>\n<\/div>\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img decoding=\"async\" src=\"https:\/\/techministryblog.wordpress.com\/wp-content\/uploads\/2025\/04\/screenshot-2025-04-26-at-9.30.52e280afpm.png?w=654\" alt=\"\" class=\"wp-image-3840\" \/><figcaption class=\"wp-element-caption\">This picks the first person scheduled in the band.<\/figcaption><\/figure>\n<\/div>\n\n\n<p>I also built some <strong>Module Presets<\/strong> to make setting this up super easy:<\/p>\n\n\n\n<p>\u2022 <strong>Generic Position Number<\/strong> (no specific team)<\/p>\n\n\n\n<p>\u2022 <strong>Position Number Within a Team<\/strong> (like \u201cBand\u201d only)<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img decoding=\"async\" src=\"https:\/\/techministryblog.wordpress.com\/wp-content\/uploads\/2025\/04\/screenshot-2025-04-26-at-9.31.22e280afpm.png?w=607\" alt=\"\" class=\"wp-image-3843\" \/><figcaption class=\"wp-element-caption\">Generic without regard to what Team<\/figcaption><\/figure>\n<\/div>\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img decoding=\"async\" src=\"https:\/\/techministryblog.wordpress.com\/wp-content\/uploads\/2025\/04\/screenshot-2025-04-26-at-9.31.31e280afpm.png?w=606\" alt=\"\" class=\"wp-image-3844\" \/><figcaption class=\"wp-element-caption\">In this example, you can choose a number within the Band team.<\/figcaption><\/figure>\n<\/div>\n\n\n<p>And here\u2019s where it all comes together:<\/p>\n\n\n\n<p>Let\u2019s say you have a \u201cWireless Assignments\u201d team in PCO, and you assign a person to a position called \u201cWireless 4.\u201d<\/p>\n\n\n\n<p>Now, using the Shure Wireless module in Companion, you can match that name and see live RF and battery stats for Wireless 4 \u2014 tied directly to the person assigned!<\/p>\n\n\n\n<p>All together, you get a clean, dynamic, reusable <strong>Micboard-style dashboard<\/strong> \u2014 all inside Companion, no extra tools required.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><img decoding=\"async\" src=\"https:\/\/techministryblog.wordpress.com\/wp-content\/uploads\/2025\/04\/screenshot-2025-04-26-at-9.35.35e280afpm.png?w=203\" alt=\"\" class=\"wp-image-3847\" style=\"width:203px;height:auto\" \/><\/figure>\n<\/div>\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img decoding=\"async\" src=\"https:\/\/techministryblog.wordpress.com\/wp-content\/uploads\/2025\/04\/screenshot-2025-04-28-at-5.12.12e280afpm.png?w=1024\" alt=\"\" class=\"wp-image-3863\" \/><\/figure>\n<\/div>\n\n\n<p>Here\u2019s a walk through video showing it all in action:<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<div class=\"embed-youtube\"><iframe loading=\"lazy\" title=\"Automating Volunteer Displays with PCO &amp; Companion\" width=\"840\" height=\"473\" src=\"https:\/\/www.youtube.com\/embed\/m3-ymOvpBhE?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/div>\n<\/div><\/figure>\n\n\n\n<p>The updated <a href=\"https:\/\/github.com\/bitfocus\/companion-module-planningcenter-serviceslive\">PCO Services Live module<\/a> is available now in the Companion betas \u2014 go check it out if you want to try it!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you\u2019re involved in tech ministry and like to tinker, chances are you\u2019ve heard of \u2014 and maybe even used \u2014 micboard.io. Straight from their website, &#8220;Micboard simplifies microphone monitoring and storage for artists, engineers, and volunteers. View battery, audio, and RF levels from any device on the network.&#8221; It&#8217;s a neat tool and has &hellip; <a href=\"https:\/\/techministry.blog\/?p=3658\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Building a digital roster\/serving board using Companion and the Planning Center Services API&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[17,29,38,40,44,46,50,51,68],"class_list":["post-3658","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-church","tag-javascript","tag-ministry","tag-nodejs","tag-pco","tag-planning-center","tag-production","tag-programming","tag-technology"],"_links":{"self":[{"href":"https:\/\/techministry.blog\/index.php?rest_route=\/wp\/v2\/posts\/3658","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/techministry.blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/techministry.blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/techministry.blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/techministry.blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3658"}],"version-history":[{"count":0,"href":"https:\/\/techministry.blog\/index.php?rest_route=\/wp\/v2\/posts\/3658\/revisions"}],"wp:attachment":[{"href":"https:\/\/techministry.blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3658"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/techministry.blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3658"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/techministry.blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3658"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}