WPP-Whatsapp 0.2.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- WPP_Whatsapp-0.2.1/LICENSE +21 -0
- WPP_Whatsapp-0.2.1/PKG-INFO +132 -0
- WPP_Whatsapp-0.2.1/README.md +104 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp/README.md +10 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp/__init__.py +5 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp/api/Whatsapp.py +141 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp/api/__init__.py +0 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp/api/const.py +70 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp/api/helpers/__init__.py +0 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp/api/helpers/decorators.py +21 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp/api/helpers/download_file.py +37 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp/api/helpers/function.py +11 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp/api/helpers/jsFunction.py +115 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp/api/helpers/scrap-img.py +1 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp/api/helpers/wa_version.py +47 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp/api/layers/BusinessLayer.py +9 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp/api/layers/CatalogLayer.py +32 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp/api/layers/ControlsLayer.py +155 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp/api/layers/GroupLayer.py +101 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp/api/layers/HostLayer.py +762 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp/api/layers/LabelsLayer.py +82 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp/api/layers/ListenerLayer.py +360 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp/api/layers/ProfileLayer.py +93 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp/api/layers/RetrieverLayer.py +278 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp/api/layers/SenderLayer.py +485 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp/api/layers/StatusLayer.py +181 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp/api/layers/UILayer.py +59 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp/api/layers/__init__.py +0 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp/api/model/__init__.py +0 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp/api/model/status_find.py +43 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp/controllers/__init__.py +0 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp/controllers/auth.py +1 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp/controllers/browser.py +53 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp/controllers/initializer.py +254 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp/js_lib/wapi.js +1 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp/utils/__init__.py +0 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp/utils/ffmpeg.py +75 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp.egg-info/PKG-INFO +132 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp.egg-info/SOURCES.txt +44 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp.egg-info/dependency_links.txt +1 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp.egg-info/requires.txt +12 -0
- WPP_Whatsapp-0.2.1/WPP_Whatsapp.egg-info/top_level.txt +1 -0
- WPP_Whatsapp-0.2.1/setup.cfg +4 -0
- WPP_Whatsapp-0.2.1/setup.py +45 -0
- WPP_Whatsapp-0.2.1/test/test_hiden.py +99 -0
- WPP_Whatsapp-0.2.1/test/test_setinterval.py +27 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Ammar
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: WPP_Whatsapp
|
|
3
|
+
Version: 0.2.1
|
|
4
|
+
Summary: WPP_Whatsapp aim of exporting functions from WhatsApp Web to the python, which can be used to support the creation of any interaction, such as customer service, media sending, intelligence recognition based on phrases artificial and many other things, use your imagination
|
|
5
|
+
Home-page: https://github.com/3mora2/WPP_Whatsapp
|
|
6
|
+
Author: Ammar Alkotb
|
|
7
|
+
Author-email: ammar.alkotb@gmail.com
|
|
8
|
+
License: MIT License
|
|
9
|
+
Project-URL: Bug Report, https://github.com/3mora2/WPP_Whatsapp/issues/new
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Programming Language :: Python
|
|
13
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
License-File: LICENSE
|
|
16
|
+
Requires-Dist: event-emitter-js
|
|
17
|
+
Requires-Dist: greenlet
|
|
18
|
+
Requires-Dist: playwright
|
|
19
|
+
Requires-Dist: Pillow
|
|
20
|
+
Requires-Dist: psutil
|
|
21
|
+
Requires-Dist: pyee
|
|
22
|
+
Requires-Dist: segno
|
|
23
|
+
Requires-Dist: typing_extensions
|
|
24
|
+
Requires-Dist: playwright-stealth
|
|
25
|
+
Requires-Dist: node-semver
|
|
26
|
+
Requires-Dist: aiohttp
|
|
27
|
+
Requires-Dist: PlaywrightSafeThread>=0.5.2.1
|
|
28
|
+
|
|
29
|
+
# WPP_Whatsapp
|
|
30
|
+
<p align="center">
|
|
31
|
+
<a href="https://pypi.org/project/WPP-Whatsapp"><img alt="PyPI Version" src="https://img.shields.io/pypi/v/WPP_Whatsapp.svg?maxAge=86400" /></a>
|
|
32
|
+
<a href="https://pypi.org/project/WPP-Whatsapp"><img alt="View" src="https://static.pepy.tech/personalized-badge/WPP_Whatsapp?period=total&units=international_system&left_text=Downloads"/></a>
|
|
33
|
+
</p>
|
|
34
|
+
|
|
35
|
+
WPP_Whatsapp aim of exporting functions from WhatsApp Web to the python, which can be used to support the creation of
|
|
36
|
+
any interaction, such as customer service, media sending, intelligence recognition based on phrases artificial and many
|
|
37
|
+
other things, use your imagination
|
|
38
|
+
WPP_Whatsapp > [WPPConnect](https://github.com/wppconnect-team/wppconnect) Converted to python, so Documentation is same
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
## Online channels
|
|
42
|
+
|
|
43
|
+
[](https://t.me/WPP_Whatsapp)
|
|
44
|
+
|
|
45
|
+
## Functions
|
|
46
|
+
|
|
47
|
+
| | |
|
|
48
|
+
|------------------------------------------------------------|---|
|
|
49
|
+
| Automatic QR Refresh | ✔ |
|
|
50
|
+
| Send **text, image, video, audio and docs** | ✔ |
|
|
51
|
+
| Get **contacts, chats, groups, group members, Block List** | ✔ |
|
|
52
|
+
| Send contacts | ✔ |
|
|
53
|
+
| Send stickers | ✔ |
|
|
54
|
+
| Send stickers GIF | ✔ |
|
|
55
|
+
| Multiple Sessions | ✔ |
|
|
56
|
+
| Forward Messages | ✔ |
|
|
57
|
+
| Receive message | ✔ |
|
|
58
|
+
| insert user section | ✔ |
|
|
59
|
+
| Send _location_ | ✔ |
|
|
60
|
+
| **and much more** | ✔ |
|
|
61
|
+
|
|
62
|
+
See more at <a href="https://wppconnect.io/wppconnect/classes/Whatsapp.html">WhatsApp methods</a>
|
|
63
|
+
## Getting Started
|
|
64
|
+
|
|
65
|
+
### Installation
|
|
66
|
+
|
|
67
|
+
installed with [pip](https://pip.pypa.io):
|
|
68
|
+
```commandline
|
|
69
|
+
pip install WPP_Whatsapp -U
|
|
70
|
+
```
|
|
71
|
+
Alternatively, you can grab the latest source code from [GitHub](https://github.com/3mora2/WPP_Whatsapp):
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
pip install git+https://github.com/3mora2/WPP_Whatsapp
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
### Send Text
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
from WPP_Whatsapp import Create
|
|
83
|
+
|
|
84
|
+
# start client with your session name
|
|
85
|
+
your_session_name = "test"
|
|
86
|
+
creator = Create(session=your_session_name)
|
|
87
|
+
client = creator.start()
|
|
88
|
+
# Now scan Whatsapp Qrcode in browser
|
|
89
|
+
|
|
90
|
+
# check state of login
|
|
91
|
+
if creator.state != 'CONNECTED':
|
|
92
|
+
raise Exception(creator.state)
|
|
93
|
+
|
|
94
|
+
phone_number = "201016708170" # or "+201016708170"
|
|
95
|
+
message = "hello from wpp"
|
|
96
|
+
|
|
97
|
+
# Simple message
|
|
98
|
+
result = client.sendText(phone_number, message)
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Receive Messages(Auto Replay)
|
|
102
|
+
```python
|
|
103
|
+
from WPP_Whatsapp import Create
|
|
104
|
+
|
|
105
|
+
# start client with your session name
|
|
106
|
+
your_session_name = "test"
|
|
107
|
+
creator = Create(session=your_session_name)
|
|
108
|
+
client = creator.start()
|
|
109
|
+
# Now scan Whatsapp Qrcode in browser
|
|
110
|
+
|
|
111
|
+
# check state of login
|
|
112
|
+
if creator.state != 'CONNECTED':
|
|
113
|
+
raise Exception(creator.state)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def new_message(message):
|
|
117
|
+
global client
|
|
118
|
+
# Add your Code here
|
|
119
|
+
if message and not message.get("isGroupMsg"):
|
|
120
|
+
chat_id = message.get("from")
|
|
121
|
+
message_id = message.get("id")
|
|
122
|
+
if "السلام عليكم" in message.get("body"):
|
|
123
|
+
client.reply(chat_id, "وعليكم السلام", message_id)
|
|
124
|
+
else:
|
|
125
|
+
client.reply(chat_id, "Welcome", message_id)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
# Add Listen To New Message
|
|
129
|
+
creator.client.onMessage(new_message)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### <a href="https://github.com/3mora2/WPP_Whatsapp/tree/main/examples">For More Examples</a>
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# WPP_Whatsapp
|
|
2
|
+
<p align="center">
|
|
3
|
+
<a href="https://pypi.org/project/WPP-Whatsapp"><img alt="PyPI Version" src="https://img.shields.io/pypi/v/WPP_Whatsapp.svg?maxAge=86400" /></a>
|
|
4
|
+
<a href="https://pypi.org/project/WPP-Whatsapp"><img alt="View" src="https://static.pepy.tech/personalized-badge/WPP_Whatsapp?period=total&units=international_system&left_text=Downloads"/></a>
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
WPP_Whatsapp aim of exporting functions from WhatsApp Web to the python, which can be used to support the creation of
|
|
8
|
+
any interaction, such as customer service, media sending, intelligence recognition based on phrases artificial and many
|
|
9
|
+
other things, use your imagination
|
|
10
|
+
WPP_Whatsapp > [WPPConnect](https://github.com/wppconnect-team/wppconnect) Converted to python, so Documentation is same
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
## Online channels
|
|
14
|
+
|
|
15
|
+
[](https://t.me/WPP_Whatsapp)
|
|
16
|
+
|
|
17
|
+
## Functions
|
|
18
|
+
|
|
19
|
+
| | |
|
|
20
|
+
|------------------------------------------------------------|---|
|
|
21
|
+
| Automatic QR Refresh | ✔ |
|
|
22
|
+
| Send **text, image, video, audio and docs** | ✔ |
|
|
23
|
+
| Get **contacts, chats, groups, group members, Block List** | ✔ |
|
|
24
|
+
| Send contacts | ✔ |
|
|
25
|
+
| Send stickers | ✔ |
|
|
26
|
+
| Send stickers GIF | ✔ |
|
|
27
|
+
| Multiple Sessions | ✔ |
|
|
28
|
+
| Forward Messages | ✔ |
|
|
29
|
+
| Receive message | ✔ |
|
|
30
|
+
| insert user section | ✔ |
|
|
31
|
+
| Send _location_ | ✔ |
|
|
32
|
+
| **and much more** | ✔ |
|
|
33
|
+
|
|
34
|
+
See more at <a href="https://wppconnect.io/wppconnect/classes/Whatsapp.html">WhatsApp methods</a>
|
|
35
|
+
## Getting Started
|
|
36
|
+
|
|
37
|
+
### Installation
|
|
38
|
+
|
|
39
|
+
installed with [pip](https://pip.pypa.io):
|
|
40
|
+
```commandline
|
|
41
|
+
pip install WPP_Whatsapp -U
|
|
42
|
+
```
|
|
43
|
+
Alternatively, you can grab the latest source code from [GitHub](https://github.com/3mora2/WPP_Whatsapp):
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
pip install git+https://github.com/3mora2/WPP_Whatsapp
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
### Send Text
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
from WPP_Whatsapp import Create
|
|
55
|
+
|
|
56
|
+
# start client with your session name
|
|
57
|
+
your_session_name = "test"
|
|
58
|
+
creator = Create(session=your_session_name)
|
|
59
|
+
client = creator.start()
|
|
60
|
+
# Now scan Whatsapp Qrcode in browser
|
|
61
|
+
|
|
62
|
+
# check state of login
|
|
63
|
+
if creator.state != 'CONNECTED':
|
|
64
|
+
raise Exception(creator.state)
|
|
65
|
+
|
|
66
|
+
phone_number = "201016708170" # or "+201016708170"
|
|
67
|
+
message = "hello from wpp"
|
|
68
|
+
|
|
69
|
+
# Simple message
|
|
70
|
+
result = client.sendText(phone_number, message)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Receive Messages(Auto Replay)
|
|
74
|
+
```python
|
|
75
|
+
from WPP_Whatsapp import Create
|
|
76
|
+
|
|
77
|
+
# start client with your session name
|
|
78
|
+
your_session_name = "test"
|
|
79
|
+
creator = Create(session=your_session_name)
|
|
80
|
+
client = creator.start()
|
|
81
|
+
# Now scan Whatsapp Qrcode in browser
|
|
82
|
+
|
|
83
|
+
# check state of login
|
|
84
|
+
if creator.state != 'CONNECTED':
|
|
85
|
+
raise Exception(creator.state)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def new_message(message):
|
|
89
|
+
global client
|
|
90
|
+
# Add your Code here
|
|
91
|
+
if message and not message.get("isGroupMsg"):
|
|
92
|
+
chat_id = message.get("from")
|
|
93
|
+
message_id = message.get("id")
|
|
94
|
+
if "السلام عليكم" in message.get("body"):
|
|
95
|
+
client.reply(chat_id, "وعليكم السلام", message_id)
|
|
96
|
+
else:
|
|
97
|
+
client.reply(chat_id, "Welcome", message_id)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
# Add Listen To New Message
|
|
101
|
+
creator.client.onMessage(new_message)
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### <a href="https://github.com/3mora2/WPP_Whatsapp/tree/main/examples">For More Examples</a>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
I am try use playwright as threadsafe
|
|
2
|
+
and try all function sync but in event function
|
|
3
|
+
like `page.on("event", func)` must use async function,
|
|
4
|
+
may be playwright exec only one sync function in same time,
|
|
5
|
+
so if you need more use them as async
|
|
6
|
+
|
|
7
|
+
now all function has two type
|
|
8
|
+
|
|
9
|
+
- one relate to event (play in background) like `page.on` need use async and await
|
|
10
|
+
- other not relate to event, use without async and await
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
from WPP_Whatsapp.api.helpers.jsFunction import setInterval
|
|
3
|
+
from WPP_Whatsapp.api.layers.HostLayer import HostLayer
|
|
4
|
+
from WPP_Whatsapp.api.const import defaultOptions, Logger
|
|
5
|
+
from WPP_Whatsapp.api.layers.BusinessLayer import BusinessLayer
|
|
6
|
+
from WPP_Whatsapp.api.layers.ListenerLayer import ListenerLayer
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Whatsapp(BusinessLayer):
|
|
10
|
+
interval: asyncio.Event
|
|
11
|
+
|
|
12
|
+
def __init__(self, session, threadsafe_browser, version=None, **kwargs):
|
|
13
|
+
self.connected = None
|
|
14
|
+
self.options = {}
|
|
15
|
+
self.options.update(defaultOptions)
|
|
16
|
+
for key, value in kwargs.items():
|
|
17
|
+
if key in self.options:
|
|
18
|
+
self.options[key] = value
|
|
19
|
+
|
|
20
|
+
# self.autoCloseInterval = None
|
|
21
|
+
self.version = version
|
|
22
|
+
self.autoCloseCalled = False
|
|
23
|
+
self.isInitialized = False
|
|
24
|
+
self.isInjected = False
|
|
25
|
+
self.isStarted = False
|
|
26
|
+
self.isLogged = False
|
|
27
|
+
self.isInChat = False
|
|
28
|
+
# self.checkStartInterval = None
|
|
29
|
+
self.urlCode = ''
|
|
30
|
+
self.status = ''
|
|
31
|
+
self.attempt = 0
|
|
32
|
+
self.lastPercent = ""
|
|
33
|
+
self.lastPercentMessage = ""
|
|
34
|
+
self.session = session
|
|
35
|
+
self.page = threadsafe_browser.page
|
|
36
|
+
self.browser = threadsafe_browser.browser
|
|
37
|
+
self.ThreadsafeBrowser = threadsafe_browser
|
|
38
|
+
self.loop = threadsafe_browser.loop
|
|
39
|
+
self.logger = self.options.get("logger") or Logger
|
|
40
|
+
self.logger.info(f'{self.session}: Initializing...')
|
|
41
|
+
self.logQR = kwargs.get("logQR") or False
|
|
42
|
+
self.autoClose = kwargs.get("autoClose") or self.options.get("autoClose") or 60
|
|
43
|
+
HostLayer.__init__(self)
|
|
44
|
+
ListenerLayer.__init__(self)
|
|
45
|
+
self.handel()
|
|
46
|
+
|
|
47
|
+
def handel(self):
|
|
48
|
+
# self.interval = None
|
|
49
|
+
if self.page:
|
|
50
|
+
self.interval = setInterval(self.loop, self.__intervalHandel, 60)
|
|
51
|
+
self.page.on('close', self.clear_all_interval)
|
|
52
|
+
|
|
53
|
+
async def clear_all_interval(self, *args, **kwargs):
|
|
54
|
+
Logger.info("clear all intervals")
|
|
55
|
+
if hasattr(self, "interval"):
|
|
56
|
+
self.clearInterval(self.interval)
|
|
57
|
+
if hasattr(self, "autoCloseInterval"):
|
|
58
|
+
self.clearInterval(self.autoCloseInterval)
|
|
59
|
+
if hasattr(self, "checkStartInterval"):
|
|
60
|
+
self.clearInterval(self.checkStartInterval)
|
|
61
|
+
|
|
62
|
+
# @staticmethod
|
|
63
|
+
# def __setInterval(func, interval, *args, **kwargs):
|
|
64
|
+
# stopped = threading.Event()
|
|
65
|
+
#
|
|
66
|
+
# def _loop_():
|
|
67
|
+
# while not stopped.is_set():
|
|
68
|
+
# func()
|
|
69
|
+
# time.sleep(interval)
|
|
70
|
+
#
|
|
71
|
+
# th = threading.Thread(target=_loop_)
|
|
72
|
+
# th.start()
|
|
73
|
+
# return stopped
|
|
74
|
+
|
|
75
|
+
async def __intervalHandel(self):
|
|
76
|
+
try:
|
|
77
|
+
# Add window, when WPP not create yet
|
|
78
|
+
newConnected = await self.ThreadsafeBrowser.page_evaluate("() => typeof window.WPP !== 'undefined' && window.WPP.conn.isRegistered()")
|
|
79
|
+
except:
|
|
80
|
+
newConnected = None
|
|
81
|
+
|
|
82
|
+
if newConnected is None or newConnected == self.connected:
|
|
83
|
+
return
|
|
84
|
+
self.connected = newConnected
|
|
85
|
+
|
|
86
|
+
if not newConnected:
|
|
87
|
+
self.logger.info(f'{self.session}: Session Unpaired')
|
|
88
|
+
if self.statusFind:
|
|
89
|
+
self.statusFind('disconnectedMobile', self.session)
|
|
90
|
+
|
|
91
|
+
async def afterPageScriptInjected(self):
|
|
92
|
+
await self._afterPageScriptInjectedHost()
|
|
93
|
+
await self._afterPageScriptInjectedListener()
|
|
94
|
+
is_authenticated = await self.ThreadsafeBrowser.page_evaluate("() => typeof window.WPP !== 'undefined' && WPP.conn.isRegistered()")
|
|
95
|
+
self.connected = is_authenticated
|
|
96
|
+
|
|
97
|
+
def useHere(self, timeout=120):
|
|
98
|
+
return self.ThreadsafeBrowser.run_threadsafe(self.useHere_, timeout_=timeout)
|
|
99
|
+
|
|
100
|
+
def logout(self, timeout=120):
|
|
101
|
+
return self.ThreadsafeBrowser.run_threadsafe(self.logout_, timeout_=timeout)
|
|
102
|
+
|
|
103
|
+
def getMessageById(self, messageId, timeout=120):
|
|
104
|
+
return self.ThreadsafeBrowser.run_threadsafe(self.getMessageById_, messageId, timeout_=timeout)
|
|
105
|
+
|
|
106
|
+
def getMessages(self, chatId, params=None, timeout=120):
|
|
107
|
+
"""
|
|
108
|
+
:param chatId:
|
|
109
|
+
:param params: (count, id, direction)
|
|
110
|
+
:return:
|
|
111
|
+
"""
|
|
112
|
+
return self.ThreadsafeBrowser.run_threadsafe(self.getMessages_, chatId, params, timeout_=timeout)
|
|
113
|
+
|
|
114
|
+
def rejectCall(self, callId, timeout=120):
|
|
115
|
+
return self.ThreadsafeBrowser.run_threadsafe(self.rejectCall_, callId, timeout_=timeout)
|
|
116
|
+
|
|
117
|
+
#############################
|
|
118
|
+
async def useHere_(self):
|
|
119
|
+
return await self.ThreadsafeBrowser.page_evaluate("() => WAPI.takeOver()")
|
|
120
|
+
|
|
121
|
+
async def logout_(self):
|
|
122
|
+
return await self.ThreadsafeBrowser.page_evaluate("() => WPP.conn.logout()")
|
|
123
|
+
|
|
124
|
+
async def getMessageById_(self, messageId):
|
|
125
|
+
return await self.ThreadsafeBrowser.page_evaluate("(messageId) => WAPI.getMessageById(messageId)", messageId)
|
|
126
|
+
|
|
127
|
+
async def getMessages_(self, chatId, params=None):
|
|
128
|
+
"""
|
|
129
|
+
:param chatId:
|
|
130
|
+
:param params: (count, id, direction)
|
|
131
|
+
:return:
|
|
132
|
+
"""
|
|
133
|
+
if not params:
|
|
134
|
+
params = {}
|
|
135
|
+
chatId = self.valid_chatId(chatId)
|
|
136
|
+
return await self.ThreadsafeBrowser.page_evaluate("({ chatId, params }) => WAPI.getMessages(chatId, params)",
|
|
137
|
+
{"chatId": chatId, "params": params})
|
|
138
|
+
|
|
139
|
+
async def rejectCall_(self, callId):
|
|
140
|
+
return await self.ThreadsafeBrowser.page_evaluate(
|
|
141
|
+
"({callId}) => WPP.call.rejectCall(callId)", callId)
|
|
File without changes
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
useragentOverride = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.63 Safari/537.36'
|
|
4
|
+
whatsappUrl = 'https://web.whatsapp.com'
|
|
5
|
+
chromiumArgs = [
|
|
6
|
+
'--log-level=3',
|
|
7
|
+
'--start-maximized',
|
|
8
|
+
'--no-default-browser-check',
|
|
9
|
+
'--disable-site-isolation-trials',
|
|
10
|
+
'--no-experiments',
|
|
11
|
+
'--ignore-gpu-blacklist',
|
|
12
|
+
'--ignore-certificate-errors',
|
|
13
|
+
'--ignore-certificate-errors-spki-list',
|
|
14
|
+
'--disable-gpu',
|
|
15
|
+
'--disable-extensions',
|
|
16
|
+
'--disable-default-apps',
|
|
17
|
+
'--enable-features=NetworkService',
|
|
18
|
+
'--disable-setuid-sandbox',
|
|
19
|
+
'--no-sandbox',
|
|
20
|
+
# Extras
|
|
21
|
+
'--disable-webgl',
|
|
22
|
+
'--disable-infobars',
|
|
23
|
+
'--window-position=0,0',
|
|
24
|
+
'--ignore-certifcate-errors',
|
|
25
|
+
'--ignore-certifcate-errors-spki-list',
|
|
26
|
+
'--disable-threaded-animation',
|
|
27
|
+
'--disable-threaded-scrolling',
|
|
28
|
+
'--disable-in-process-stack-traces',
|
|
29
|
+
'--disable-histogram-customizer',
|
|
30
|
+
'--disable-gl-extensions',
|
|
31
|
+
'--disable-composited-antialiasing',
|
|
32
|
+
'--disable-canvas-aa',
|
|
33
|
+
'--disable-3d-apis',
|
|
34
|
+
'--disable-accelerated-2d-canvas',
|
|
35
|
+
'--disable-accelerated-jpeg-decoding',
|
|
36
|
+
'--disable-accelerated-mjpeg-decode',
|
|
37
|
+
'--disable-app-list-dismiss-on-blur',
|
|
38
|
+
'--disable-accelerated-video-decode',
|
|
39
|
+
'--disable-dev-shm-usage',
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
logging.basicConfig(level=logging.ERROR, format='%(asctime)s - %(levelname)s - %(message)s',
|
|
43
|
+
datefmt='%d-%b-%y %H:%M:%S')
|
|
44
|
+
Logger = logging.getLogger(name="WPP_Whatsapp")
|
|
45
|
+
|
|
46
|
+
defaultOptions = {
|
|
47
|
+
"folderNameToken": r"E:\Projects\Python\_Libs_\tokens",
|
|
48
|
+
"headless": True,
|
|
49
|
+
"devtools": False,
|
|
50
|
+
"useChrome": True,
|
|
51
|
+
"debug": False,
|
|
52
|
+
"logQR": True,
|
|
53
|
+
"browserWS": '',
|
|
54
|
+
"browserArgs": [''],
|
|
55
|
+
"puppeteerOptions": {},
|
|
56
|
+
"disableWelcome": False,
|
|
57
|
+
"updatesLog": True,
|
|
58
|
+
"autoClose": 0,
|
|
59
|
+
"deviceSyncTimeout": 180000,
|
|
60
|
+
"createPathFileToken": True,
|
|
61
|
+
"waitForLogin": True,
|
|
62
|
+
"logger": Logger,
|
|
63
|
+
"tokenStore": 'file',
|
|
64
|
+
'whatsappVersion': '2.2326.x',
|
|
65
|
+
'deviceName': False,
|
|
66
|
+
'linkPreviewApiServers': None,
|
|
67
|
+
'disableGoogleAnalytics': True,
|
|
68
|
+
'googleAnalyticsId': None,
|
|
69
|
+
'poweredBy': 'WPPConnect',
|
|
70
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import inspect
|
|
2
|
+
from asyncio import ProactorEventLoop
|
|
3
|
+
from types import FunctionType
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def async_to_sync(func: FunctionType):
|
|
7
|
+
def wrapper(self, *args, **kwargs):
|
|
8
|
+
if not inspect.isfunction(func):
|
|
9
|
+
raise Exception(f"{func} Not Function")
|
|
10
|
+
if inspect.iscoroutinefunction(func):
|
|
11
|
+
future = func(self, *args, **kwargs)
|
|
12
|
+
if inspect.iscoroutine(future):
|
|
13
|
+
self.loop: "ProactorEventLoop"
|
|
14
|
+
# try:
|
|
15
|
+
return self.loop.run_until_complete(func(self, *args, **kwargs))
|
|
16
|
+
# except RuntimeError :
|
|
17
|
+
# return asyncio.ensure_future(future, loop=self.loop)
|
|
18
|
+
|
|
19
|
+
return future
|
|
20
|
+
|
|
21
|
+
return wrapper
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import base64
|
|
2
|
+
|
|
3
|
+
import requests
|
|
4
|
+
import re
|
|
5
|
+
from typing import List, Union
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
async def downloadFileToBase64(_path: str, _mines: List[Union[str, re.Pattern]] = []) -> Union[str, bool]:
|
|
9
|
+
if not isinstance(_mines, list):
|
|
10
|
+
print(f'set mines string array, not "{type(_mines).__name__}"')
|
|
11
|
+
return False
|
|
12
|
+
|
|
13
|
+
re_http = re.compile(r'^https?:')
|
|
14
|
+
|
|
15
|
+
if not re_http.match(_path):
|
|
16
|
+
return False
|
|
17
|
+
|
|
18
|
+
try:
|
|
19
|
+
response = requests.get(_path)
|
|
20
|
+
response.raise_for_status()
|
|
21
|
+
|
|
22
|
+
mimeType = response.headers['content-type']
|
|
23
|
+
|
|
24
|
+
if _mines:
|
|
25
|
+
isValidMime = any((m.fullmatch(mimeType) if isinstance(m, re.Pattern) else m == mimeType) for m in _mines)
|
|
26
|
+
if not isValidMime:
|
|
27
|
+
print(f'Content-Type "{mimeType}" of {_path} is not allowed')
|
|
28
|
+
return False
|
|
29
|
+
|
|
30
|
+
archive = base64.b64encode(response.content)
|
|
31
|
+
base64_content = archive.decode("utf-8")
|
|
32
|
+
|
|
33
|
+
return f'data:{mimeType};base64,{base64_content}'
|
|
34
|
+
except Exception as e:
|
|
35
|
+
print(e)
|
|
36
|
+
|
|
37
|
+
return False
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import traceback
|
|
3
|
+
|
|
4
|
+
# from threading import Thread, Event
|
|
5
|
+
#
|
|
6
|
+
#
|
|
7
|
+
# def setInterval(func, interval, *args, **kwargs):
|
|
8
|
+
# stopped = Event()
|
|
9
|
+
#
|
|
10
|
+
# async def loop():
|
|
11
|
+
# while not stopped.wait(interval):
|
|
12
|
+
# await func(*args)
|
|
13
|
+
#
|
|
14
|
+
# Thread(target=loop).start()
|
|
15
|
+
# return stopped
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# def setInterval(func, interval, *args, **kwargs):
|
|
19
|
+
# stopped = asyncio.Event()
|
|
20
|
+
# loop = kwargs.get('loop') or asyncio.get_event_loop()
|
|
21
|
+
#
|
|
22
|
+
# async def loop_():
|
|
23
|
+
# print("__nn__")
|
|
24
|
+
# while not stopped.is_set():
|
|
25
|
+
# await func(*args)
|
|
26
|
+
# await asyncio.sleep(interval)
|
|
27
|
+
# print("finish")
|
|
28
|
+
#
|
|
29
|
+
# loop. create_task(loop_())
|
|
30
|
+
# return stopped
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
# async def pprint_():
|
|
34
|
+
# print("ffffffffffffff")
|
|
35
|
+
#
|
|
36
|
+
#
|
|
37
|
+
# d = setInterval(pprint_, 5)
|
|
38
|
+
#
|
|
39
|
+
# async def asetInterval(func, timeout, *args):
|
|
40
|
+
# print("setInterval")
|
|
41
|
+
# while True:
|
|
42
|
+
# await asyncio.sleep(timeout / 1000)
|
|
43
|
+
# print("func")
|
|
44
|
+
# await func(*args)
|
|
45
|
+
#
|
|
46
|
+
#
|
|
47
|
+
# def setTimeout(func, time, *args):
|
|
48
|
+
# stopped = Event()
|
|
49
|
+
#
|
|
50
|
+
# def loop():
|
|
51
|
+
# while not stopped.wait((time / 1000)):
|
|
52
|
+
# func(*args)
|
|
53
|
+
# stopped.set()
|
|
54
|
+
#
|
|
55
|
+
# Thread(target=loop).start()
|
|
56
|
+
# return stopped
|
|
57
|
+
#
|
|
58
|
+
#
|
|
59
|
+
# def clearInterval(Interval):
|
|
60
|
+
# try:
|
|
61
|
+
# if Interval:
|
|
62
|
+
# Interval.set()
|
|
63
|
+
# print("Interval", Interval.is_set())
|
|
64
|
+
# # Interval.clear()
|
|
65
|
+
# except:
|
|
66
|
+
# traceback.print_exc()
|
|
67
|
+
#
|
|
68
|
+
#
|
|
69
|
+
# async def print_i(i):
|
|
70
|
+
# print(i + 1, "print_i")
|
|
71
|
+
# await asyncio.sleep(1)
|
|
72
|
+
# print(i + 2, "print_i")
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
# async def stop_All():
|
|
76
|
+
# clearInterval(intr)
|
|
77
|
+
# clearInterval(intr2)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
# intr = setInterval(print_i, 5, 1)
|
|
81
|
+
# intr2 = setInterval(stop_All, 50, )
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
from typing import Dict
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
class EventEmitter:
|
|
88
|
+
|
|
89
|
+
def __init__(self):
|
|
90
|
+
self._callbacks: Dict[str, callable] = {}
|
|
91
|
+
|
|
92
|
+
def on(self, event_name, function):
|
|
93
|
+
self._callbacks[event_name] = self._callbacks.get(event_name, []) + [function]
|
|
94
|
+
return function
|
|
95
|
+
|
|
96
|
+
def emit(self, event_name, *args, **kwargs):
|
|
97
|
+
[function(*args, **kwargs) for function in self._callbacks.get(event_name, [])]
|
|
98
|
+
|
|
99
|
+
def off(self, event_name, function):
|
|
100
|
+
self._callbacks.get(event_name, []).remove(function)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def setInterval(loop, func, interval, *args, **kwargs):
|
|
104
|
+
stopped = asyncio.Event()
|
|
105
|
+
|
|
106
|
+
async def loop_():
|
|
107
|
+
while not stopped.is_set():
|
|
108
|
+
if asyncio.iscoroutinefunction(func):
|
|
109
|
+
await func(*args, **kwargs)
|
|
110
|
+
else:
|
|
111
|
+
func(*args, **kwargs)
|
|
112
|
+
await asyncio.sleep(interval)
|
|
113
|
+
|
|
114
|
+
loop.create_task(loop_())
|
|
115
|
+
return stopped
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|