Skip to content

Commit 3b5adfa

Browse files
Release 1.2.1
1 parent 674a6c6 commit 3b5adfa

File tree

9 files changed

+274
-108
lines changed

9 files changed

+274
-108
lines changed

.DS_Store

6 KB
Binary file not shown.

whatsapp_addon/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## 1.2.1
2+
3+
- Fixed bug that did not allow the reception of push notifications on other devices.
4+
- Added event presence update.
5+
- Added two more services like subscribe presence and send presence update.
6+
17
## 1.2.0
28

39
- **Changed radically command and events. Please refer to doc and developer tools for change your automations.**

whatsapp_addon/DOCS.md

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,18 +145,30 @@ data:
145145
id: id-like-buttons-message
146146
```
147147
148+
### **How to subscribe to presence update**
149+
150+
```yaml
151+
service: whatsapp.presence_subscribe
152+
data:
153+
clientId: default
154+
userId: 391234567890@s.whatsapp.net
155+
```
156+
148157
---
149158
150159
## Events
151160
152-
| Event type | Description |
153-
| -------------------- | ----------------------------- |
154-
| new_whatsapp_message | The message that was received |
161+
| Event type | Description |
162+
| ------------------------ | ------------------------------------- |
163+
| new_whatsapp_message | The message that was received |
164+
| whatsapp_presence_update | Presence of contact in a chat updated |
155165
156166
---
157167
158168
## **Sample automations**
159169
170+
## Ping Pong
171+
160172
```yaml
161173
- alias: Ping Pong
162174
description: ""
@@ -176,6 +188,8 @@ data:
176188
mode: single
177189
```
178190
191+
## Arrive at home
192+
179193
```yaml
180194
- alias: Arrive at home
181195
description: ""
@@ -196,6 +210,8 @@ data:
196210
mode: single
197211
```
198212
213+
## Driving mode
214+
199215
```yaml
200216
- alias: Driving mode
201217
description: ""
@@ -235,3 +251,24 @@ data:
235251
key: "{{ trigger.event.data.key }}"
236252
mode: single
237253
```
254+
255+
## Presence notify (SUBSCRIBE FIRST!)
256+
257+
```yaml
258+
- alias: Nuova automazione
259+
description: ""
260+
trigger:
261+
- platform: event
262+
event_type: whatsapp_presence_update
263+
event_data: {}
264+
condition:
265+
- condition: template
266+
value_template:
267+
"{{ trigger.event.data.presences['391234567890@s.whatsapp.net'].lastKnownPresence
268+
== 'available' }}"
269+
action:
270+
- service: persistent_notification.create
271+
data:
272+
message: Contact is online!
273+
mode: single
274+
```

whatsapp_addon/WhatsappClient.js

Lines changed: 76 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,91 @@
1-
const EventEmitter = require('events');
1+
const EventEmitter = require("events");
22

3-
const makeWASocket = require('@adiwajshing/baileys').default
3+
const makeWASocket = require("@adiwajshing/baileys").default;
44
const {
5-
DisconnectReason,
6-
useSingleFileAuthState,
7-
Browsers
8-
} = require('@adiwajshing/baileys')
5+
DisconnectReason,
6+
useSingleFileAuthState,
7+
Browsers,
8+
} = require("@adiwajshing/baileys");
99

1010
class WhatsappClient extends EventEmitter {
11-
#sock;
12-
13-
constructor(sessionPath) {
14-
super();
15-
var self = this;
16-
async function connectToWhatsApp() {
17-
const { state, saveState } = useSingleFileAuthState(sessionPath)
18-
19-
self.#sock = makeWASocket({
20-
auth: state,
21-
syncFullHistory: false,
22-
browser: Browsers.macOS('Desktop'),
23-
logger: require("pino")({ level: 'silent' })
24-
})
25-
26-
self.#sock.ev.on('creds.update', saveState)
27-
28-
self.#sock.ev.on('connection.update', (update) => {
29-
const { connection, lastDisconnect, qr } = update
30-
31-
if (qr) {
32-
self.emit('qr', qr)
33-
}
34-
35-
if (connection === 'close') {
36-
const shouldReconnect = lastDisconnect.error.output?.statusCode !== DisconnectReason.loggedOut
37-
if (shouldReconnect) {
38-
connectToWhatsApp()
39-
} else {
40-
self.emit('disconnected')
41-
}
42-
} else if (connection === 'open') {
43-
self.emit('ready')
44-
}
45-
})
46-
47-
self.#sock.ev.on('messages.upsert', (Message) => {
48-
let msg = Message.messages[0]
49-
if (!msg.key.fromMe)
50-
self.emit('message', msg)
51-
})
11+
#sock;
12+
13+
constructor(sessionPath) {
14+
super();
15+
var self = this;
16+
async function connectToWhatsApp() {
17+
const { state, saveState } = useSingleFileAuthState(sessionPath);
18+
19+
self.#sock = makeWASocket({
20+
auth: state,
21+
syncFullHistory: false,
22+
browser: Browsers.macOS("Desktop"),
23+
logger: require("pino")({ level: "silent" }),
24+
});
25+
26+
self.#sock.ev.on("creds.update", saveState);
27+
28+
self.#sock.ev.on("connection.update", (update) => {
29+
const { connection, lastDisconnect, qr } = update;
30+
31+
if (qr) {
32+
self.emit("qr", qr);
5233
}
5334

54-
connectToWhatsApp()
55-
}
35+
if (connection === "close") {
36+
const shouldReconnect =
37+
lastDisconnect.error.output?.statusCode !==
38+
DisconnectReason.loggedOut;
39+
if (shouldReconnect) {
40+
connectToWhatsApp();
41+
} else {
42+
self.emit("disconnected");
43+
}
44+
} else if (connection === "open") {
45+
self.emit("ready");
46+
}
47+
});
5648

57-
async sendMessage(chatId, msg, options) {
58-
return await this.#sock.sendMessage(chatId, msg, options);
59-
}
49+
self.#sock.ev.on("messages.upsert", (Message) => {
50+
let msg = Message.messages[0];
51+
if (!msg.key.fromMe) self.emit("message", msg);
52+
});
6053

61-
async presenceSubscribe(chatId) {
62-
return await this.#sock.presenceSubscribe(chatId);
54+
self.#sock.ev.on("presence.update", (presence) => {
55+
self.emit("presence_update", presence);
56+
});
6357
}
6458

65-
async updateProfileStatus(status) {
66-
return await this.#sock.updateProfileStatus(status)
67-
}
59+
connectToWhatsApp();
60+
}
6861

69-
async updateProfileName(name) {
70-
return await this.#sock.updateProfileName(name)
71-
}
62+
async sendMessage(chatId, msg, options) {
63+
return await this.#sock.sendMessage(chatId, msg, options);
64+
}
7265

73-
async isOnWhatsapp(id) {
74-
return await this.#sock.onWhatsApp(id)
75-
}
66+
async presenceSubscribe(chatId) {
67+
return await this.#sock.presenceSubscribe(chatId);
68+
}
7669

77-
async updateBlockStatus(id, status) {
78-
return await this.#sock.updateBlockStatus(id, status)
79-
}
70+
async updateProfileStatus(status) {
71+
return await this.#sock.updateProfileStatus(status);
72+
}
73+
74+
async updateProfileName(name) {
75+
return await this.#sock.updateProfileName(name);
76+
}
77+
78+
async isOnWhatsapp(id) {
79+
return await this.#sock.onWhatsApp(id);
80+
}
81+
82+
async updateBlockStatus(id, status) {
83+
return await this.#sock.updateBlockStatus(id, status);
84+
}
85+
86+
async sendPresenceUpdate(type, id) {
87+
return await this.#sock.sendPresenceUpdate(type, id);
88+
}
8089
}
8190

82-
module.exports = WhatsappClient
91+
module.exports = WhatsappClient;

whatsapp_addon/config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: Whatsapp
2-
version: "1.2.0"
2+
version: "1.2.1"
33
slug: whatsapp_addon
44
description: Whatsapp addon for send message from Home Assistant
55
url: "https://github.com/giuseppecastaldo/ha-addons/tree/main/whatsapp_addon"

whatsapp_addon/custom_component/__init__.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,17 @@ async def send_message(call: ServiceCall) -> None:
2121
async def set_status(call: ServiceCall) -> None:
2222
await hass.async_add_executor_job(whatsapp.set_status, call.data)
2323

24+
@callback
25+
async def presence_subscribe(call: ServiceCall) -> None:
26+
await hass.async_add_executor_job(whatsapp.presence_subscribe, call.data)
27+
28+
@callback
29+
async def send_presence_update(call: ServiceCall) -> None:
30+
await hass.async_add_executor_job(whatsapp.send_presence_update, call.data)
31+
2432
hass.services.async_register(DOMAIN, 'send_message', send_message)
2533
hass.services.async_register(DOMAIN, 'set_status', set_status)
34+
hass.services.async_register(DOMAIN, 'presence_subscribe', presence_subscribe)
35+
hass.services.async_register(DOMAIN, 'send_presence_update', send_presence_update)
2636

2737
return True

whatsapp_addon/custom_component/services.yaml

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ send_message:
1111
name: Target User ID
1212
description: Target User ID
1313
required: true
14-
example: 391234567890@c.us
14+
example: 391234567890@s.whatsapp.net
1515
body:
1616
name: Message's body
1717
description: Message's body
@@ -32,3 +32,46 @@ set_status:
3232
description: New status message
3333
required: true
3434
example: Available
35+
36+
presence_subscribe:
37+
name: Presence subscribe
38+
description: Subscribe to user presence update like online, offline, typing, etc...
39+
fields:
40+
clientId:
41+
name: Client ID
42+
description: Which instance of whatsapp should be used
43+
required: true
44+
example: default
45+
userId:
46+
name: Target User ID
47+
description: Target User ID
48+
required: true
49+
example: 391234567890@s.whatsapp.net
50+
51+
send_presence_update:
52+
name: Send presence update
53+
description: Send presence update like online, offline, typing, etc...
54+
fields:
55+
clientId:
56+
name: Client ID
57+
description: Which instance of whatsapp should be used
58+
required: true
59+
example: default
60+
type:
61+
name: Presence type
62+
description: Presence type
63+
required: true
64+
example: composing
65+
selector:
66+
select:
67+
options:
68+
- "unavailable"
69+
- "available"
70+
- "composing"
71+
- "recording"
72+
- "paused"
73+
to:
74+
name: Target User ID
75+
description: Target User ID
76+
required: false
77+
example: 391234567890@s.whatsapp.net

whatsapp_addon/custom_component/whatsapp.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,9 @@ def send_message(self, data):
99

1010
def set_status(self, data):
1111
return requests.post(url_normalize(f'{HOST}/setStatus'), json=data).content == 'OK'
12+
13+
def presence_subscribe(self, data):
14+
return requests.post(url_normalize(f'{HOST}/presenceSubscribe'), json=data).content == 'OK'
15+
16+
def send_presence_update(self, data):
17+
return requests.post(url_normalize(f'{HOST}/sendPresenceUpdate'), json=data).content == 'OK'

0 commit comments

Comments
 (0)