We're sorry but this page doesn't work properly without JavaScript enabled. Please enable it to continue.
Feedback

"It's about time to take your medication!" or how to write a friendly reminder bot ;-)

00:00

Formal Metadata

Title
"It's about time to take your medication!" or how to write a friendly reminder bot ;-)
Title of Series
Part Number
61
Number of Parts
173
Author
License
CC Attribution - NonCommercial - ShareAlike 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this
Identifiers
Publisher
Release Date
Language
Production PlaceBilbao, Euskadi, Spain

Content Metadata

Subject Area
Genre
Abstract
Florian Wilhelm - "It's about time to take your medication!" or how to write a friendly reminder bot ;-) The author shows how to use the [SleekXMPP] library in order to write a small chatbot that connects to Google Hangouts and reminds you or someone else to take medication for instance. The secure and recommended OAuth2 protocol is used to authorize the bot application in the [Google Developers Console] in order to access the Google+ Hangouts API. The author will elaborate then on how to use an event- driven library to write a bot that sends scheduled messages, waits for a proper reply and repeats the question if need be. Thereby, a primer on event-driven architectures will be given.
Keywords
51
68
Thumbnail
39:40
108
Thumbnail
29:48
Value-added networkRobotMetropolitan area networkMaxima and minimaElectronic meeting systemGamma functionWhiteboardMultiplication signEvent-driven programmingComputer architectureGroup actionGraphical user interfaceRobotEvent horizonBitLoop (music)StatisticsBlock (periodic table)Process (computing)Form (programming)Task (computing)Goodness of fitWritingData transmissionData miningCASE <Informatik>CoprocessorPoint (geometry)Computer programmingReal numberHash functionRight angleMessage passingContrast (vision)Engineering physicsParallel computingVideo gameThread (computing)Broadcast programmingSystem callDifferent (Kate Ryan album)Analytic continuationTable (information)FacebookImplementationAdventure gameComputer multitaskingSmartphoneCuboidoutputLatent heatState of matterGreatest elementInstance (computer science)SynchronizationWindowQuery languageMathematicsFunction (mathematics)EstimatorSocial classSoftwareLecture/ConferenceXML
Single-precision floating-point formatTask (computing)Maxima and minimaGamma functionSample (statistics)Executive information systemMetropolitan area networkInheritance (object-oriented programming)VarianceHigher-order logicArmValue-added networkPlastikkarteTask (computing)Multiplication signBlock (periodic table)Computer programmingDirection (geometry)WeightPoint (geometry)Functional (mathematics)Graph coloringConcurrency (computer science)Disk read-and-write headComputer fileEndliche ModelltheorieEvent horizonWeb pageTelecommunicationEvent-driven programmingString (computer science)Socket-SchnittstelleContrast (vision)Parallel portUser interfaceTranslation (relic)Data modelSynchronizationElectronic mailing listSummierbarkeitHeat transferSingle-precision floating-point formatCartesian coordinate systemMessage passingCASE <Informatik>WordInterface (computing)NumberSoftwareMaster-GleichungThread (computing)Normal (geometry)Revision controlCuboidBitHuman migrationPrisoner's dilemmaDiagramInterpreter (computing)Uniform resource locatorPrice indexReading (process)Instance (computer science)Overhead (computing)Transformation (genetics)Library (computing)Letterpress printingXML
Metropolitan area networkTask (computing)World Wide Web ConsortiumClient (computing)StatisticsElectronic mailing listMereologyBitComputer programmingFunctional (mathematics)Web pageElectronic mailing listMultiplication signXMLComputer animation
Task (computing)Inheritance (object-oriented programming)Electronic mailing listMetropolitan area networkWeb pageOperator (mathematics)ResultantSystem callProxy serverComputer animation
Letterpress printingResultantFunctional (mathematics)Multiplication signElectronic mailing listComputer animation
Functional (mathematics)Event horizonTask (computing)ResultantDifferent (Kate Ryan album)Computer animation
CodeInheritance (object-oriented programming)Value-added networkInterior (topology)Task (computing)Dependent and independent variablesArmMetropolitan area networkJava appletBit error rateStatement (computer science)Instance (computer science)CASE <Informatik>Functional (mathematics)WeightPoint (geometry)CodeInformation securityWritingCoroutineComputer animation
Metropolitan area networkArmDependent and independent variablesTask (computing)Functional (mathematics)Dependent and independent variablesMultiplication signTask (computing)Point (geometry)Computer animation
ArmMetropolitan area networkTask (computing)Data typeMathematical singularityGoogolMessage passingState of matterGrand Unified TheoryState of matterRight angleMessage passingTask (computing)Multiplication signPoint (geometry)Loop (music)ResultantRevision controlElectronic mailing listInstance (computer science)Functional (mathematics)Event horizon1 (number)Web pageLibrary (computing)Letterpress printingProcess (computing)RobotGoodness of fitGraph (mathematics)Graph (mathematics)Event-driven programmingReading (process)AbstractionComputer animation
State of matterGrand Unified TheoryTask (computing)BootingMetropolitan area networkDiscrete element methodGoogolReverse engineeringDevice driverImplementationLoop (music)Event horizonExt functorGamma functionExecutive information systemMaxima and minimaOpen setStandard deviationInformation systemsValue-added networkGroup actionAlpha (investment)AngleProjective planeComputer fileStress (mechanics)State of matterGroup actionMultiplication signSocial classRight angleDifferent (Kate Ryan album)Event horizonClient (computing)WebsiteCodeCommunications protocolMessage passingPower (physics)ResultantTouchscreenServer (computing)MereologyPhysical systemFunctional (mathematics)Cartesian coordinate systemDefault (computer science)Task (computing)PasswordAuthorizationBitComputer programmingWindows RegistryPosition operatorSource codePoint (geometry)Data conversionCASE <Informatik>Reverse engineeringGoogle TalkState diagramInstant MessagingFacebookMoment (mathematics)Data transmissionLine (geometry)Library (computing)Particle systemImplementationSoftwareGoodness of fitSet (mathematics)ChatterbotAuthenticationRobotStandard deviation2 (number)GoogolState observerXML
System programmingTelecommunicationWebsiteXMLUML
InformationProof theoryStatisticsTemplate (C++)Machine learningData conversionPhysicalismInstance (computer science)Message passingLibrary (computing)CASE <Informatik>Link (knot theory)State of matterNeuroinformatikFacebookArithmetic meanRight angleQuicksortMeasurementSmartphoneBasis <Mathematik>Communications protocolArmExecution unitVirtual machineTablet computerRobotLecture/Conference
Transcript: English(auto-generated)
Thank you everybody, and welcome to my talk, it's about time to take your medication, or how to write a friendly reminder board. So, I also work at Blue Yonder, so normally I'm more like a data scientist guy, and yeah, the last EuroPython in Berlin, I gave a talk about how you can extend Scikit-Learn with your own estimator,
so quite mathy stats talk, and there were about 15 people that thought, okay, so this year I'll try something different, and well, okay, it's a little bit better at least. So, surely the question that you all have is, why would anyone write chatbot?
And there's a little story behind it, so a friend of mine was diagnosed with diabetes, so you surely all know diabetes, so you have to take insulin the whole time, and he said that, yeah, so there's two kinds of insulin, there's one you take before you eat something, or while you eat something, and then there's the long-acting insulin,
this is something you have to take at a specific time during the day. And he said that he's always like forgetting about this, or taking it one hour too late, or too early, and of course he sets alarm on his smartphone, but it would be really cool if someone would somehow remind him,
just like use a chat, or call him, or somehow remind him, and then the idea was born, okay, why not write a little bot that uses Google Talk, or Facebook, or any kind of chatting engine, and reminds him to actually please take your long-acting insulin now,
and to also wait for an answer that he really did it, and otherwise remind him again, and all over. And I thought, well, that's also good for me, it's not only that I'm helping a friend, it's also for me, because it's a good use case to actually start learning something new,
learning more about event-driven asynchronous programming, something where there's a real hype right now, I mean everyone's talking about AsyncIO, there were a lot of talks about AsyncIO, I don't know if you've seen the talk by Niklas about the distributed hash table,
which was I think a really great talk about AsyncIO, so I took this as a use case, I want to learn something about it, also a little bit about XMPP, and about how one can write a Google app, because in the end I used Google Hangouts to actually implement it, and of course, yeah, to help a friend.
So, the first thing I want to talk about is what is event-driven programming, and what it has to do with asynchronous programming. So, event-driven programming, this is the definition of Jessica McKellar from the twisted network programming essentials, in an event-driven program, program flows is determined by external events,
it is characterized by an event loop, and the use of callback to trigger action when events happen. So this is basically the definition, and it's just stated by any kind of event, an event could be like a user triggers an action, or a message is received over a network, and then you have predefined actions, the so-called callbacks, that are then triggered,
and that actually do something. And in most cases this is implemented as a kind of event loop, as a main loop that listens for events and triggers the callbacks, and callbacks are just continuations, so it's just like,
what do I do if I get a message, or if I have received something. And event-driven programs can be single-threaded, but also multi-threaded architecture exists, so due to the gill in Python, so asyncIO is mostly single-threaded, but you could also imagine that you had for each callback,
you could start a new thread or something, then you would have a more multi-threaded event-driven program, but this is mostly not what it's done in most implementations. And to differentiate this a little bit from what is blocking and non-blocking,
you could think of an event-driven program itself, purely from the definition, could be blocking or could be non-blocking. That means, for instance, if you have a GUI, and you click on the button, then an event is triggered, some action is processed, and during that action,
your whole GUI could be blocking. I mean, this is sometimes things you see on Windows, for instance, that the whole GUI blocks and is unresponsive, or while evaluating this callback could be non-blocking so that other things can happen at the same time. Or for instance, another example would be some kind of 3D computer game.
I mean, while the engine is waiting for user input, it's still calculating the physics engine and is updating the graphics. So, what is asynchronous programming then? Asynchronous I-O, or non-blocking I-O, is a form of input-output processing
that permits other processing to continue before the transmission has finished. So, this is also a bit like a form of cooperative multitasking, because you kind of, at certain points during your execution,
you kind of give away the processor to other things, and you give it away so other tasks can use the processor. So, but it's cooperative in contrast to preemptive in the sense that it's really at specific points, and we will see that later.
And the concept can also be implemented as an event loop. So, since a picture says more than 1,000 words, so I'll have this graphic. So, if we have a program, something, a really simple program
that basically consists of three tasks, and the tasks have different colors, and if you see the gray boxes are actually like waiting times. This is when the task reads in a file or maybe waits for a network socket or message or an event of the user, then it kind of, it suspends its work, it waits,
and the total time of the program is the sum of all those blocks. So, in multi-threaded, you would like conically put each task in on thread and execute them in parallel.
So, this is something you would not do like this in Python. In Python you would more or less use processes because of the global interpreter lock, but in this case, it's not important. The point here is that you still have the gray blocks and the tasks are still waiting until some IO is ready, for instance.
And in asynchronous, there it is that you have only one thread again, but during the gray blocks, there's actually a switch to another task,
and something is done. So, here we start with the blue, then during the waiting time here, we start working on task number two and even on task number one, since we also have task number three, because here we also have a waiting block, and then it's in a concurrent way and in a way that can't be like really deterministic toll.
So, the colors could also change on the right side, and I think this is an important point. So, concurrent and event-driven programming, you don't know beforehand what the path, the thread through your program is going to be.
So, when to actually use asynchronous event-driven programming? If you have many tasks, of course, you should have at least two, otherwise it makes no really sense. If the tasks are largely independent, so if there's no much intercommunication between two tasks, you could imagine if two tasks are the whole time talking to each other,
then this could be difficult. Then, of course, when your tasks wait for IO, when they normally would block, and you think you could do it during that time, you could do other things, and if your tasks share a lot of mutable data, it would need to be synced if you do it in a multi-threaded or multi-processing way.
This is also like an indicator that you could think about using something asynchronous or something event-driven. And this is especially for network application and user interfaces. This is like, naturally, that you use asynchronous event-driven programming.
So, some examples I want to show to better get the idea. So, easy tasks, just fetch some URLs and print them and check the libx time.
So, how would this look like in a single-threaded version? So, we have some hosts, just a list. We set our timer, and for each host, we use the URL lib to request the host. And then we print it. We also do a little transformation to make it a little bit more interesting.
We just make everything uppercase and print the first 20 characters and the host where we got the webpage from and print the elapsed time. So, this would be like a normal single-threaded program in Python, how you would do it. And, of course, here is like the blocking.
So, here is actually the great block that we've seen before in our diagram because we are waiting here for the request to be fulfilled and we wait for getting the request. And also here we wait to read the HTML. So, now let's do this in a multi-threaded way.
Here it gets only a little bit more complicated. So, we also do just the request and the reading in one function. And now we generate some threads. So, each task is just now a thread and it's listed in the chops list.
And we start here with our timer. So, I skip the overhead of creating the tasks, the threads. Then for each chop we start it, we wait until they're joined, so until they're finished, and we see that there was a speed up.
So, this is just more or less a direct translation of the single-threaded program in a multi-threaded program. So, how would this look like in an asynchronous style? And I used here Twisted, which is right now only available for Python 2, but they are just working on a migration to Python 3.
So, here it gets a bit more complicated because we kind of have to separate the different parts of the program much more and we use now callbacks. So, we have here the capitalized function. So, okay, we just use capitalize and strip it down to 20 characters.
And we print elapsed time. And now here it's the interesting part. So, for East Host in our host list, we get the page. And this is now a non-blocking operation. So, this will directly return and will get us a deferred result. And a deferred result is what in Python async I always call the future.
So, it's actually just a proxy for future result. And you can say what should happen if the result is retrieved. And this is what you do with the add callback. So, you say if the deferred result ever becomes the real result,
then please call the print capitalized function with it. And this is, yeah, so we registered our callback. And then we add everything to the list and then we say, okay, now for all lists, if all deferred results actually fired, then we also want to fire the print elapsed time function.
And we call it with a task react, the main function. So, this is now the event loop, so to say. So, we say, okay, run this loop and run the function. And we see, yeah, that it worked. But what you can see from this example is it gets really complicated.
So, adding the callbacks, it's like you have to think, okay, I have deferred result and I add callbacks. And if those fired, I group them and add another one. So, it gets really complicated. And this is also a statement that Guido van Rossum supposedly once said. So, I found it on the net this quote.
And the net never lies, right? So, it requires superhuman discipline to write readable code in callbacks. And if you don't believe me, look at any piece of JavaScript code. And so the question is how would this now look if you would, for instance, use asyncio? So, in asyncio, you would use a coroutine.
So, coroutine, so how many of you know what a coroutine is? So, okay, I would say most. So, it's just a function where you can, like, it's not a function. Coroutine is like a more general idea of a function. But you can stop at one point, return and come back.
And here, I use the aio HTTP, which is based on asyncio. And at that point, we yield from the request. And so we give away the execution here for other tasks to do something at the waiting time. But what we get in return is the real response.
So, if the function here, so you yield from, if the function after yield from returns a future, you wait until the future gets, like, realized. Or if it's a coroutine, until the next result is generated.
And then we yield from the response and read and we directly get the HTML. And now, for each in host, we have a task list again. We append this print page function. We get the event loop and we run the task until they're done.
And we also see the speedup. So, the point here is that using asyncio and avoiding callbacks in this example, it's much more readable and it much more looks like the single-threaded version, actually. And, yeah, it avoids these complicated graphs of callbacks.
So, I think this gets you, like, a good idea about asynchronous event-driven programming. So, now back to our actual task. So, how to build now a bot based on this. So, the idea is we notify a friend at 8 p.m. as agreed about taking his long-acting insulin using Google Talks or Google Hangout.
Then we wait 20 minutes for reply. Then we ask again, did you really take it, and ask again after another time. During the whole time, we check if there's a message which starts or is equal to yes.
If we get this message, we praise him, we say, yeah, well done, good job. And if the message is any other to yes, we just ignore it. Of course, we could also send something like I didn't get it or so.
Yeah, and after having three times asked in total, we want to send the give up message like, okay, now I'm giving up and ask again tomorrow. So, when actually stating something like this, it's, for me at least, it was helpful to come up first with the state graph because what we are actually doing with the abstraction is that we are changing between different states
and there are also libraries for this in Python. But before I build it, I just wanted to know, okay, so how many states do I actually have to make it, yeah, to make the solution as simple as possible. So, when during the day, we are in a no message sent state, so this is the initial state,
and what happens if we, for instance, get any kind of message, so this is the event from my buddy, from my friend, at that time, then we just do nothing. So, to avoid things that he, for instance, writes yes before I even have asked.
I mean, this is a situation to consider. And so, at the event at 8 p.m., we send a message. We are now in the message sent state, so if he replies then with a yes, we send, okay, that's good, send the praise, and go back. After another 20 minutes, we ask again, and I think you get the idea until that point,
and there is also if he then repeats with yes, it's still okay, but after one hour, we send, okay, you've done not so good, and we give up. And this is how it can be translated in a program.
But which protocols are actually used? So, first I thought about, or I started to implement it in XMPP, so XMPP is the Extensible Message and Presence Protocol, which is based on XML, or formerly it was known as Chubber, and Google Talk, so gTalk used it,
but it was deprecated quite lately, so Google switched to Hangout, which is a proprietary protocol, which is not that good. Even Facebook, they had an XMPP AP until just recently, May 2015,
where they stopped it, so this is not so good, but still, gTalk is working. And I also did the implementation for this, and so if you want to ever do something with XMPP,
I would recommend the Sleek XMPP library, and you also get a lot of good documentation about it. But since it was deprecated, I switched to Google Hangouts, as I said, a proprietary protocol, and a really good library that was kind of, that is a reverse engineering of Google Hangouts is Hangouts by Tom Dreyer,
and yeah, it's a quite active project at the moment, and it also already provides chat client, interactive chat client, and there's a lot of bots already based on Hangouts, so this is a really interesting project.
So the implementations, the two, can be found on the Blue Yonder website, not Blue Yonder website, but Blue Yonder group GitHub account, and I want to just show some code examples, so where it all starts,
it's like the run of the bot class, so it's really not that much code, actually, so you can later just look it up. So the interesting part is that the client is now the Hangout protocol client,
and you say what should happen on a connect, you connect different functions to the events that are then called, so this is the observer pattern, and we have here the event loop, we get the seconds to the next alarm, so it's just the function that calculates from now to next 8pm today or tomorrow,
and says later I'm going to call the function set alarm, and then it's like calling the connect function of the client to do some more registering of callbacks. So how does the set alarm function look like?
It's a little bit more interesting, so here's the message, we get the conversation with the recipient, because you could chat to many people at the same time, we yield from the message, so this is also again a point
where we give away the execution to do something others, like waiting for an answer or for doing other kind of network transmissions, we set here the state that we are now in the ask state, we sleep, and since we yield from asyncio.sleep here,
it's also we give away the execution to other tasks that can be run concurrently, and here it's just this three times asking, and here is the giving up, and in the end we just set the timer, set it back to the next time,
and I think the code is quite easily readable, and it more or less avoids the registering a lot of callbacks on some kind of deferred results, like you would have done it maybe with Twisted. And now handling a message,
so on event when the message is received, we get from the message the conversation, we get the user ID, we get the text, what was actually sent, we check if the user ID is equal to the recipient ID, to the one we want to talk,
we check if the text is positive, a positive answer, and if everything is fulfilled, we are in the right state, it is positive, and it's from our body, we just send the message, that's great, and go back in the asked equals false state, so we go back to the initial state in our state diagram.
Alright, that's much about the source code, as I said you can just check it up online. Maybe one more thing about authorization, if you write a bottle like this, you don't want to provide your credentials and put it somewhere in a file, so this is where the authentication to standard comes into play,
and this allows that you as a resource owner, give special rights to your application, and it works by using user tokens, so how does this work?
Your application, all it wants to do is to use your Google account to actually send some messages, and it doesn't need to know all your contacts, it's just sending messages, so it requests a token with a scope of sending messages, then you get a URL, you can display to the user,
basically you all know these kind of screens, where you then just click accept, and you get the authorization code back, and you can use this code to get a token, and with this token your application can then, without knowing your password of your Google account,
use the Google API to send messages over Hangouts or Google Talk. Alright, so just a picture to show how it looks like in the end,
and it's just an easy use case, but it worked in the end and he's quite happy with it. Thanks to Tom Dreyer, so this was the guy from Hangouts, who also helped me a bit, and all the pictures I took are creative comments, and thank you for your attention.
Hi, thanks for your talk.
I actually have two small questions, like have you thought of implementing this on other communication supports, like for example Telegram, WhatsApp, all this kind of stuff? Have you thought of other communication supports apart from Hangouts, like WhatsApp, Facebook, Telegram, are you implementing it?
And the other question is, I actually thought of making something like this, having a chronic disease myself to just remember stuff, but what I thought would be really interesting in this, would be to have some kind of AI or machine learning, to actually, for having the computer,
knowing when I'm more keen to forget to take it, or this kind of stuff, so is it some kind of idea you have in the future? Because I would be really interested in participating then. I also thought about this, because now I now get the messages, so when he took it, and maybe over the weekend,
it's more easy to forget, right? I mean maybe you're in a party or whatever, and it's just not the right time, and you're like, you don't do anything, and of course you could then run a lot of statistical analysis on it, and I mean since I work as a data scientist, of course if you would have a lot of information about this,
you could do some statistics, you could even predict that on the weekend, yeah, but on the other hand, it's always with private information, right? Because yeah, but I think this is a good idea, and I think the basic ideas to your first question could also be easily done on Facebook,
and so there are a lot of libraries if you start looking for it, and there are also a lot of bot libraries that could help with finding the right answers, or making maybe the conversation a lot more interesting, so there's stuff like this, I wanted to keep it simple as a first try,
but yeah, now one could definitely build on it. More questions? Hi, yeah, that's really great. Have you thought of putting any kind of link back
to maybe something physical like opening a packet so that you both have proof as well as his yes command that he has taken this into it? Excuse me like that. So say he had to open a packet that moved a switch, and that was recorded that he had.
I'm more thinking about say people with Alzheimer's who need to be reminded to take tablets. Have you thought of expanding it in that kind of way? So I mean in the physio world, they're really keen on making sure
that people do actually take their tablets as opposed to just saying yes, they've taken them. So have you thought of expanding it so that you can have a switch that saw that someone had opened a pill box, say? Ah, okay, now I understand, yeah. I mean, then it gets of course more complicated. You would need to have the device or what those insulin pumps, for instance.
Some already have some, yeah, technique in it, and if one could access that protocol, and then you could maybe even, yeah, he could connect his smartphone to that device. I know that there's a lot going on.
For instance, the measurement of the blood sugar is now just like three months ago, there was a new device from Libra which is constantly like measuring your blood sugar. You have it on your right arm, and you can just read it out on a second-by-second basis,
which is much better than doing it the conventional way. And of course, one could trigger back, so if you took it, then you will also get from this sensor that the blood sugar goes down. And so there's endless possibilities, but then I would need to like, I mean, this was not a commercial idea or something,
it was just for me a use case, but I think it's definitely possible in the technical sense, and one could follow up on that, yeah, definitely. More questions? Right, that was fascinating. Thank you very much again, Fran.
Thank you.