πŸš€ Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more β†’

pywa

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

pywa

Build WhatsApp Bots in Python β€’ Fast, Effortless, Powerful πŸš€

2.10.0
Maintainers
1
PyWa Logo

PyWa β€’ Build WhatsApp Bots in Python β€’ Fast, Effortless, Powerful πŸš€

PyPi Downloads PyPI Version Tests Coverage Docs License CodeFactor Telegram

πŸ’« PyWa is the all-in-one Python framework for the WhatsApp Cloud API

Send rich messages with media and interactive buttons, Listen to user events in real time, Build and send flows, Create and send template messages, Enjoy blazing-fast async support and seamless integration with FastAPI, Flask, and more. Fully typed, documented, and production-ready. Build powerful WhatsApp bots in minutes.

πŸ“„ Quick Documentation Index

Get Started β€’ WhatsApp Client β€’ Handlers β€’ Listeners β€’ Filters β€’ Updates β€’ Flows β€’ Examples

⚑ Why PyWa?

  • πŸš€ Fast and Simple: Focus on building your bot without worrying about low-level details.
  • πŸ’¬ Rich Messaging: Send text, images, videos, documents, audio, locations, contacts, and interactive keyboards.
  • πŸ“© Real-Time Updates: Receive messages, callbacks, and message status updates effortlessly.
  • πŸ”” Listeners: Use powerful listeners to wait for specific user events.
  • ♻️ Flows Support: Create, send, and listen to Flows seamlessly.
  • πŸ”„ Webhook Integration: Built-in support for popular frameworks like Flask and FastAPI.
  • πŸ”¬ Advanced Filters: Handle incoming updates with powerful filtering options.
  • πŸ“„ Template Messaging: Easily create and send template messages.
  • βœ… Production-Ready: Fully typed, documented, and rigorously tested for reliability.

πŸ‘¨β€πŸ’» How to Use

  • Send a message

See WhatsApp Client for all the options.

from pywa import WhatsApp, types

# Create a WhatsApp client
wa = WhatsApp(
    phone_id="100458559237541",
    token="EAAEZC6hUxkTIB"
)

# Send a text message with buttons
wa.send_message(
    to="9876543210",
    text="Hello from PyWa!",
    buttons=[
        types.Button(title="Menu", callback_data="menu"),
        types.Button(title="Help", callback_data="help")
    ]
)

# Send a image message from URL
wa.send_image(
    to="9876543210",
    image="https://example.com/image.jpg",
    caption="Check out this image!",
)
  • Handle incoming updates (with FastAPI in this example)

See Handlers for fully detailed guide.

# wa.py
from pywa import WhatsApp, filters, types
from fastapi import FastAPI

fastapi_app = FastAPI() # FastAPI server

# Create a WhatsApp client
wa = WhatsApp(
    phone_id=1234567890,
    token="************",
    server=fastapi_app, # the server to listen to incoming updates
    callback_url="https://yourdomain.com/",  # the public URL of your server
    verify_token="xyz123", # some random string to verify the webhook
    app_id=123456, # your app id
    app_secret="*******" # your app secret
)

# Register callback to handle incoming messages
@wa.on_message(filters.matches("Hello", "Hi")) # Filter to match text messages that contain "Hello" or "Hi"
def hello(client: WhatsApp, msg: types.Message):
    msg.react("πŸ‘‹") # React to the message with a wave emoji
    msg.reply_text( # Short reply to the message
        text=f"Hello {msg.from_user.name}!", # Greet the user
        buttons=[ # Add buttons to the reply
            types.Button(
                title="About me",
                callback_data="about_me" # Callback data to identify the click
            )
        ]
    )
    # Use the `wait_for_reply` listener to wait for a reply from the user
    age = msg.reply(text="What's your age?").wait_for_reply(filters=filters.text).text
    msg.reply_text(f"Your age is {age}.")

# Register another callback to handle incoming button clicks
@wa.on_callback_button(filters.matches("about_me")) # Filter to match the button click
def click_me(client: WhatsApp, clb: types.CallbackButton):
    clb.reply_text(f"Hello {clb.from_user.name}, I am a WhatsApp bot built with PyWa!") # Reply to the button click
  • To run the server, use fastapi-cli (pip install "fastapi[standard]"):
fastapi dev wa.py  # see uvicorn docs for more options (port, host, reload, etc.)
  • Async Usage

  • PyWa also supports async usage with the same API. This is useful if you want to use async/await in your code. To use the async version, replace all the imports from pywa to pywa_async:

# wa.py
import fastapi
from pywa_async import WhatsApp, types  # Same API, just different imports

fastapi_app = fastapi.FastAPI()
wa = WhatsApp(..., server=fastapi_app)

async def main():
    await wa.send_message(...) # async call

@wa.on_message
async def hello(_: WhatsApp, msg: types.Message): # async callback
    await msg.react("πŸ‘‹")
    await msg.reply(...)
  • Create and send flows

See Flows for much more details and examples.

from pywa import WhatsApp, types
from pywa.types.flows import *

# Create a WhatsApp client
wa = WhatsApp(..., business_account_id=123456)

# Build a flow
my_flow_json = FlowJSON(
    screens=[
        Screen(
            id="NEWSLETTER",
            title="PyWa Newsletter",
            layout=Layout(
                children=[
                    TextHeading(text="Subscribe to our newsletter"),
                    name := TextInput(
                        name="name",
                        label="Name",
                        input_type=InputType.TEXT,
                        required=False,
                    ),
                    email := TextInput(
                        name="email",
                        label="Email",
                        input_type=InputType.EMAIL,
                        required=True,
                    ),
                    Footer(
                        label="Subscribe",
                        on_click_action=CompleteAction(
                            payload={ # Payload to send to the server
                                "name": name.ref,
                                "email": email.ref,
                            }
                        )
                    )
                ]
            )
        )
    ]
)

# Create the flow
wa.create_flow(
    name="subscribe_to_newsletter",
    categories=[FlowCategory.SIGN_UP, FlowCategory.OTHER],
    flow_json=my_flow_json,
    publish=True
)

# Send the flow to a user
wa.send_text(
    to="9876543210",
    text="Hello from PyWa!",
    buttons=types.FlowButton(
        title="Subscribe to our newsletter!",
        flow_name="subscribe_to_newsletter",
    )
)

# Handle the flow response
@wa.on_flow_completion
def handle_flow_response(_: WhatsApp, flow: types.FlowCompletion):
    flow.reply(
        text=f"Thank you for subscribing to our newsletter, {flow.response['name']}! "
             f"We will send you updates to {flow.response['email']}.",
        buttons=[types.Button(title="Unsubscribe", callback_data="unsubscribe")]
    )
  • Create and send template messages
from pywa import WhatsApp, types

# Create a WhatsApp client
wa = WhatsApp(..., business_account_id=123456)

# Create a template
created = wa.create_template(
    template=types.NewTemplate(
        name="buy_new_iphone_x",
        category=types.NewTemplate.Category.MARKETING,
        language=types.NewTemplate.Language.ENGLISH_US,
        header=types.NewTemplate.Text(text="The New iPhone {15} is here!"),
        body=types.NewTemplate.Body(text="Buy now and use the code {WA_IPHONE_15} to get {15%} off!"),
        footer=types.NewTemplate.Footer(text="Powered by PyWa"),
        buttons=[
            types.NewTemplate.UrlButton(title="Buy Now", url="https://example.com/shop/{iphone15}"),
            types.NewTemplate.PhoneNumberButton(title="Call Us", phone_number='1234567890'),
            types.NewTemplate.QuickReplyButton(text="Unsubscribe from marketing messages"),
            types.NewTemplate.QuickReplyButton(text="Unsubscribe from all messages"),
        ],
    ),
)

# Send the template message
wa.send_template(
    to="9876543210",
    template=types.Template(
        name="buy_new_iphone_x",
        language=types.Template.Language.ENGLISH_US,
        header=types.Template.TextValue(value="15"),
        body=[
            types.Template.TextValue(value="John Doe"),
            types.Template.TextValue(value="WA_IPHONE_15"),
            types.Template.TextValue(value="15%"),
        ],
        buttons=[
            types.Template.UrlButtonValue(value="iphone15"),
            types.Template.QuickReplyButtonData(data="unsubscribe_from_marketing_messages"),
            types.Template.QuickReplyButtonData(data="unsubscribe_from_all_messages"),
        ],
    ),
)

πŸŽ› Installation

  • Install using pip3:
pip3 install -U pywa
  • Install from source (the bleeding edge):
pip3 install -U git+https://github.com/david-lev/pywa.git
  • If you going to use the webhook features, here is shortcut to install the required dependencies:
pip3 install -U "pywa[fastapi]"
pip3 install -U "pywa[flask]"
  • If you going to use the Flow features and want to use the default FlowRequestDecryptor and the default FlowResponseEncryptor, here is shortcut to install the required dependencies:
pip3 install -U "pywa[cryptography]"

πŸ’Ύ Requirements

πŸ“– Setup and Usage

See the Documentation for detailed instructions

β˜‘οΈ TODO

  • Add support for async
  • Add support for more web frameworks (Django, aiohttp, etc.)
  • Add support for flows
  • Add support for more types of updates (account_alerts, phone_number_quality_updates, template_category_updates, etc.)
  • Add more examples and guides

Feel free to open an issue if you have any suggestions. or even better - submit a PR!

βš–οΈ License

This project is licensed under the MIT License - see the LICENSE file for details

πŸ”± Contributing

Contributions are welcome! Please see the Contributing Guide for more information.

FAQs

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts