Earlier this month, Pebble released version 3.6 of their SDK. My eyes widened when I discovered it included access to their Dictation API. This API gives all Pebble developers access to dictation from the Pebble Time microphone. I eagerly opened up the CloudPebble editor and began experimenting!
In this article, we'll explore the Dictation API by putting together a watchapp that accepts a dictated message and sends it to a Slack channel via IFTTT.
What You'll Need
In order to step through this guide, you'll need the following:
[author_more]
- A Pebble Time Watch - The older Pebbles do not have a microphone, so this won't work on them!
- An general knowledge in Pebble app development - If you are new to Pebble development, have a read of my beginner tutorial on Pebble Watch Development with JavaScript to get started.
- An IFTTT account
- A Slack account and Slack Channel to post to - You could switch this out for any other service which IFTTT allows you to send messages if you're not a Slack user.
The Code
There are developers out there who prefer to jump straight into the code. If you are that type of developer, all the code is available on GitHub.
Our watchapp will have two main files:
main.c
- Our C code manages the dictation, the display of instructions and display of the entered message.pebble-js-app.js
- This manages our communication to IFTTT.
IFTTT
I'd recommend setting up your IFTTT Maker channel and Slack rule first, just so the code set up we'll do after this makes more sense.
I've previously covered IFTTT in the articles Connecting LIFX Light Bulbs to the IoT Using IFTTT and Connecting the IoT and Node.js to IFTTT (this second one covers the Maker channel). So if you'd like a more in depth explanation of using IFTTT and the Maker channel, have a read through of those.
Here's a very quick runthrough of what you'll need to set up:
- Create an IFTTT account if you haven't already got one.
- Connect the Maker Channel and Slack Channel to your account.
- Create a new recipe with the Maker channel as the trigger.
- Choose the "Receive a web request" trigger option and name the event "slack_message".
- Choose the Slack channel to be the action channel for this IFTTT rule and choose the "Post to channel" action.
- Select the Slack channel you'd like the message to go to and set the message to only contain
{{Value1}}
. - You can remove the title, or choose something like "Pebble Message Received". I left it blank. I also left the thumbnail URL blank too.
- Create your action and you should be ready to go! IFTTT is ready to send any messages it receives from that event to the Slack channel you specified.
Our C Code
The main.c
file looks like so:
[code language="c"]
#include <pebble.h>
static Window *s_main_window;
static TextLayer *message_layer;
static DictationSession *s_dictation_session;
static char display_message[512];
static void handle_message(char *slack_message) {
DictionaryIterator *iter;
app_message_outbox_begin(&iter);
dict_write_cstring(iter, 0, slack_message);
app_message_outbox_send();
}
static void dictation_session_callback(DictationSession *session, DictationSessionStatus status, char *transcription, void *context) {
if(status == DictationSessionStatusSuccess) {
snprintf(display_message, sizeof(display_message), "Message sent!\n\n\"%s\"", transcription);
text_layer_set_text(message_layer, display_message);
handle_message(transcription);
} else {
static char error_message[128];
snprintf(error_message, sizeof(error_message), "Error code:\n%d", (int)status);
text_layer_set_text(message_layer, error_message);
}
}
static void select_click_handler(ClickRecognizerRef recognizer, void *context) {
dictation_session_start(s_dictation_session);
}
static void click_config_provider(void *context) {
window_single_click_subscribe(BUTTON_ID_SELECT, select_click_handler);
}
static void window_load(Window *window) {
Layer *window_layer = window_get_root_layer(window);
GRect bounds = layer_get_bounds(window_layer);
message_layer = text_layer_create(GRect(bounds.origin.x, (bounds.size.h - 72) / 2, bounds.size.w, bounds.size.h));
text_layer_set_text(message_layer, "Press select and tell me your Slack message :)");
text_layer_set_text_alignment(message_layer, GTextAlignmentCenter);
text_layer_set_font(message_layer, fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD));
layer_add_child(window_layer, text_layer_get_layer(message_layer));
}
static void window_unload(Window *window) {
text_layer_destroy(message_layer);
}
static void init() {
s_main_window = window_create();
window_set_click_config_provider(s_main_window, click_config_provider);
window_set_window_handlers(s_main_window, (WindowHandlers) {
.load = window_load,
.unload = window_unload,
});
window_stack_push(s_main_window, true);
app_message_open(app_message_inbox_size_maximum(), app_message_outbox_size_maximum());
s_dictation_session = dictation_session_create(sizeof(display_message), dictation_session_callback, NULL);
}
static void deinit() {
dictation_session_destroy(s_dictation_session);
window_destroy(s_main_window);
}
int main() {
init();
app_event_loop();
deinit();
}
[/code]
Our Dictation Calls
The first bit of code Pebble developers will notice is new is the line which sets up a DictationSession
. This is what we store our transcription data and other data related to the Dictation API within:
[code language="c"]
static DictationSession *s_dictation_session;
[/code]
Next, we define a simple char
array to store our latest successfully transcribed message:
[code language="c"]
static char display_message[512];
[/code]
Within our init()
function, we set up the actual dictation session so that it is ready and waiting for us to request it. It is set to provide space to store our dictated message that matches the length of display_message
. It also sets the callback function once we've performed dictation to be dictation_session_callback()
.
[code language="c"]
s_dictation_session = dictation_session_create(sizeof(display_message), dictation_session_callback, NULL);
[/code]
Running Dictation on Click
We want to set up our dictation to run when the user clicks the select button on their Pebble. We set click functionality via window_set_click_config_provider()
.
[code language="c"]
window_set_click_config_provider(s_main_window, click_config_provider);
[/code]
That tells our Pebble that our click functions are defined within click_config_provider()
. Within that, we initialize the process of dictation via a press of the select button (defined as BUTTON_ID_SELECT
in Pebble's SDK). This button action is set up via window_single_click_subscribe()
function.
[code language="c"]
static void click_config_provider(void *context) {
window_single_click_subscribe(BUTTON_ID_SELECT, select_click_handler);
}
[/code]
Continue reading %How to Use Pebble’s New Dictation API%
by Patrick Catanzariti via SitePoint
No comments:
Post a Comment