Friday, May 17, 2013

[Tasker] How to read out WhatsApp messages with Tasker and react on their content in real time

Update2:

They changed something since Android 5.
First, one needs a new sqlite3 binary. I found a working one at xda-developers.
Secondary, one has to change the database access terminal command in Tasker from

sqlite3 /data/data/com.whatsapp/databases/msgstore.db "SELECT timestamp,data,key_remote_jid FROM messages WHERE key_from_me='0' ORDER BY timestamp DESC LIMIT 1;"

to

cd /data/data/com.whatsapp/databases/;
sqlite3 msgstore.db "SELECT timestamp,data,key_remote_jid FROM messages WHERE key_from_me='0' ORDER BY timestamp DESC LIMIT 1;"

Now it works again. 
I will update the post soon and explain the changes in more detail. 

Update:

If you like this article, you should take a look at this one:
Make Tasker read aloud all incoming notifications and messages


Tasker can read out incoming or stored WhatsApp Messages, I used Tasker to do the following things on WhatsApp:
  • Display the incoming messages in iOS style, no need to pull down the notification menu to read the messages. The whole message is displayed in the menu bar. See screenshot for details
  • Play different notification sounds for different contacts or different message content, this way you can for example get a special notification if your name is mentioned.
  • Mute WhatsApp at specific times or at specific locations, without muting other notifications. 
  • Update: Read aloud WhatsApp messages
 What we need:
  • Tasker
  • WhatsApp
  • root. I want you to root your phone now! You need root for SQLite, we need it to read out the database of WhatsApp.
  • SQLite for Android
  • Kyo-Tux Aeon HD icon pack, provides useful icons for Tasker, its free and lightweight, so grab it

Here is the complete profile:
Profile: WhatsApp Statusbar
  Priority: 9 CoolDown: 0
  Event: Notification [ Owner Application:WhatsApp Title:* ]

Enter: WhatsApp Notification
  Run Both Together
  A1: Run Shell [ Command:sqlite3 /data/data/com.whatsapp/databases/msgstore.db "SELECT timestamp,data,key_remote_jid FROM messages WHERE key_from_me='0' ORDER BY timestamp DESC LIMIT 1;" Timeout (Seconds):15 Use Root:On Store Result In:%sql_result Continue Task After Error:On ]
  A2: If [ %sql_result !~ %SQL_RESULT_OLD ]
    A3: Variable Set [ Name:%SQL_RESULT_OLD To:%sql_result Do Maths:Off Append:Off ]
    A4: Variable Split [ Name:%sql_result Splitter:| Delete Base:On ]
    A5: Variable Set [ Name:%sql_result1 To:%sql_result1/1000 Do Maths:On Append:Off ]
    A6: Variable Convert [ Name:%sql_result1 Function:Seconds to Date Time Store Result In: ]
    A7: Variable Split [ Name:%sql_result1 Splitter: Delete Base:Off ]
    A8: Variable Search Replace [ Variable:%sql_result12 Search:\. Ignore Case:Off Multi-Line:Off One Match Only:Off Store Matches In: Replace Matches:On Replace With:: ]
    A9: Perform Task [ Name:Number->Name WhatsApp Stop:Off Priority:6 Parameter 1 (%par1):%sql_result3 Parameter 2 (%par2): Return Value Variable:%sql_result3 ]
    A10: Wait Until [ MS:0 Seconds:5 Minutes:0 Hours:0 Days:0 ] If [ %sql_result3 !~R @s.whatsapp.net ]
    A11: Array Push [ Name:%WHATSAPP_NOTIFY Position:1 Value:%sql_result3: %sql_result2 Fill Spaces:Off ]
    A12: Notify Cancel [ Title:%WHATSAPP_NOTIFY4 Warn Not Exist:Off ]
    A13: Variable Clear [ Name:%WHATSAPP_NOTIFY4 Pattern Matching:Off ]
    A14: Notify [ Title:%sql_result3: %sql_result2 Text:%sql_result2 Icon:ipack:kyotuxaeonhd:buddy_green Number:0 Permanent:Off Priority:3 ]
    A15: Perform Task [ Name:Play Sound Stop:Off Priority:6 Parameter 1 (%par1): Parameter 2 (%par2): Return Value Variable: ]
  A16: End If
Click here to see the WhatsAppStatusbar.prf.xml you can import directly into Tasker.
<TaskerData sr="" dvi="1" tv="1.3.3u2m">
 <Profile sr="prof59" ve="2">
  <cdate>1353556343390</cdate>
  <edate>1368831772583</edate>
  <flags>1</flags>
  <id>59</id>
  <mid0>175</mid0>
  <nme>WhatsApp Statusbar</nme>
  <pri>9</pri>
  <Event sr="con0" ve="2">
   <code>461</code>
   <pri>1</pri>
   <App sr="arg0">
    <appClass>com.whatsapp.Main</appClass>
    <appPkg>com.whatsapp</appPkg>
    <label>WhatsApp</label>
   </App>
   <Str sr="arg1" ve="3"/>
  </Event>
 </Profile>
 <Task sr="task175">
  <cdate>1353556370005</cdate>
  <edate>1368831772583</edate>
  <id>175</id>
  <nme>WhatsApp Message</nme>
  <pri>10</pri>
  <rty>2</rty>
  <Action sr="act0" ve="3">
   <code>123</code>
   <se>false</se>
   <Str sr="arg0" ve="3">sqlite3 /data/data/com.whatsapp/databases/msgstore.db "SELECT timestamp,data,key_remote_jid FROM messages WHERE key_from_me='0' ORDER BY timestamp DESC LIMIT 1;"</Str>
   <Int sr="arg1" val="15"/>
   <Int sr="arg2" val="1"/>
   <Str sr="arg3" ve="3">%sql_result</Str>
  </Action>
  <Action sr="act1" ve="3">
   <code>37</code>
   <lhs>%sql_result</lhs>
   <op>2</op>
   <rhs>%SQL_RESULT_OLD</rhs>
  </Action>
  <Action sr="act10" ve="3">
   <code>355</code>
   <Str sr="arg0" ve="3">%WHATSAPP_NOTIFY</Str>
   <Int sr="arg1" val="1"/>
   <Str sr="arg2" ve="3">%sql_result3: %sql_result2</Str>
   <Int sr="arg3" val="0"/>
  </Action>
  <Action sr="act11" ve="3">
   <code>779</code>
   <Str sr="arg0" ve="3">%WHATSAPP_NOTIFY4</Str>
   <Int sr="arg1" val="0"/>
  </Action>
  <Action sr="act12" ve="3">
   <code>549</code>
   <Str sr="arg0" ve="3">%WHATSAPP_NOTIFY4</Str>
   <Int sr="arg1" val="0"/>
  </Action>
  <Action sr="act13" ve="3">
   <code>523</code>
   <Str sr="arg0" ve="3">%sql_result3: %sql_result2</Str>
   <Str sr="arg1" ve="3">%sql_result2</Str>
   <Img sr="arg2" ve="2">
    <nme>buddy_green</nme>
    <pkg>net.dinglisch.android.ipack.kyotuxaeonhd</pkg>
   </Img>
   <Int sr="arg3" val="0"/>
   <Int sr="arg4" val="0"/>
   <Int sr="arg5" val="3"/>
  </Action>
  <Action sr="act14" ve="3">
   <code>130</code>
   <Str sr="arg0" ve="3">Play Sound</Str>
   <Int sr="arg1" val="0"/>
   <Int sr="arg2" val="6"/>
   <Str sr="arg3" ve="3"/>
   <Str sr="arg4" ve="3"/>
   <Str sr="arg5" ve="3"/>
  </Action>
  <Action sr="act15" ve="3">
   <code>38</code>
  </Action>
  <Action sr="act2" ve="3">
   <code>547</code>
   <Str sr="arg0" ve="3">%SQL_RESULT_OLD</Str>
   <Str sr="arg1" ve="3">%sql_result</Str>
   <Int sr="arg2" val="0"/>
   <Int sr="arg3" val="0"/>
  </Action>
  <Action sr="act3" ve="3">
   <code>590</code>
   <Str sr="arg0" ve="3">%sql_result</Str>
   <Str sr="arg1" ve="3">|</Str>
   <Int sr="arg2" val="1"/>
  </Action>
  <Action sr="act4" ve="3">
   <code>547</code>
   <Str sr="arg0" ve="3">%sql_result1</Str>
   <Str sr="arg1" ve="3">%sql_result1/1000</Str>
   <Int sr="arg2" val="1"/>
   <Int sr="arg3" val="0"/>
  </Action>
  <Action sr="act5" ve="3">
   <code>596</code>
   <Str sr="arg0" ve="3">%sql_result1</Str>
   <Int sr="arg1" val="4"/>
   <Str sr="arg2" ve="3"/>
  </Action>
  <Action sr="act6" ve="3">
   <code>590</code>
   <Str sr="arg0" ve="3">%sql_result1</Str>
   <Str sr="arg1" ve="3"/>
   <Int sr="arg2" val="0"/>
  </Action>
  <Action sr="act7" ve="3">
   <code>598</code>
   <Str sr="arg0" ve="3">%sql_result12</Str>
   <Str sr="arg1" ve="3">\.</Str>
   <Int sr="arg2" val="0"/>
   <Int sr="arg3" val="0"/>
   <Int sr="arg4" val="0"/>
   <Str sr="arg5" ve="3"/>
   <Int sr="arg6" val="1"/>
   <Str sr="arg7" ve="3">:</Str>
  </Action>
  <Action sr="act8" ve="3">
   <code>130</code>
   <Str sr="arg0" ve="3">Number-&gt;Name
WhatsApp</Str>
   <Int sr="arg1" val="0"/>
   <Int sr="arg2" val="6"/>
   <Str sr="arg3" ve="3">%sql_result3</Str>
   <Str sr="arg4" ve="3"/>
   <Str sr="arg5" ve="3">%sql_result3</Str>
  </Action>
  <Action sr="act9" ve="3">
   <code>35</code>
   <lhs>%sql_result3</lhs>
   <op>12</op>
   <rhs>@s.whatsapp.net</rhs>
   <Int sr="arg0" val="0"/>
   <Int sr="arg1" val="5"/>
   <Int sr="arg2" val="0"/>
   <Int sr="arg3" val="0"/>
   <Int sr="arg4" val="0"/>
  </Action>
  <Img sr="icn" ve="2">
   <cls>com.whatsapp.Main</cls>
   <pkg>com.whatsapp</pkg>
  </Img>
 </Task>
</TaskerData>


The most important line is A1. Here we use the installed sqlite to save the time, the sender and the content of the last message stored in the WhatsApp database into a Tasker variable. The values are separated by a "|", the time is in ms and the sender is stored as a phone numer. So there are some conversions needed afterwards.
You may have noticed that there is a call to another task at line A9. WhatsApp saves only the number of the contact who send you the message in its database, so we need to convert the number to a real contact name as saved in your phone book. The task "Number->Name WhatsApp" does it. It searches the address book for contacts associated with a WhatsApp account and returns their name. So after line A10 you should know who texted you by name, you can put in if clauses to react different to different names. Here the description of the "Number->Name WhatsApp" task:
Number->Name WhatsApp
  A1: Run Shell [ Command:sqlite3 /data/data/com.android.providers.contacts/databases/contacts2.db "SELECT display_name FROM raw_contacts WHERE sync1 like '%par1';" Timeout (Seconds):5 Use Root:On Store Result In:%sql_result_name Continue Task After Error:On ]
  A2: If [ %sql_result_name !~R sql_result_name ]
    A3: Return [ Value:%sql_result_name Stop:On ]
  A4: Else
    A5: Return [ Value:%par1 Stop:On ]
  A6: End If
Click here to see the NumberNameWhatsApp.tsk.xml you can import directly into Tasker.
<TaskerData sr="" dvi="1" tv="1.3.3u2m">
 <Task sr="task60">
  <cdate>1355153077534</cdate>
  <edate>1357807836858</edate>
  <id>60</id>
  <nme>Number-&gt;Name WhatsApp</nme>
  <pri>10</pri>
  <Action sr="act0" ve="3">
   <code>123</code>
   <se>false</se>
   <Str sr="arg0" ve="3">sqlite3 /data/data/com.android.providers.contacts/databases/contacts2.db "SELECT display_name FROM raw_contacts WHERE sync1 like '%par1';"</Str>
   <Int sr="arg1" val="5"/>
   <Int sr="arg2" val="1"/>
   <Str sr="arg3" ve="3">%sql_result_name</Str>
  </Action>
  <Action sr="act1" ve="3">
   <code>37</code>
   <lhs>%sql_result_name</lhs>
   <op>12</op>
   <rhs>sql_result_name</rhs>
  </Action>
  <Action sr="act2" ve="3">
   <code>126</code>
   <Str sr="arg0" ve="3">%sql_result_name</Str>
   <Int sr="arg1" val="1"/>
  </Action>
  <Action sr="act3" ve="3">
   <code>43</code>
  </Action>
  <Action sr="act4" ve="3">
   <code>126</code>
   <Str sr="arg0" ve="3">%par1</Str>
   <Int sr="arg1" val="1"/>
  </Action>
  <Action sr="act5" ve="3">
   <code>38</code>
  </Action>
 </Task>
</TaskerData>

At line A15 of the task "WhatsApp Notification" task I call a Tasker task called "Play Sound". That's because I disabled notification sounds in WhatsApp to handle them myself (They are time and WhatsApp message content depandant). Here an example of how a simple "Play Sound" task could look like:
Play Sound
  Run Both Together
  A1: If [ %par1 ~R .*[Rr]+[Uu]+[Aa]+[Rr]+.* ]
    A2: Variable Set [ Name:%tmp To:%VOLS Do Maths:Off Append:Off ]
    A3: Wait [ MS:50 Seconds:0 Minutes:0 Hours:0 Days:0 ]
    A4: System Volume [ Level:7 Display:Off Sound:Off ]
    A5: If [ %SILENT ~ off ]
      A6: Play Ringtone [ Type:Notification Sound:Dinosaur Roar Stream:1 ]
    A7: Else If [ %HEADSET ~ 1 ]
      A8: Play Ringtone [ Type:Notification Sound:Dinosaur Roar Stream:1 ]
    A9: End If
    A10: Vibrate [ Time:1000 ]
    A11: Vibrate [ Time:1000 ]
    A12: Vibrate [ Time:1000 ]
    A13: Vibrate [ Time:1000 ]
    A14: Wait [ MS:0 Seconds:5 Minutes:0 Hours:0 Days:0 ]
    A15: System Volume [ Level:%tmp Display:Off Sound:Off ]
  A16: Else If [ %par1 ~R [Mm][Ii][Aa][Uu]+\b ]
    A17: If [ %SILENT ~ off ]
      A18: Play Ringtone [ Type:Notification Sound:Miau Stream:1 ]
    A19: Else If [ %HEADSET ~ 1 ]
      A20: Play Ringtone [ Type:Notification Sound:Miau Stream:1 ]
    A21: End If
  A22: Else
    A23: If [ %par2 !~ 1 ]
      A24: If [ %HEADSET !~ 1 ]
        A25: If [ %SILENT ~ off ]
          A26: Vibrate [ Time:100 ]
          A27: Play Ringtone [ Type:Notification Sound:Good news Stream:5 ]
        A28: End If
      A29: End If
    A30: End If
  A31: End If
Save me as "PlaySound.tsk.xml" and import me in Tasker.
<TaskerData sr="" dvi="1" tv="1.3.3u2m">
 <Task sr="task176">
  <cdate>1353531946878</cdate>
  <edate>1368836670797</edate>
  <id>176</id>
  <nme>Play Sound</nme>
  <pri>10</pri>
  <rty>2</rty>
  <Action sr="act0" ve="3">
   <code>37</code>
   <lhs>%par1</lhs>
   <op>11</op>
   <rhs>.*[Rr]+[Uu]+[Aa]+[Rr]+.*</rhs>
  </Action>
  <Action sr="act1" ve="3">
   <code>547</code>
   <Str sr="arg0" ve="3">%tmp</Str>
   <Str sr="arg1" ve="3">%VOLS</Str>
   <Int sr="arg2" val="0"/>
   <Int sr="arg3" val="0"/>
  </Action>
  <Action sr="act10" ve="3">
   <code>61</code>
   <Int sr="arg0" val="1000"/>
  </Action>
  <Action sr="act11" ve="3">
   <code>61</code>
   <Int sr="arg0" val="1000"/>
  </Action>
  <Action sr="act12" ve="3">
   <code>61</code>
   <Int sr="arg0" val="1000"/>
  </Action>
  <Action sr="act13" ve="3">
   <code>30</code>
   <Int sr="arg0" val="0"/>
   <Int sr="arg1" val="5"/>
   <Int sr="arg2" val="0"/>
   <Int sr="arg3" val="0"/>
   <Int sr="arg4" val="0"/>
  </Action>
  <Action sr="act14" ve="3">
   <code>308</code>
   <Int sr="arg0">
    <var>%tmp</var>
   </Int>
   <Int sr="arg1" val="0"/>
   <Int sr="arg2" val="0"/>
  </Action>
  <Action sr="act15" ve="3">
   <code>43</code>
   <lhs>%par1</lhs>
   <op>11</op>
   <rhs>[Mm][Ii][Aa][Uu]+\b</rhs>
  </Action>
  <Action sr="act16" ve="3">
   <code>37</code>
   <lhs>%SILENT</lhs>
   <op>1</op>
   <rhs>off</rhs>
  </Action>
  <Action sr="act17" ve="3">
   <code>192</code>
   <Int sr="arg0" val="1"/>
   <Str sr="arg1" ve="3">Join Hangout</Str>
   <Int sr="arg2" val="1"/>
  </Action>
  <Action sr="act18" ve="3">
   <code>43</code>
   <lhs>%HEADSET</lhs>
   <op>1</op>
   <rhs>1</rhs>
  </Action>
  <Action sr="act19" ve="3">
   <code>192</code>
   <Int sr="arg0" val="1"/>
   <Str sr="arg1" ve="3">Join Hangout</Str>
   <Int sr="arg2" val="1"/>
  </Action>
  <Action sr="act2" ve="3">
   <code>30</code>
   <Int sr="arg0" val="50"/>
   <Int sr="arg1" val="0"/>
   <Int sr="arg2" val="0"/>
   <Int sr="arg3" val="0"/>
   <Int sr="arg4" val="0"/>
  </Action>
  <Action sr="act20" ve="3">
   <code>38</code>
  </Action>
  <Action sr="act21" ve="3">
   <code>43</code>
  </Action>
  <Action sr="act22" ve="3">
   <code>37</code>
   <lhs>%par2</lhs>
   <op>2</op>
   <rhs>1</rhs>
  </Action>
  <Action sr="act23" ve="3">
   <code>37</code>
   <lhs>%HEADSET</lhs>
   <op>2</op>
   <rhs>1</rhs>
  </Action>
  <Action sr="act24" ve="3">
   <code>37</code>
   <lhs>%SILENT</lhs>
   <op>1</op>
   <rhs>off</rhs>
  </Action>
  <Action sr="act25" ve="3">
   <code>61</code>
   <Int sr="arg0" val="100"/>
  </Action>
  <Action sr="act26" ve="3">
   <code>192</code>
   <Int sr="arg0" val="1"/>
   <Str sr="arg1" ve="3">Good news</Str>
   <Int sr="arg2" val="5"/>
  </Action>
  <Action sr="act27" ve="3">
   <code>38</code>
  </Action>
  <Action sr="act28" ve="3">
   <code>38</code>
  </Action>
  <Action sr="act29" ve="3">
   <code>38</code>
  </Action>
  <Action sr="act3" ve="3">
   <code>308</code>
   <Int sr="arg0" val="7"/>
   <Int sr="arg1" val="0"/>
   <Int sr="arg2" val="0"/>
  </Action>
  <Action sr="act30" ve="3">
   <code>38</code>
  </Action>
  <Action sr="act4" ve="3">
   <code>37</code>
   <lhs>%SILENT</lhs>
   <op>1</op>
   <rhs>off</rhs>
  </Action>
  <Action sr="act5" ve="3">
   <code>192</code>
   <Int sr="arg0" val="1"/>
   <Str sr="arg1" ve="3">Flowers</Str>
   <Int sr="arg2" val="1"/>
  </Action>
  <Action sr="act6" ve="3">
   <code>43</code>
   <lhs>%HEADSET</lhs>
   <op>1</op>
   <rhs>1</rhs>
  </Action>
  <Action sr="act7" ve="3">
   <code>192</code>
   <Int sr="arg0" val="1"/>
   <Str sr="arg1" ve="3">Flowers</Str>
   <Int sr="arg2" val="1"/>
  </Action>
  <Action sr="act8" ve="3">
   <code>38</code>
  </Action>
  <Action sr="act9" ve="3">
   <code>61</code>
   <Int sr="arg0" val="1000"/>
  </Action>
  <Img sr="icn" ve="2">
   <nme>nn_play</nme>
   <pkg>net.dinglisch.android.ipack.ilikebuttonshd</pkg>
  </Img>
 </Task>
</TaskerData>

If headphones are connected or phone is on silent mode no sound is played at all. If the message contains something like "Rrruaaarrrr" a dinosaur roar is played at full volume (even with headphones connected) and the phone vibrates for 4 seconds. If a "Miauuu" is in the message a cats miau is played... I'm sure you can do better :)

You can even make Tasker react on a click on one of the notifications, just add the following profile:
Profile: WhatsApp Notification1 Click
 Event: Notification Click [ Owner Application:Tasker Title:%WHATSAPP_NOTIFY1 ]
Enter: Open WhatsApp
 A1: Load App [ App:WhatsApp Data: Exclude From Recent Apps:Off ]
Duplicate this profile two times so you can click on any of our three custom notifications.
Profile: WhatsApp Notification2 Click
 Event: Notification Click [ Owner Application:Tasker Title:%WHATSAPP_NOTIFY2 ]
Enter: Open WhatsApp
 A1: Load App [ App:WhatsApp Data: Exclude From Recent Apps:Off ]
Profile: WhatsApp Notification3 Click
 Event: Notification Click [ Owner Application:Tasker Title:%WHATSAPP_NOTIFY3 ]
Enter: Open WhatsApp
 A1: Load App [ App:WhatsApp Data: Exclude From Recent Apps:Off ]


I added another profile which deletes all our custom made WhatsApp notifications automatically after opening WhatsApp. Looks like this:
Profile: WhatsApp opened
 Application: WhatsApp

Enter: WhatsApp Notification clear
 A1: Notify Cancel [ Title:%WHATSAPP_NOTIFY1 Warn Not Exist:Off ]
 A2: Notify Cancel [ Title:%WHATSAPP_NOTIFY2 Warn Not Exist:Off ]
 A3: Notify Cancel [ Title:%WHATSAPP_NOTIFY3 Warn Not Exist:Off ]
 A4: Variable Clear [ Name:%WHATSAPP_NOTIFY* Pattern Matching:On ]
 A5: Stop [ With Error:Off Task:WhatsApp Notification ]

Have fun and use this knowledge wisely. Please leave your thoughts in the comments, I'm very excited about your implementations. Hope you read this Ruy Aguilar ;)

53 comments:

  1. Awesome stuff here! Will try them out when I have the time. You should really get this out to more people! Thanks a lot for all your tasker recipes.

    ReplyDelete
  2. i followed over here from life hacker. Excellent stuff! Never saw an article like this integrating with whatsapp. keep up the good work!

    ReplyDelete
  3. It doesnt work the way it should. I was expecting a popup on my screen showing the name and message. If possible, can u please make that 1 for me?

    ReplyDelete
    Replies
    1. What you want is pretty simple: Take a look at the action "Popup". You can find it under "Alerts". You can even create a custom Scene to make to Popup look more iOS style. Just go to "Scenes", clone the original Popup scenery and modify it to your needs. Hope this helps :)

      Delete
  4. There's also the WhatsApp database for contacts in /data/data/com.whatsapp/databases/wa.db which has some more nifty WhatsApp info per contact.

    ReplyDelete
  5. Few more thing, original whatapp notification is not cancelled. How to deal with that?
    And the notification doesnt show up when the contact is not linked with any name. How to make it show the number instead of not showing up at all?

    ReplyDelete
    Replies
    1. For me it is displayed with the number when no contact was found, look at the task corresponding to return the name:
      A2: If [ %sql_result_name !~R sql_result_name ]
      A3: Return [ Value:%sql_result_name Stop:On ]
      A4: Else
      A5: Return [ Value:%par1 Stop:On ]
      A6: End If
      If no name was found (%sql_result_name is set to the value "sql_result_name") then return the passed variable without modifications (return %par1). You can improve the task a little bit by removing the Wait Until line A10 in the WhatsApp Notification Task and set the priority of the task call in A9: Perform Task [ Name:Number->Name WhatsApp ] to the value 9.
      To display the number make a variable search-replace. Replace the string "@s.whatsapp.net" with nothing "".

      Your modified tasks could look like this:
      Task: WhatsApp Notification

      ...
      A9: Perform Task [ Name:Number->Name WhatsApp Stop:Off Priority:9 Parameter 1 (%par1):%sql_result3 Parameter 2 (%par2): Return Value Variable:%sql_result3 ]
      A10: Array Push [ Name:%WHATSAPP_NOTIFY P...
      ...

      and your modified "Number->Name WhatsApp" task:
      Number->Name WhatsApp
      A1: Run Shell [ Command:sqlite3 /data/data/com.android.providers.contacts/databases/contacts2.db "SELECT display_name FROM raw_contacts WHERE sync1 like '%par1';" Timeout (Seconds):5 Use Root:On Store Result In:%sql_result_name Continue Task After Error:On ]
      A2: If [ %sql_result_name !~R sql_result_name ]
      A3: Return [ Value:%sql_result_name Stop:On ]
      A4: Else
      A5: Variable Search Replace [ Variable:%par1 Search:@s.whatsapp.net Ignore Case:Off Multi-Line:Off One Match Only:Off Store Matches In: Replace Matches:On Replace With: ]
      A6: Return [ Value:%par1 Stop:On ]
      A7: End If

      I hope its not too confusing :(


      I haven't found a way to suppress the WhatsApp notifications yet.... My workaround is to cancel my own notifications as soon as they are showed. So that only the original WhatsApp notifications are displayed in the notification menu. So I have two additional lines before A15 in the WhatsApp notification task:
      A13: Wait [ MS:50 Seconds:0 Minutes:0 Hours:0 Days:0 ]
      A14: Notify Cancel [ Title:%WHATSAPP_NOTIFY1 Warn Not Exist:Off ] If [ %DISPLAYON is 1]
      So I can read the notification and react on it with Tasker, even have it read aloud (see http://technologyworkroom.blogspot.de/2013/06/taskermake-tasker-read-aloud-all.html), but it doesn't block the notification menu place.

      Delete
  6. Alright, I have changed to the code that u gave me. Thanks. Hopefully it works. My next problem is group messaging. Because it doesnt give the name of the group and its sender. Please help. Sorry for troubling u so much.

    ReplyDelete
    Replies
    1. you are right with this... Groups never troubled me much, so I just ignored this bug. I will look on how to retrieve their names out of WhatsApp and answer as soon as I find out. Stay tuned...

      Delete
    2. The problem with this is that messages from groups are stored as "admin_number-group_number@g.us" or something like that.. So even if you split the sql_result3 you won't be getting the sender's number. I don't think there's a workaround for this, because most probably group names are stored on whatsapp servers.

      What you CAN do is manually store the group's number in Global variables so you can add something like this:

      A8: Variable Split [ Name:%sql_result3 Splitter: - Delete Base:On]
      A9: Perform Task [ Name:Whatsapp Group Stop:Off Priority:6 Parameter 1 (%par1):%sql_result32 Parameter 2 (%par2): Return Value Variable:%sql_result3 If $sql_result32 is Set]

      Then you create a new task where you have a few comparisons between the param passed and the "numbers@g.us" you already know, as to set the return value to the corresponding name..

      Personally I think that's too much work, so I'd just split the variable and add "Set variable $sql_result3 To 'Message in Group' If $sql_result32 is Set" And change the following appearances of $sql_result3 to 31, which works even if the split didn't happen.

      Delete
  7. That looks very great. I will try it this evening. I assume this could also be adapted for other messenger like Line or Viber. What do you think? Could the SQLite also be used to send messages in Whatsapp?

    ReplyDelete
    Replies
    1. It is possible! And I'm currently investigating it. I want to make a hands-free voice activated interaction with WhatsApp, so its crucial to be able to send messages trough Tasker. I will post an article about this as soon as it's running satisfactorily.

      Delete
    2. Sounds good. Thanks for your reply. :) I just googled a little bit, and there is another way suggested here: http://geekswithblogs.net/shauryaanand/archive/2012/11/09/151216.aspx I thought maybe you are interested in reading it.

      Currently I get thousand ideas what to do with it... :) I could imagine to use this technique along with others to improve my networking and relationships by sending out messages and responding automatically based on

      - different occasions that are defined in Google Calendar entries (like birthdays),

      - different contexts, locations and times (at work, in the city, at home, holiday, weekend, workday, day, night, etc.)

      - the contac's preferred channel (Whatsapp, SMS, Email, and if possible also other phone messengers like Skype, Viber, Line, Yahoo Messenger, etc.).

      Delete
    3. It is more complicated then I thought... WhatsApp has an restriction to only one account per phone number and the sended messages got signed by their servers which only accept messages from one client. So if I would find a way to send messages from my number without the WhatsApp program the WhatsApp app would stop working. Only one client allowed... I'm still looking into this... but I don't have an Android phone any more, because my S3 died from Sudden Death.. I hope it will be repaired soon and I can continue to work on this... :(

      Really thinking about getting one of this chinese android phones.. iOcean X7 Elite or something similar....

      Delete
    4. What about Yousup Library:
      https://github.com/tgalal/yowsup

      It's used in Open WhatsApp, for BlackBerry OS, and in Wazapp, for Nokia N9 Meego/Harmattan.

      Delete
  8. I have a Samsung Galaxy S2 Plus, it is not rooted. can i download your files and import them in my tasker? will it work?

    ReplyDelete
    Replies
    1. it should work on every Android phone ;)

      Delete
    2. okay, but will it work if my phone is not rooted?

      Delete
  9. i basically want my phone to say "Meow" when i get a whatsapp message from a specific person. how do i do that? do i need to Root and install SQLite and Ipack for that? which of the import files do i download from this article?

    ReplyDelete
    Replies
    1. This should be pretty easy... create a new profile to watch for all WhatsApp Noifications.

      Start a Task which plays the Meow sound if the notifications contains the name of the your chosen person and to play a default sound otherwise.

      Everytime you get a message from that person you should get a Meow sound.

      The task the profile should start can like this:
      A1: If [ %NTITLE ~R New message from YOURNAMEHERE ]
      A2: Play Ringtone [ Type:Notification Sound:Meow Stream:1 ]
      A3: Else
      A4: Play Ringtone [ Type:Notification Sound:Default Stream:1 ]

      Don't forget to disable all notification sounds in WhatsApp itself. Could I help you with this :) ?



      Delete
    2. I understood creating the task part, but how to create a profile to watch for all whatsapp notifications!?

      Delete
    3. Add a new profile, select "Event", then "Notification", Owner Application: "WhatsApp". Leave title empty.

      Delete
    4. Yes works! thanks! :D
      Please post more articles soon! and also if you could put up some tutorials on programming that would be great!! :D

      Delete
  10. Thank you so much for this awesome Piece! Im quite close to be able to use it in my profiles - but there's a problem with resolving the phonenumber to the plain name. It doesnt store the output. For debugging, i let tasker show the errors. In return, i get:
    Error: near "491234567890": syntax error
    I tried it with playing around with sync1 to sync4. the variable that needs to get is resolved is all fine, its in the format "491234567890@s.whatsapp.net"

    :-/ Maybe you can provide me a hint, what is going wrong there? That'd be awesome! Thanks in advance!

    ReplyDelete
    Replies
    1. Uhm - i was blind! Note to myself: '" may look like ", but aint the same at all :-) While altering the code to fit my needings i was a bit too fast.
      Its workin like a charm. Thank you for the great piece of Taskercode!

      Delete
  11. Hello..I am trying the commands listed above..one thing I noticed is that the msgstore.db is actually encrypted and in full it's actually msgstore.db.crypt. I am rooted but also noticed no one else here got this problem. What am I doing wrong? How we I get access to the db file?

    ReplyDelete
    Replies
    1. Hi Beeps, you need to make sure that your phone is rooted, that Tasker has root access, and that the script itself has root access as well.

      Delete
  12. This comment has been removed by the author.

    ReplyDelete
  13. Hi Benny, thank you for your awesome script. It works perfectly and I used it as a basis to get Hangout notifications working as well.

    For the people who wish to resolve group hangout names, in the WhatsApp statusbar script, a simple change will give the user the data they need. Change the command to the following and ensure that you have single quotes when checking remote_resource:

    sqlite3 /data/data/com.whatsapp/databases/msgstore.db "SELECT timestamp,data, case WHEN remote_resource is '' THEN key_remote_jid ELSE remote_resource END FROM messages WHERE key_from_me='0' ORDER BY timestamp DESC LIMIT 1;"

    ReplyDelete
    Replies
    1. Wow ! Thank you sec12tst8r84 !

      Delete
    2. Hi sorry I'm a bit confused, This is for whatsapp and not just for Hangouts right? So I just replace
      A1: Run Shell [ Command:sqlite3 /data/data/com.whatsapp/databases/msgstore.db "SELECT timestamp,data,key_remote_jid FROM messages WHERE key_from_me='0' ORDER BY timestamp DESC LIMIT 1;"
      with the above lines?
      Thanks a lot for all your great work!

      Delete
    3. have not tried it yet, but technically - yes...

      Delete
  14. Hello. All set here, but gives the error message "task Number->Name WhatsApp task does not exist". Didn't change anything, just copy & import the files into Tasker. Any ideas?

    ReplyDelete
  15. Hello again. Found a way to it. Changed the call line to "A9: Perform Task [ Name:NameWhatsApp Stop:" and changed the Task name accordingly to "NameWhatsApp" with no extra chars and no spaces and it works fine now. My device is a Galaxy S2 rooted.
    Thanks for this great code.
    JF - Venezuela

    ReplyDelete
  16. Hi there, do I have to root for playing a specified notification tone in an incoming group message?

    ReplyDelete
    Replies
    1. Yes, because you need root to access the WhatsApp message database :(

      Delete
  17. I see an app on Play Store that can define time to send Whatsapp Message without Tasker: https://play.google.com/store/apps/details?id=com.auto.whatsapp.message.lite

    ReplyDelete
    Replies
    1. It is possible to send messages from another number then you own. But thank ou very much for the link!!!

      Delete
  18. hey! It looks like youve done some amazing work! The only problem is that I cant figure out how to download the .xml can you please help me or send them to my email at kazooloo@gmail.com

    ReplyDelete
  19. This comment has been removed by the author.

    ReplyDelete
  20. I have modified this tasker profile to work better with groups. It recognizes if the msg is from a group or person by analysing the number of elements of sql_result. If it's from a group it's put in the format NAME @ GROUP : MESSAGE. If it's from a person it's just NAME : MESSAGE.

    With 0 experience with any databases, sql and not too much exerience with tasker either it took me quite some time, but got it done. If there is anyone that wants it post here and i'll upload the project.

    ReplyDelete
  21. Great stuff... I also programmed the whatsapp... with a little popup variation :)... thks for the inputs

    ReplyDelete
  22. This comment has been removed by the author.

    ReplyDelete
  23. About done with my WhatsApp project which was started by this post. Took it a little further, for more information see:
    http://www.reddit.com/r/tasker/comments/1q7okn/readingsending_whatsapp_messages_from_the/

    ReplyDelete
    Replies
    1. WOW !! Very nice! Thats' something I allready thought about, but had bever the time to do! Great job Nedle. Downloaded th project, very excited to look into it and analyze your work :)

      Delete
  24. Awesome... I used this to notify a specific WhatsApp message on my Pebble. Thank you so much!

    ReplyDelete
  25. I use Google voice via Talkatone instead, please show me how do to adapt your guide for use with talkatone.

    ReplyDelete
  26. Hi, awesome stuff but it doesn't work on my Galaxy S4. In the task Whatsapp Notifications line A9 is marked with a red exclamation mark. I don't know the problem. Please: I need help!

    ReplyDelete
    Replies
    1. You may have noticed that there is a call to another task at line A9. WhatsApp saves only the number of the contact who send you the message in its database, so we need to convert the number to a real contact name as saved in your phone book. The task "Number->Name WhatsApp" does it. It searches the address book for contacts associated with a WhatsApp account and returns their name.

      I posted the task at the top

      Delete
  27. how to receive whatsapp message senders name using tasker

    ReplyDelete