### Dynamic Handler Registration Example Setup Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/handlers/overview.rst Sets up a filter for admin users and initializes a WhatsApp client. This is the prelude to dynamically adding and removing handlers at runtime. ```python from pywa import WhatsApp, filters, handlers, types wa = WhatsApp(...) admin_filter = filters.from_users("1234567890", "9876543210") ``` -------------------------------- ### Python: Start ngrok Tunnel and Initialize WhatsApp Client Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/handlers/overview.rst This snippet shows how to start an ngrok tunnel to get a public callback URL and then initialize the WhatsApp client with this URL. It also includes a basic message echo handler. ```python from pywa import WhatsApp, filters, types, utils callback_url = utils.start_ngrok_tunnel( port=8000, auth_token="your-ngrok-auth-token", domain="subdomain.ngrok-free.app", ) wa = WhatsApp( phone_id="1234567890", token="EAA...", app_id="1234567890", app_secret="xxxx", callback_url=callback_url, verify_token="my-verify-token", ) @wa.on_message(filters.text) def echo(client: WhatsApp, msg: types.Message): msg.reply(msg.text) ``` -------------------------------- ### Install Pywa with All Features Source: https://github.com/david-lev/pywa/blob/master/README.md Install Pywa with all available features, including the server and cryptography support. ```bash # Everything pip install -U "pywa[server,cryptography]" ``` -------------------------------- ### Set Up Virtual Environment and Install Dependencies Source: https://github.com/david-lev/pywa/blob/master/CONTRIBUTING.md Create a virtual environment and install the project's development dependencies. For documentation changes, include the 'docs' extra. ```bash python3 -m venv .venv source .venv/bin/activate pip install -e ".[dev]" # for docs changes: pip install -e ".[dev,docs]" ``` -------------------------------- ### Install Pywa with Server Source: https://github.com/david-lev/pywa/blob/master/README.md Install Pywa with the recommended built-in webhook server for handling incoming messages. ```bash # With built-in webhook server (recommended) pip install -U "pywa[server]" ``` -------------------------------- ### Translator Bot Example (Setup) Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/examples/demo-bots.rst This snippet sets up a translator bot using Google Translate. It initializes the translator and pywa, and defines dictionaries for popular and other languages. ```python import logging import googletrans # pip3 install googletrans==4.0.0-rc1 from pywa import WhatsApp, types, filters translator = googletrans.Translator() wa = WhatsApp( phone_id='your_phone_number', token='your_token', verify_token='xyzxyz', ) MESSAGE_ID_TO_TEXT: dict[str, str] = {} # msg_id -> text POPULAR_LANGUAGES = { "en": ("English", "๐Ÿ‡บ๐Ÿ‡ธ"), "es": ("Espaรฑol", "๐Ÿ‡ช๐Ÿ‡ธ"), "fr": ("Franรงais", "๐Ÿ‡ซ๐Ÿ‡ท") } OTHER_LANGUAGES = { "iw": ("ืขื‘ืจื™ืช", "๐Ÿ‡ฎ๐Ÿ‡ฑ"), "ar": ("ุงู„ุนุฑุจูŠุฉ", "๐Ÿ‡ธ๐Ÿ‡ฆ"), "ru": ("ะ ัƒััะบะธะน", "๐Ÿ‡ท๐Ÿ‡บ"), "de": ("Deutsch", "๐Ÿ‡ฉ๐Ÿ‡ช"), "it": ("Italiano", "๐Ÿ‡ฎ๐Ÿ‡น"), "pt": ("Portuguรชs", "๐Ÿ‡ต๐Ÿ‡น"), "ja": ("ๆ—ฅๆœฌ่ชž", "๐Ÿ‡ฏ๐Ÿ‡ต"), } ``` -------------------------------- ### Login Screen Example Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/examples/sign_up_flow.rst Example code for setting up a login screen. This snippet demonstrates the structure and components used for user authentication. ```python from pywa.widgets import Screen, ScreenData, TextInput, TextHeading, EmbeddedLink, Form, Footer, Action, FlowActionType, InputType login_screen = Screen( data=ScreenData( email=str, password=str ), layout=[ TextHeading("Login to your account") ], content=[ Form( children=[ TextInput( key="email", label="Email", input_type=InputType.EMAIL, required=True ), TextInput( key="password", label="Password", input_type=InputType.PASSWORD, required=True ) ] ) ], footer=Footer( children=[ Action( FlowActionType.DATA_EXCHANGE, "Login", { "email": login_screen.data.email.ref, "password": login_screen.data.password.ref } ) ] ) ) ``` -------------------------------- ### Install Pywa Server Extras Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/handlers/overview.rst Install the necessary extras for running the Pywa server. This command should be run in your terminal. ```bash pip install "pywa[server]" ``` -------------------------------- ### Hello Bot Example Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/examples/demo-bots.rst A basic bot that sends a "Hello" message and a wave emoji to users when they send a message. It requires basic pywa setup. ```python from pywa import WhatsApp, types wa = WhatsApp( phone_id='your_phone_number', token='your_token', verify_token='xyzxyz', ) @wa.on_message def hello(_: WhatsApp, msg: types.Message): msg.react('๐Ÿ‘‹') msg.reply(f'Hello {msg.from_user.name}!') # Run the server with `pywa dev` ``` -------------------------------- ### Install Pywa Core Source: https://github.com/david-lev/pywa/blob/master/README.md Install the core Pywa library for sending messages without a webhook server. ```bash # Core (sending messages, no webhook server) pip install -U pywa ``` -------------------------------- ### Install PyWa with Server Support Source: https://github.com/david-lev/pywa/blob/master/README.md Install the PyWa package with the necessary dependencies for server-side integration. This command is used to set up the framework for receiving webhooks and managing bot interactions. ```bash pip install -U "pywa[server]" ``` -------------------------------- ### Install Pywa using pip Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/getting-started.rst Install the pywa library using pip. This is the standard method for installing Python packages. ```bash pip3 install -U pywa ``` -------------------------------- ### Python Handler for Message Commands Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/handlers/overview.rst Example of a Python handler that responds to a 'start' command and waits for a text reply from the user. ```python from pywa import WhatsApp, filters, types wa = WhatsApp(...) @wa.on_message(filters.command("start")) def start(client: WhatsApp, msg: types.Message): age = msg.reply("Hello! What's your age?").wait_for_reply(filters.text).text msg.reply(f"Nice, you are {age}.") ``` -------------------------------- ### Install Pywa from Source Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/getting-started.rst Install the bleeding-edge version of pywa directly from its GitHub repository. This is useful for developers who want the latest features or to contribute to the project. ```bash git clone https://github.com/david-lev/pywa.git cd pywa && pip3 install -U . ``` -------------------------------- ### Install Pywa with Webhook Support Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/getting-started.rst Install pywa with the 'server' extra to enable webhook features. This is necessary if you plan to receive messages or events from WhatsApp. ```bash pip3 install -U "pywa[server]" ``` -------------------------------- ### Static Flow Example (newsletter_flow.py) Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/flows/overview.rst This example demonstrates the structure of a static WhatsApp Flow, defining screens and components without server-side interaction. ```python from pywa.types.flows import * ``` -------------------------------- ### Sign Up Flow Handler (Pre 1.22.0) Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/examples/sign_up_flow.rst This example shows how to handle the SIGN_UP screen manually before version 1.22.0, including checks for existing users, password matching, and password complexity. ```python @wa.on_flow_request("/sign-up-flow") def on_sign_up_request(_: WhatsApp, flow: FlowRequest) -> FlowResponse | None: if flow.action == FlowRequestActionType.DATA_EXCHANGE: if flow.screen == "SIGN_UP": if user_repository.exists(flow.data["email"]): ... elif flow.data["password"] != flow.data["confirm_password"]: ... elif not any(char.isdigit() for char in flow.data["password"]): ... else: ... elif flow.screen == "LOGIN": ... elif flow.screen == "LOGIN_SUCCESS": ... ``` -------------------------------- ### Start Screen Configuration Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/examples/sign_up_flow.rst Defines the initial screen of the flow, presenting welcome text and options to sign up or log in. This screen is static and does not expect data. ```python START = Screen( id="START", title="Home", layout=Layout( children=[ TextHeading( text="Welcome to our app", ), EmbeddedLink( text="Click here to sign up", on_click_action=Action( name=FlowActionType.NAVIGATE, next=Next( type=NextType.SCREEN, name="SIGN_UP", ), payload={ "first_name_initial_value": "", "last_name_initial_value": "", "email_initial_value": "", "password_initial_value": "", "confirm_password_initial_value": "", }, ), ), EmbeddedLink( text="Click here to login", on_click_action=Action( name=FlowActionType.NAVIGATE, next=Next( type=NextType.SCREEN, name="LOGIN", ), payload={ "email_initial_value": "", "password_initial_value": "", }, ), ), ] ), ) ``` -------------------------------- ### Bash: Install ngrok Package Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/handlers/overview.rst Command to install the ngrok Python package using pip. ```bash pip install ngrok ``` -------------------------------- ### Install Pre-commit Hooks Source: https://github.com/david-lev/pywa/blob/master/CONTRIBUTING.md Activate pre-commit to ensure code quality checks are performed automatically before commits. ```bash pre-commit install ``` -------------------------------- ### Python: Manual Callback URL Registration Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/handlers/overview.rst Example for manual callback URL registration where the client is initialized with a token and verify_token. Pywa will handle the verification challenge. ```python from pywa import WhatsApp wa = WhatsApp( token="EAA...", verify_token="my-verify-token", ) ``` -------------------------------- ### Send Authentication Template Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/templates/overview.rst Example of sending an authentication template with OTP. Ensure the template name and language are correctly configured. ```python wa.send_template( to="972123456789", name="auth_code", language=TemplateLanguage.ENGLISH_US, params=[ AuthenticationBody.params(otp="123456"), OneTapOTPButton.params(otp="123456"), ], ) ``` -------------------------------- ### Install Pywa with Cryptography Support Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/getting-started.rst Install pywa with the 'cryptography' extra for Flow features, including default encryption and decryption. This is required for advanced message handling with Flows. ```bash pip3 install -U "pywa[cryptography]" ``` -------------------------------- ### Partner App Installed Filter Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/filters/account_update_filters.rst A filter that triggers when a partner's app is installed. ```APIDOC ## pywa.filters.partner_app_installed ### Description This filter is used to detect when a partner's application has been installed. ### Usage ```python # Example usage (conceptual) if partner_app_installed(update): print("Partner app installed") ``` ``` -------------------------------- ### Python: Automatic Callback URL Registration (App Scope) Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/handlers/overview.rst Example demonstrating automatic callback URL registration with Pywa for the app scope. Requires app_id and app_secret. ```python from pywa import WhatsApp, utils wa = WhatsApp( phone_id="1234567890", token="EAA...", app_id="1234567890", app_secret="xxxx", callback_url=utils.start_ngrok_tunnel(domain="subdomain.ngrok-free.app"), verify_token="my-verify-token", ) ``` -------------------------------- ### Run Pywa Server Directly from Python Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/handlers/overview.rst For quick scripts and prototypes, you can start the built-in server directly from Python using the `WhatsApp.run()` method. This method is blocking. ```python from pywa import WhatsApp wa = WhatsApp(...) # Register handlers here wa.run() ``` -------------------------------- ### WhatsApp.listen Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/listeners/reference.rst Starts listening for incoming messages and events from WhatsApp. ```APIDOC ## WhatsApp.listen ### Description Starts listening for incoming messages and events from WhatsApp. ### Method (Method signature from source, not an HTTP method) ### Parameters (Parameters not explicitly detailed in the source, omitted) ### Request Example (Not applicable for this method) ### Response (Response details not explicitly detailed in the source, omitted) ``` -------------------------------- ### Run pywa in Development Mode Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/handlers/overview.rst This command starts the pywa webhook server for development and enables automatic reloading when code changes. ```bash pywa dev ``` -------------------------------- ### Python: Automatic Callback URL Registration (Phone Scope) Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/handlers/overview.rst Example showing automatic callback URL registration with Pywa for the phone number scope. Requires a specific callback_url and verify_token. ```python from pywa import WhatsApp, utils wa = WhatsApp( phone_id="1234567890", token="EAA...", verify_token="my-verify-token", callback_url="https://example.com", callback_url_scope=utils.CallbackURLScope.PHONE, ) ``` -------------------------------- ### Define Media Template Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/templates/overview.rst Define a template that includes media components like images. The 'example' parameter can be a URL, file path, Media object, or bytes, used by WhatsApp for verification. ```python from pywa.types.templates import * media_template = Template( name="media_template", language=TemplateLanguage.ENGLISH_US, category=TemplateCategory.MARKETING, components=[ HeaderImage(example="https://www.example.com/image-example.jpg"), BodyText(text="Check out our new product!"), FooterText(text="Visit our website for more details."), ], ) ``` -------------------------------- ### Pywa Conversational Flows with Listeners Source: https://github.com/david-lev/pywa/blob/master/README.md Implement conversational flows using message listeners. This example prompts for a name and replies with a greeting. Requires an initialized WhatsApp object. ```python @wa.on_message(filters.command("start")) def start(_: WhatsApp, msg: types.Message): name = msg.reply("What's your name?").wait_for_reply(filters=filters.text).text msg.reply(f"Nice to meet you, {name}!") ``` -------------------------------- ### v5.1 Python Flow Examples Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/examples/flows.rst Python code for WhatsApp Business API v5.1 flows. Found in the tests/data/flows directory. ```python from pywa.utils import WhatsAppMessage def get_flow_message_v5_1() -> WhatsAppMessage: """Get a v5.1 flow message.""" return WhatsAppMessage( type="interactive", interactive={ "type": "flow", "flow": { "name": "123456789012345", "parameters": [ { "name": "flow_token", "value": "flow_token_value" }, { "name": "flow_message", "value": "flow_message_value" }, { "name": "flow_json_payload", "value": { "key1": "value1", "key2": "value2" } } ] } } ) ``` -------------------------------- ### Send Flow Message with Button Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/examples/sign_up_flow.rst Send a message containing a flow button to initiate a user flow. This example demonstrates how to configure the button with flow details like ID, token, mode, and action. ```python from pywa.types import FlowButton from pywa.types.flows import FlowStatus, FlowActionType wa.send_message( to="1234567890", text="Welcome to our app! Click the button below to login or sign up", buttons=FlowButton( title="Sign Up", flow_id=flow_id, flow_token="5749d4f8-4b74-464a-8405-c26b7770cc8c", mode=FlowStatus.DRAFT, flow_action_type=FlowActionType.NAVIGATE, flow_action_screen="START", ), ) ``` -------------------------------- ### URL Uploader Bot Example Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/examples/demo-bots.rst This bot uploads files from URLs provided in messages. It also includes error handling for media download and upload failures, notifying the user if a file cannot be processed. ```python from pywa import WhatsApp, types, filters, errors wa = WhatsApp( phone_id='your_phone_number', token='your_token', verify_token='xyzxyz', ) @wa.on_message(filters.startswith('http')) def download(_: WhatsApp, msg: types.Message): msg.reply_document(msg.text, filename=msg.text.split('/')[-1]) # When a file fails to download/upload, the bot will reply with an error message. @wa.on_message_status(filters.failed_with(errors.MediaDownloadError, errors.MediaUploadError)) def on_media_download_error(_: WhatsApp, status: types.MessageStatus): status.reply(f"I can't download/upload this file: {status.error.details}") # Run the server with `pywa dev` ``` -------------------------------- ### Replace ChatOpened Entry Points Source: https://github.com/david-lev/pywa/blob/master/MIGRATION.md Replace the `@wa.on_chat_opened` decorator with `@wa.on_message(filters.command("start"))` for handling initial user interactions. ```python ########################## OLD CODE ########################## from pywa import WhatsApp, types wa = WhatsApp(...) @wa.on_chat_opened def opened_chat(_: WhatsApp, update: types.ChatOpened): wa.send_message(to=update.from_user.wa_id, text="Welcome!") ########################## NEW CODE ########################## from pywa import WhatsApp, filters, types wa = WhatsApp(...) @wa.on_message(filters.command("start")) def start(_: WhatsApp, msg: types.Message): msg.reply("Welcome!") @wa.on_callback_button(filters.matches("start")) def start_clicked(_: WhatsApp, clb: types.CallbackButton): clb.reply_text("Welcome!") ``` -------------------------------- ### Serve Documentation Locally Source: https://github.com/david-lev/pywa/blob/master/CONTRIBUTING.md Run a local HTTP server to view the built documentation. Navigate to http://localhost:8000 in your browser. ```bash python3 -m http.server 8000 -d docs/build/html ``` -------------------------------- ### start_ngrok_tunnel Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/types/others.rst Starts an ngrok tunnel to expose a local server to the internet. This is useful for receiving webhooks from WhatsApp. This function is part of the pywa.utils module and helps in setting up a publicly accessible URL for testing and development. ```APIDOC ## start_ngrok_tunnel() ### Description Starts an ngrok tunnel to expose a local server to the internet, facilitating webhook reception. ### Method Function call ### Parameters None explicitly documented in the source for direct invocation. ### Request Example ```python # Example usage (assuming pywa.utils is imported) # start_ngrok_tunnel() ``` ### Response Returns information about the ngrok tunnel, typically including the public URL. Specific return types are not detailed in the source. ``` -------------------------------- ### Echo Bot Example Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/examples/demo-bots.rst This bot echoes back any message it receives from a user. It uses the `copy` method to forward the message to the sender, with an option to reply to a specific message. ```python from pywa import WhatsApp, types wa = WhatsApp( phone_id='your_phone_number', token='your_token', verify_token='xyzxyz', ) @wa.on_message def echo(_: WhatsApp, msg: types.Message): try: msg.copy(to=msg.sender, reply_to_message_id=msg.message_id_to_reply) except ValueError: msg.reply("I can't echo this message") # Run the server with `pywa dev` ``` -------------------------------- ### Send Text and Image Messages with Pywa Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/getting-started.rst Initialize the WhatsApp client and send a text message and an image. Ensure you have your Phone ID and Token from API Setup, and add recipient numbers to the allowed list for testing. ```python from pywa import WhatsApp wa = WhatsApp( phone_id='YOUR_PHONE_ID', # from API Setup token='YOUR_TOKEN' # from API Setup ) # Send a text message wa.send_message( to='PHONE_NUMBER_TO_SEND_TO', text='Hi! This message was sent from pywa!' ) # Send an image wa.send_image( to='PHONE_NUMBER_TO_SEND_TO', image='https://www.rd.com/wp-content/uploads/2021/04/GettyImages-1053735888-scaled.jpg' ) ``` -------------------------------- ### Clone Repository and Navigate Source: https://github.com/david-lev/pywa/blob/master/CONTRIBUTING.md Clone your forked repository locally and navigate into the project directory. ```bash git clone https://github.com//pywa.git cd pywa ``` -------------------------------- ### Build Documentation Locally Source: https://github.com/david-lev/pywa/blob/master/CONTRIBUTING.md Build the project's documentation locally using make. This is useful for verifying documentation changes. ```bash make -C docs html ``` -------------------------------- ### Sign Up Form with Input Fields Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/examples/sign_up_flow.rst This snippet demonstrates the creation of a sign-up form with various text input fields for first name, last name, email, password, and confirm password. It includes initial values, validation rules like minimum/maximum characters and required fields, and helper text for the password. ```Python first_name_initial_value := ScreenData(key="first_name_initial_value", example="John"), last_name_initial_value := ScreenData(key="last_name_initial_value", example="Doe"), email_initial_value := ScreenData(key="email_initial_value", example="john.doe@gmail.com"), password_initial_value := ScreenData(key="password_initial_value", example="abc123"), confirm_password_initial_value := ScreenData(key="confirm_password_initial_value", example="abc123"), ], layout=Layout( children=[ TextHeading( text="Please enter your details", ), EmbeddedLink( text="Already have an account?", on_click_action=Action( name=FlowActionType.NAVIGATE, next=Next( type=NextType.SCREEN, name="LOGIN", ), payload={ "email_initial_value": "", "password_initial_value": "", }, ), ), Form( name="form", children=[ first_name := TextInput( name="first_name", label="First Name", input_type=InputType.TEXT, required=True, init_value=first_name_initial_value.ref, ), last_name := TextInput( name="last_name", label="Last Name", input_type=InputType.TEXT, required=True, init_value=last_name_initial_value.ref, ), email := TextInput( name="email", label="Email Address", input_type=InputType.EMAIL, required=True, init_value=email_initial_value.ref, ), password := TextInput( name="password", label="Password", input_type=InputType.PASSWORD, min_chars=8, max_chars=16, helper_text="Password must contain at least one number", required=True, init_value=password_initial_value.ref, ), confirm_password := TextInput( name="confirm_password", label="Confirm Password", input_type=InputType.PASSWORD, min_chars=8, max_chars=16, required=True, init_value=confirm_password_initial_value.ref, ), Footer( label="Done", on_click_action=Action( name=FlowActionType.DATA_EXCHANGE, payload={ "first_name": first_name.ref, "last_name": last_name.ref, "email": email.ref, "password": password.ref, "confirm_password": confirm_password.ref, }, ), ), ] ) ] ) ``` -------------------------------- ### Initializing Client with Handlers Module Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/handlers/overview.rst Shows how to initialize the WhatsApp client and specify modules from which to load handlers. This approach is used when handlers are defined in separate files. ```python from pywa import WhatsApp from . import my_handlers # Import the module that holds the handlers wa = WhatsApp( ..., handlers_modules=[my_handlers,], # Pass the module to load handlers from it ) ``` -------------------------------- ### pywa.filters.startswith Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/filters/common_filters.rst Function to filter messages that start with a specific prefix. ```APIDOC ## startswith ### Description Filters messages whose content starts with a specified prefix. ### Signature `startswith(prefix: str)` ### Parameters - **prefix** (str) - Required - The prefix string that the message content must start with. ### Returns A filter object that matches messages starting with the specified prefix. ``` -------------------------------- ### Dynamically Loading Handlers Module Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/handlers/overview.rst Demonstrates how to load handlers from a module after the WhatsApp client has already been initialized. This allows for on-the-fly registration of handlers. ```python wa.load_handlers_modules(my_handlers) ``` -------------------------------- ### Full Sign-Up Flow Definition Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/examples/sign_up_flow.rst Provides a comprehensive definition of the sign-up flow, including all screens, layouts, and actions. This snippet shows how to construct a complete flow from individual components. ```python from pywa import utils from pywa.types.flows import ( FlowJSON, Screen, ScreenData, Form, Footer, Layout, Action, Next, NextType, FlowActionType, ComponentRef, InputType, TextHeading, TextSubheading, TextInput, OptIn, EmbeddedLink, ) SIGN_UP_FLOW_JSON = FlowJSON( version=utils.Version.FLOW_JSON, data_api_version=utils.Version.FLOW_DATA_API, routing_model={ "START": ["SIGN_UP", "LOGIN"], "SIGN_UP": ["LOGIN"], "LOGIN": ["LOGIN_SUCCESS"], "LOGIN_SUCCESS": [], }, screens=[ Screen( id="START", title="Home", layout=Layout( children=[ TextHeading( text="Welcome to our app", ), EmbeddedLink( text="Click here to sign up", on_click_action=Action( name=FlowActionType.NAVIGATE, next=Next( type=NextType.SCREEN, name="SIGN_UP", ), payload={ "first_name_initial_value": "", "last_name_initial_value": "", "email_initial_value": "", "password_initial_value": "", "confirm_password_initial_value": "", }, ), ), EmbeddedLink( text="Click here to login", on_click_action=Action( name=FlowActionType.NAVIGATE, next=Next( type=NextType.SCREEN, name="LOGIN", ), payload={ "email_initial_value": "", "password_initial_value": "", }, ), ), ] ), ), Screen( id="SIGN_UP", title="Sign Up", data=[ ``` -------------------------------- ### Template Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/templates/types.rst Represents a generic message template. Provides methods to get components and validate parameters. ```APIDOC ## Template() ### Description Represents a generic message template. Provides methods to get components and validate parameters. ### Methods - **get_component(name: str)**: Get a specific component by name. - **get_components()**: Get all components of the template. - **validate_params()**: Validate the parameters of the template. ``` -------------------------------- ### Get Flow Details Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/flows/overview.rst Retrieves the details of a specific flow using its ID. Useful for inspecting flow configurations. ```python flow = wa.get_flow(created.id) print(flow) ``` -------------------------------- ### Initialize WhatsApp Client Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/examples/sign_up_flow.rst Initialize the WhatsApp client with necessary credentials and configuration for sending and receiving messages and handling webhooks. ```python from pywa import WhatsApp wa = WhatsApp( phone_id="1234567890", token="abcdefg", callback_url="https://my-server.com", webhook_endpoint="/webhook", verify_token="xyz123", app_id=123, app_secret="zzz", business_private_key=open("private.pem").read(), business_private_key_password="abc123", ) ``` -------------------------------- ### Call Management Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/client/overview.rst Methods for managing calls, including getting permissions, pre-accepting, accepting, rejecting, and terminating calls. ```APIDOC ## Calls ### Description Methods for managing calls, including retrieving call permissions, pre-accepting, accepting, rejecting, and terminating calls. ### Methods - `:meth:`~WhatsApp.get_call_permissions`: Get call permissions - `:meth:`~WhatsApp.pre_accept_call`: Pre-accept a call - `:meth:`~WhatsApp.accept_call`: Accept a call - `:meth:`~WhatsApp.reject_call`: Reject a call - `:meth:`~WhatsApp.terminate_call`: Terminate a call ``` -------------------------------- ### User Sign-up Flow Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/flows/overview.rst Handles user sign-up by validating password strength and matching confirmation, then adding the user to the database and redirecting to the sign-in screen. ```python @handle_signin_flow.on_data_exchange(screen=signup_screen) def on_sign_up(_: WhatsApp, req: FlowRequest) -> FlowResponse: if not re.match(r"^(?=.*\d)(?=.*[^A-Za-z0-9]).{8,}$", req.data["password"]): return req.respond( screen=signup_screen, error_message="Password must be at least 8 characters long and contain at least one number and one special character.", ) if req.data["password"] != req.data["confirm_password"]: return req.respond( screen=signup_screen, error_message="Passwords do not match. Please try again.", ) user = User( email=req.data["email"], password=req.data["password"], first_name=req.data["first_name"], last_name=req.data["last_name"], offer_acceptance=req.data["offers_acceptance"], is_signed_in=False ) db.add_user(user) return req.respond( screen=signin_screen, data={ welcome.key: "Thank you for signing up! You can now sign in with your new account.", default_email.key: user.email, }, ) ``` -------------------------------- ### v2.1 Python Flow Examples Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/examples/flows.rst Python code for WhatsApp Business API v2.1 flows. Found in the tests/data/flows directory. ```python from pywa.utils import WhatsAppMessage def get_flow_message_v2_1() -> WhatsAppMessage: """Get a v2.1 flow message.""" return WhatsAppMessage( type="interactive", interactive={ "type": "flow", "flow": { "name": "123456789012345", "parameters": [ { "name": "flow_token", "value": "flow_token_value" }, { "name": "flow_message", "value": "flow_message_value" }, { "name": "flow_json_payload", "value": { "key1": "value1", "key2": "value2" } } ] } } ) ``` -------------------------------- ### Run Tests Source: https://github.com/david-lev/pywa/blob/master/CONTRIBUTING.md Execute the test suite to verify that the project is functioning correctly. ```bash pytest ``` -------------------------------- ### v4.0 Python Flow Examples Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/examples/flows.rst Python code for WhatsApp Business API v4.0 flows. Found in the tests/data/flows directory. ```python from pywa.utils import WhatsAppMessage def get_flow_message_v4_0() -> WhatsAppMessage: """Get a v4.0 flow message.""" return WhatsAppMessage( type="interactive", interactive={ "type": "flow", "flow": { "name": "123456789012345", "parameters": [ { "name": "flow_token", "value": "flow_token_value" }, { "name": "flow_message", "value": "flow_message_value" }, { "name": "flow_json_payload", "value": { "key1": "value1", "key2": "value2" } } ] } } ) ``` -------------------------------- ### Sign Up: Submit and navigate to Login Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/examples/sign_up_flow.rst This snippet handles the final submission of the sign-up form after all validations pass. It creates the user and navigates to the LOGIN screen with the email pre-filled. ```python @on_sign_up_request.on(action=FlowRequestActionType.DATA_EXCHANGE, screen="SIGN_UP") def submit_signup(_: WhatsApp, request: FlowRequest) -> FlowResponse | None: user_repository.create(request.data["email"], request.data) return FlowResponse( version=request.version, screen="LOGIN", data={ "email_initial_value": request.data["email"], "password_initial_value": "", }, ) ``` -------------------------------- ### v5.0 Python Flow Examples Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/examples/flows.rst Python code for WhatsApp Business API v5.0 flows. Found in the tests/data/flows directory. ```python from pywa.utils import WhatsAppMessage def get_flow_message_v5_0() -> WhatsAppMessage: """Get a v5.0 flow message.""" return WhatsAppMessage( type="interactive", interactive={ "type": "flow", "flow": { "name": "123456789012345", "parameters": [ { "name": "flow_token", "value": "flow_token_value" }, { "name": "flow_message", "value": "flow_message_value" }, { "name": "flow_json_payload", "value": { "key1": "value1", "key2": "value2" } } ] } } ) ``` -------------------------------- ### v6.0 Python Flow Examples Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/examples/flows.rst Python code for WhatsApp Business API v6.0 flows. Found in the tests/data/flows directory. ```python from pywa.utils import WhatsAppMessage def get_flow_message_v6_0() -> WhatsAppMessage: """Get a v6.0 flow message.""" return WhatsAppMessage( type="interactive", interactive={ "type": "flow", "flow": { "name": "123456789012345", "parameters": [ { "name": "flow_token", "value": "flow_token_value" }, { "name": "flow_message", "value": "flow_message_value" }, { "name": "flow_json_payload", "value": { "key1": "value1", "key2": "value2" } } ] } } ) ``` -------------------------------- ### Create Template from Library with Parameters Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/templates/overview.rst Create a template from the library that requires parameters. Provide parameter definitions, such as URL button inputs, to customize the template. ```python from pywa import WhatsApp from pywa.types.templates import * wa = WhatsApp(waba_id=..., token=...) # Define the template with parameters order_update = LibraryTemplate( name="order_update", library_template_name="order_update_1", category=TemplateCategory.UTILITY, language=TemplateLanguage.ENGLISH_US, library_template_button_inputs=[ URLButton.library_input( base_url="https://www.example.com/track-order/{{1}}", url_suffix_example="https://www.example.com/track-order/12345", ), ] ) # Create the template wa.create_template(order_update) # CreatedTemplate(id='...', category=TemplateCategory.UTILITY, status=TemplateStatus.PENDING) ``` -------------------------------- ### v6.1 Python Flow Examples Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/examples/flows.rst Python code for WhatsApp Business API v6.1 flows. Found in the tests/data/flows directory. ```python from pywa.utils import WhatsAppMessage def get_flow_message_v6_1() -> WhatsAppMessage: """Get a v6.1 flow message.""" return WhatsAppMessage( type="interactive", interactive={ "type": "flow", "flow": { "name": "123456789012345", "parameters": [ { "name": "flow_token", "value": "flow_token_value" }, { "name": "flow_message", "value": "flow_message_value" }, { "name": "flow_json_payload", "value": { "key1": "value1", "key2": "value2" } } ] } } ) ``` -------------------------------- ### v6.2 Python Flow Examples Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/examples/flows.rst Python code for WhatsApp Business API v6.2 flows. Found in the tests/data/flows directory. ```python from pywa.utils import WhatsAppMessage def get_flow_message_v6_2() -> WhatsAppMessage: """Get a v6.2 flow message.""" return WhatsAppMessage( type="interactive", interactive={ "type": "flow", "flow": { "name": "123456789012345", "parameters": [ { "name": "flow_token", "value": "flow_token_value" }, { "name": "flow_message", "value": "flow_message_value" }, { "name": "flow_json_payload", "value": { "key1": "value1", "key2": "value2" } } ] } } ) ``` -------------------------------- ### v6.3 Python Flow Examples Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/examples/flows.rst Python code for WhatsApp Business API v6.3 flows. Found in the tests/data/flows directory. ```python from pywa.utils import WhatsAppMessage def get_flow_message_v6_3() -> WhatsAppMessage: """Get a v6.3 flow message.""" return WhatsAppMessage( type="interactive", interactive={ "type": "flow", "flow": { "name": "123456789012345", "parameters": [ { "name": "flow_token", "value": "flow_token_value" }, { "name": "flow_message", "value": "flow_message_value" }, { "name": "flow_json_payload", "value": { "key1": "value1", "key2": "value2" } } ] } } ) ``` -------------------------------- ### v7.1 Python Flow Examples Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/examples/flows.rst Python code for WhatsApp Business API v7.1 flows. Found in the tests/data/flows directory. ```python from pywa.utils import WhatsAppMessage def get_flow_message_v7_1() -> WhatsAppMessage: """Get a v7.1 flow message.""" return WhatsAppMessage( type="interactive", interactive={ "type": "flow", "flow": { "name": "123456789012345", "parameters": [ { "name": "flow_token", "value": "flow_token_value" }, { "name": "flow_message", "value": "flow_message_value" }, { "name": "flow_json_payload", "value": { "key1": "value1", "key2": "value2" } } ] } } ) ``` -------------------------------- ### Enabling Handler Continuation Source: https://github.com/david-lev/pywa/blob/master/MIGRATION.md Shows how to set `continue_handling=True` during WhatsApp instance creation to allow an update to be processed by subsequent handlers. ```python from pywa import WhatsApp wa = WhatsApp(..., continue_handling=True) ``` -------------------------------- ### Create WhatsApp Template Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/templates/overview.rst Demonstrates how to use the `create_template` method from the PyWa client to register a defined template with WhatsApp. ```python from pywa import WhatsApp ``` -------------------------------- ### Get All Flows Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/flows/overview.rst Retrieves a list of all available flows associated with the WhatsApp Business account. Useful for managing multiple flows. ```python flows = wa.get_flows() for flow in flows: print(flow) ``` -------------------------------- ### Manual Webhook Verification Route Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/handlers/overview.rst Implement a GET route for webhook verification using `wa.webhook_challenge_handler` to handle the verification challenge from WhatsApp. ```python challenge, status = wa.webhook_challenge_handler( vt=request.GET[utils.HUB_VT], ch=request.GET[utils.HUB_CH], ) return challenge, status ``` -------------------------------- ### Loading Handlers from a Module (Class Registration) Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/handlers/overview.rst Illustrates how to register handlers on the WhatsApp class itself, allowing them to be loaded from separate modules. This is useful when handlers do not have direct access to a client instance during definition. ```python from pywa import WhatsApp, filters, types @WhatsApp.on_message(filters.text) # Register on the class, not an instance def handle_text(client: WhatsApp, msg: types.Message): msg.reply(msg.text) ``` -------------------------------- ### v7.1 JSON Flow Example Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/examples/flows.rst JSON payload for a v7.1 WhatsApp Business API flow message. Used in conjunction with Python code. ```json { "type": "interactive", "interactive": { "type": "flow", "flow": { "name": "123456789012345", "parameters": [ { "name": "flow_token", "value": "flow_token_value" }, { "name": "flow_message", "value": "flow_message_value" }, { "name": "flow_json_payload", "value": { "key1": "value1", "key2": "value2" } } ] } } } ``` -------------------------------- ### Synchronous Client Initialization Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/client/overview.rst Initialize a synchronous WhatsApp client. This is used for handling messages and events in a blocking manner. ```python from pywa import WhatsApp, types wa = WhatsApp(...) @wa.on_message def on_message(_: WhatsApp, msg: types.Message): msg.reply("Hello!") ``` -------------------------------- ### Update Template Creation and Sending Source: https://github.com/david-lev/pywa/blob/master/MIGRATION.md Illustrates the changes in creating and sending templates, including parameter formatting and component structure. ```python ########################## OLD CODE ########################## 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"), ], ), ) ########################## NEW CODE ########################## from pywa import WhatsApp from pywa.types.templates import * # Create a WhatsApp client wa = WhatsApp(..., business_account_id=123456) wa.create_template( template=Template( name="buy_new_iphone_x", category=TemplateCategory.MARKETING, language=TemplateLanguage.ENGLISH_US, parameter_format=ParamFormat.NAMED, components=[ ht := HeaderText("The New iPhone {{iphone_num}} is here!", iphone_num=15), bt := BodyText("Buy now and use the code {{code}} to get {{per}}% off!", code="WA_IPHONE_15", per=15), FooterText(text="Powered by PyWa"), Buttons( buttons=[ url := URLButton(text="Buy Now", url="https://example.com/shop/{{1}}", example="iphone15"), PhoneNumberButton(text="Call Us", phone_number="1234567890"), qrb1 := QuickReplyButton(text="Unsubscribe from marketing messages"), qrb2 := QuickReplyButton(text="Unsubscribe from all messages"), ] ), ] ), ) # Send the template message wa.send_template( to="9876543210", name="buy_new_iphone_x", language=TemplateLanguage.ENGLISH_US, params=[ ht.params(iphone_num=30), bt.params(code="WA_IPHONE_30", per=30), url.params(url_variable="iphone30", index=0), qrb1.params(callback_data="unsubscribe_from_marketing_messages", index=1), qrb2.params(callback_data="unsubscribe_from_all_messages", index=2), ] ) ``` -------------------------------- ### Run Pywa Development Server Source: https://github.com/david-lev/pywa/blob/master/MIGRATION.md Commands to run the Pywa development server for testing and deployment. ```bash pywa dev pywa run ``` -------------------------------- ### Simplifying Match Filters Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/filters/overview.rst Illustrates how to use multiple arguments with match-filters like `matches` to achieve the same result as multiple OR conditions. ```python filters.matches("hello", "hi") ``` -------------------------------- ### Project Structure Overview Source: https://github.com/david-lev/pywa/blob/master/CONTRIBUTING.md This bash snippet displays the directory structure of the pywa project, illustrating the organization of modules and packages. ```bash pywa/ โ”œโ”€โ”€ __init__.py โ”œโ”€โ”€ _helpers.py โ”œโ”€โ”€ api.py โ”œโ”€โ”€ client.py โ”œโ”€โ”€ errors.py โ”œโ”€โ”€ filters.py โ”œโ”€โ”€ handlers.py โ”œโ”€โ”€ listeners.py โ”œโ”€โ”€ server.py โ”œโ”€โ”€ types โ”‚ย ย  โ”œโ”€โ”€ __init__.py โ”‚ย ย  โ”œโ”€โ”€ base_update.py โ”‚ย ย  โ”œโ”€โ”€ callback.py โ”‚ย ย  โ”œโ”€โ”€ chat_opened.py โ”‚ย ย  โ”œโ”€โ”€ flows.py โ”‚ย ย  โ”œโ”€โ”€ media.py โ”‚ย ย  โ”œโ”€โ”€ message.py โ”‚ย ย  โ”œโ”€โ”€ message_status.py โ”‚ย ย  โ”œโ”€โ”€ others.py โ”‚ย ย  โ”œโ”€โ”€ sent_message.py โ”‚ย ย  โ””โ”€โ”€ templates.py โ””โ”€โ”€ utils.py ``` -------------------------------- ### Listen to Sign Up Flow Requests Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/examples/sign_up_flow.rst Sets up a callback function to listen for incoming flow requests on a specific endpoint. The callback handles FlowRequest objects and returns FlowResponse. ```python from pywa.types.flows import FlowRequest, FlowResponse @wa.on_flow_request("/sign-up-flow") def on_sign_up_request(_: WhatsApp, flow: FlowRequest) -> FlowResponse | None: if flow.has_error: logging.error("Flow request has error: %s", flow.data) return ... ``` -------------------------------- ### Waiting for Text Reply with wait_for_reply Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/listeners/overview.rst Use the wait_for_reply shortcut to get a text response from a user after sending a message. This is useful for interactive conversations where you need specific text input. ```python from pywa import WhatsApp, types, filters wa = WhatsApp(...) @wa.on_message(filters.command("start")) def start(client: WhatsApp, msg: types.Message): age = msg.reply("Hello! How old are you?").wait_for_reply(filters.text) msg.reply(f"You are {age.text} years old") ``` -------------------------------- ### Run FastAPI Application Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/handlers/overview.rst After integrating Pywa with FastAPI, run your FastAPI application using the standard command. ```bash fastapi dev main.py ``` -------------------------------- ### Handler Execution with Priority Source: https://github.com/david-lev/pywa/blob/master/docs/source/content/handlers/overview.rst Control the order of handler execution by setting the `priority` parameter. Higher priority numbers run first. This example demonstrates a handler with priority=1 and another with priority=2. ```python from pywa import WhatsApp, types wa = WhatsApp(...) @wa.on_message(priority=1) def first(client: WhatsApp, msg: types.Message): print("First:", msg) @wa.on_message(priority=2) def second(client: WhatsApp, msg: types.Message): print("Second:", msg) ```