{"id":13627614,"url":"https://github.com/t0mer/ma-nish","last_synced_at":"2025-10-09T11:48:17.616Z","repository":{"id":101737254,"uuid":"571191282","full_name":"t0mer/ma-nish","owner":"t0mer","description":"ma-nish is an unofficial python wrapper for Whatsapp cloud api","archived":false,"fork":false,"pushed_at":"2024-12-08T11:38:46.000Z","size":617,"stargazers_count":18,"open_issues_count":4,"forks_count":6,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-30T08:37:41.857Z","etag":null,"topics":["api","fastapi","python","python3","uvicorn","whatsapp","whatsapp-bot"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/t0mer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-11-27T13:17:20.000Z","updated_at":"2025-06-23T15:34:49.000Z","dependencies_parsed_at":"2025-02-20T09:42:47.527Z","dependency_job_id":null,"html_url":"https://github.com/t0mer/ma-nish","commit_stats":{"total_commits":34,"total_committers":3,"mean_commits":"11.333333333333334","dds":0.05882352941176472,"last_synced_commit":"3383c31ce67578fc398abb0ca1b986dd18e925ab"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/t0mer/ma-nish","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/t0mer%2Fma-nish","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/t0mer%2Fma-nish/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/t0mer%2Fma-nish/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/t0mer%2Fma-nish/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/t0mer","download_url":"https://codeload.github.com/t0mer/ma-nish/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/t0mer%2Fma-nish/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279001311,"owners_count":26083059,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-09T02:00:07.460Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","fastapi","python","python3","uvicorn","whatsapp","whatsapp-bot"],"created_at":"2024-08-01T22:00:36.268Z","updated_at":"2025-10-09T11:48:17.584Z","avatar_url":"https://github.com/t0mer.png","language":"Python","funding_links":[],"categories":["Projects by main language"],"sub_categories":["python"],"readme":"# manish\nWhatsApp has now opened up its API so you no longer have to go through a partner to send and receive WhatsApp messages!\nMaNish is an Unofficial python wrapper to [WhatsApp Cloud API](https://developers.facebook.com/docs/whatsapp/cloud-api)\n\n## Features supported\n1. Sending Messages\n2. Sending Media (images, audio, video and documents)\n3. Sending Stickers\n3. Sending Location\n4. Sending Contacts\n5. Sending Buttons\n6. Sending Template messages\n7. Parsing messages and media received (Webhook)\n\n## Components and Frameworks used in manish\n* [Loguru](https://pypi.org/project/loguru/)\n* [Requests ](https://pypi.org/project/requests/)\n* [requests-toolbelt](https://pypi.org/project/requests-toolbelt/)\n* [python-dotenv](https://pypi.org/project/python-dotenv/)\n* [validators](https://pypi.org/project/validators/)\n* [geopy](https://pypi.org/project/geopy/)\n* [Pillow](https://pypi.org/project/Pillow/)\n* [Uvicorn](https://pypi.org/project/uvicorn/)\n* [fastapi](https://pypi.org/project/fastapi/)\n* [jinja2](https://pypi.org/project/Jinja/)\n\n\n## Limitations\n* 1000 free messages per month (Free tier)\n* It is only possible to send messages other than templates after the target phone responds to an initial message (Unless you use Template messages)\n* You can't send message to a group\n\n\n## Getting started\nTo get started with **manish**, you have to firstly install the libary either directly or using *pip*.\n\n### Installation from source\n\nUse git to clone or you can also manually download the project repository just as shown below;\n\n```bash\n$ git clone https://github.com/t0mer/ma-nish/\n$ cd ma-nish\nma-nish $ python setup.py install \n```\n\n### Installing from PyPi\n\n```bash\n# For Windows \n\npip install  --upgrade ma-nish\n\n#For Linux | MAC \n\npip3 install --upgrade ma-nish\n```\n\n\n## Setting up the environment\n### Set Up Meta App\n\nFirst you’ll need to follow the [instructions on this page](https://developers.facebook.com/docs/whatsapp/cloud-api/get-started) to:\n\n* Register as a Meta Developer\n* Enable two-factor authentication for your account\n* Create a Meta App – you need to create a Business App for WhatsApp\n\nOnce you’ve done that, go to your app and set up the WhatsApp product.\n\n[![New app](https://techblog.co.il/wp-content/uploads/2022/12/new-app.png \"New App\")](https://techblog.co.il/wp-content/uploads/2022/12/new-app.png \"New App\")\n\nYou’ll be given a temporary access token and a Phone Number ID, note these down as you’ll need them later. Set up your own phone number as a recipient and you can have a go at sending yourself a test message:\n\n[![Getting started](https://techblog.co.il/wp-content/uploads/2022/12/test-number.png \"Getting started\")](https://techblog.co.il/wp-content/uploads/2022/12/test-number.png \"Getting started\")\n\n### Set Up Message Template\n\nIn the test message above, you used the **hello_world** template. You’ll need to set up your own template for your own purposes. If you go to [“Message Templates”](https://business.facebook.com/wa/manage/message-templates/) in the WhatsApp manager you can build your own templates.\n\nIn the following example, i created a template for my smat home. The template header if fixed and so is the footer. in the body i added variable for dynamic text:\n\n[![Smart Home Template](https://techblog.co.il/wp-content/uploads/2022/12/my-template.png \"Smart Home Template\")](https://techblog.co.il/wp-content/uploads/2022/12/my-template.png \"Smart Home Template\")\n\n\nOnce you're done with the above ,you're ready to start send messages using **manish**.\n\n## Authentication\nBefore you can send messages, you need to authenticate your application using the **```phone_number_id```** and **```Token```** of your test number.\n\n```python\n\u003e\u003e\u003e from manish import MaNish\n\u003e\u003e\u003e manish = MaNish('TOKEN',  phone_number_id='xxxxxxxxxx')\n```\n\nOne your app is authenticated, you can start sending messages.\nAs mentioned above, it is only possible to send messages other than templates after the target phone responds to an initial message.\n\n## Sending Messanges\n\nThis method can be used for sending simple text messages.\n\n```python\n\u003e\u003e\u003e manish.send_message(\n        message='Your message',\n        recipient_id='97250xxxxxxx'\n     )\n```\n***Mobile should include country code without the + symbol***\n\n## Sending Media\nWhen sending media:\n* Images\n* Video\n* Audio\n* Document\n* Gif\n\nYou can either specify:\n* URL for the media.\n* Local file.\n\n## Sending Image\n\n```python\n\u003e\u003e\u003e manish.send_image(\n        image=\"https://i.imgur.com/COXQuEz.jpeg\",\n        recipient_id=\"97250xxxxxxx\",\n    )\n```\n\n## Sending Video\n```python\n\n\u003e\u003e\u003e manish.send_video(\n        video=\"https://user-images.githubusercontent.com/4478920/200173402-8a8343c3-afc2-4341-86ea-c833bed98a9a.mp4\",\n        recipient_id=\"97250xxxxxxx\",\n    )\n```\n\n## Sending Audio\n\n```python\n\u003e\u003e\u003e manish.send_audio(\n        audio=\"https://www.soundhelix.com/examples/mp3/SoundHelix-Song-9.mp3\",\n        recipient_id=\"97250xxxxxxx\",\n    )\n```\n\n## Sending Document\n\n```python\n\u003e\u003e\u003e messenger.send_document(\n        document=\"https://www.africau.edu/images/default/sample.pdf\",\n        recipient_id=\"97250xxxxxxx\",\n    )\n```\n\n## Sending Sticker\nCloud API: Static and animated third-party outbound stickers are supported in addition to all types of inbound stickers. A static sticker needs to be 512x512 pixels and cannot exceed 100 KB. An animated sticker must be 512x512 pixels and cannot exceed 500 KB.\n\nWhen sending from local file, the app will automatically convert the image to the supported format.\n\n\n```python\n\u003e\u003e\u003e manish.send_sticker(\n        image=\"https://i.imgur.com/COXQuEz.webp\",\n        recipient_id=\"97250xxxxxxx\",\n    )\n```\n\n## Sending Location\nThe Location message object requires **longitude** and **latitude**, but you can also send real address and manish will translate the address to coordinates and send thr message.\n\n```python\n\u003e\u003e\u003e from manish.location import *\n\u003e\u003e\u003e location = Location(address=\"10 Hagalil street, raanana\",name=\"Home\")\n\u003e\u003e\u003e manish.send_location(location = location,recipient_id=\"97250xxxxxxx\")\n\n```\n\n## Sending Contact(s)\n```python\n\u003e\u003e\u003e from manish.contact import *\n\u003e\u003e\u003e phones = [Phone(phone=\"97250xxxxxxx\",type=\"CELL\")]\n\u003e\u003e\u003e name = Name(formatted_name=\"Tomer Klein\", first_name=\"Tomer\", last_name=\"Klein\")\n\u003e\u003e\u003e addresses = [Address(street=\"Hagalil 10\", city=\"Raanana\", zip =\"123456\", country=\"Israel\")]\n\u003e\u003e\u003e emails = [Email(\"jhon.c@gmail.com\")]\n\u003e\u003e\u003e contact = Contact(name=name,addresses=addresses,emails=emails,phones=phones)\n\u003e\u003e\u003e data = ContactEncoder().encode([contact])\n\u003e\u003e\u003e manish.send_contacts(data,\"97250xxxxxxx\")\n\n```\n\n## Sending Button(s)\n```python\n\u003e\u003e\u003e from manish.button import *\n\u003e\u003e\u003e rows = []\n\u003e\u003e\u003e rows.append(Row(\"row 1\",\"Send Mony\",\"\"))\n\u003e\u003e\u003e rows.append(Row(\"row 2\",\"Withdraw Mony\",\"\"))\n\u003e\u003e\u003e sections = []\n\u003e\u003e\u003e sections.append(Section(\"iBank\",rows))\n\u003e\u003e\u003e action = Action(\"Button Testing\",sections)\n\u003e\u003e\u003e button = Button(\"Header Testing\", \"Body Testing\", \"Footer Testing\",action)\n\u003e\u003e\u003e data = ButtonEncoder().encode(button)\n\u003e\u003e\u003e manish.send_button(data,\"97250xxxxxxx\")\n```\n\n## Sending Template Messages\nThis method allows you to send template based messages (and bypass the limitation of the ability to send message outside the 24 hours window).\n\nTemplate messages can either be:\n* Text Template (Can also include currency object)\n* Media Template (Same as Text but with media in the header)\n\n### Sending simple text template\n```python\n\u003e\u003e\u003e from manish.template import *\n\u003e\u003e\u003e def send_template():\n\u003e\u003e\u003e parameter = Parameter(type=\"text\",text = \"Your Text Message\")\n\u003e\u003e\u003e parameters = []\n\u003e\u003e\u003e parameters.append(parameter)\n\u003e\u003e\u003e body = Component(type=\"body\",parameters=[parameter])\n\u003e\u003e\u003e manish.send_template(components=TemplateEncoder().encode([body]),recipient_id=\"97250xxxxxxx\",template=\"smart_home_media\",lang=\"he\")\n```\n\n### Sending media template\n**Media can only be attached to the header!**\n```python\n\u003e\u003e\u003e parameter = Parameter(type=\"text\",text = \"Your Text Message\")\n\u003e\u003e\u003e img = Media(link=\"https://raw.githubusercontent.com/t0mer/broadlinkmanager-docker/master/screenshots/Devices%20List.png\")\n\u003e\u003e\u003e iparam = MediaParameter(type=\"image\",image=img)\n\u003e\u003e\u003e parameters = []\n\u003e\u003e\u003e parameters.append(parameter)\n\u003e\u003e\u003e body = Component(type=\"body\",parameters=[parameter])\n\u003e\u003e\u003e header = Component(type=\"header\",parameters=[iparam])\n\u003e\u003e\u003e manish.send_template(components=TemplateEncoder().encode([body,header]),recipient_id=\"97250xxxxxxx\",template=\"smart_home_media\",lang=\"he\")\n```\n\n## Webhook\nWell, untill now you were only able to send messages. but what if you need to respond to incoming messages?\nSo i created [webhook](https://github.com/t0mer/ma-nish/blob/main/webhook.py) using [FastAPI](https://fastapi.tiangolo.com/). Feel free to customize and change it to fit your needs.\n\nWith this webhook you can:\n* **Verify webhook** (Whatsapp cloud api require webhook token verification)\n* **Get Senders Mobile Number**\n* **Get Message Text from sender**\n* **Get Location sent by sender**\n* **Get Media (Image, Video, Audio, Document, File) sent by user**\n* **Get Delivery status**\n\n### Verify token example\n```python\n\u003e\u003e\u003e @app.get(\"/\", include_in_schema=False)\n\u003e\u003e\u003e async def verify(request: Request):\n\u003e\u003e\u003e    if request.query_params.get('hub.mode') == \"subscribe\" and request.query_params.get(\"hub.challenge\"):\n\u003e\u003e\u003e        if not request.query_params.get('hub.verify_token') == VERIFY_TOKEN: #os.environ[\"VERIFY_TOKEN\"]:\n\u003e\u003e\u003e            return \"Verification token mismatch\", 403\n\u003e\u003e\u003e        return int(request.query_params.get('hub.challenge'))\n\u003e\u003e\u003e    return \"Hello world\", 200\n```\n\n\n\n### Webhook usage example\n```python\n\u003e\u003e\u003e @app.post(\"/\", include_in_schema=False)\n\u003e\u003e\u003e async def webhook(request: Request):\n\u003e\u003e\u003e     data = await request.json()\n\u003e\u003e\u003e     changed_field = manish.changed_field(data)\n\u003e\u003e\u003e     if changed_field == \"messages\":\n\u003e\u003e\u003e         new_message = manish.get_mobile(data)\n\u003e\u003e\u003e         if new_message:\n\u003e\u003e\u003e             mobile = manish.get_mobile(data)\n\u003e\u003e\u003e             name = manish.get_name(data)\n\u003e\u003e\u003e             message_type = manish.get_message_type(data)\n\u003e\u003e\u003e             logger.info(\n\u003e\u003e\u003e                 f\"New Message; sender:{mobile} name:{name} type:{message_type}\"\n\u003e\u003e\u003e             )\n\u003e\u003e\u003e             if message_type == \"text\":\n\u003e\u003e\u003e                 message = manish.get_message(data)\n\u003e\u003e\u003e                 name = manish.get_name(data)\n\u003e\u003e\u003e                 logger.info(\"Message: %s\", message)\n\u003e\u003e\u003e                 manish.send_message(f\"Hi {name}, nice to connect with you\", mobile)\n\u003e\u003e\u003e             elif message_type == \"interactive\":\n\u003e\u003e\u003e                 message_response = manish.get_interactive_response(data)\n\u003e\u003e\u003e                 intractive_type = message_response.get(\"type\")\n\u003e\u003e\u003e                 message_id = message_response[intractive_type][\"id\"]\n\u003e\u003e\u003e                 message_text = message_response[intractive_type][\"title\"]\n\u003e\u003e\u003e                 logger.info(f\"Interactive Message; {message_id}: {message_text}\")\n\u003e\u003e\u003e             elif message_type == \"location\":\n\u003e\u003e\u003e                 message_location = manish.get_location(data)\n\u003e\u003e\u003e                 message_latitude = message_location[\"latitude\"]\n\u003e\u003e\u003e                 message_longitude = message_location[\"longitude\"]\n\u003e\u003e\u003e                 logger.info(\"Location: %s, %s\", message_latitude, message_longitude)\n\u003e\u003e\u003e             elif message_type == \"image\":\n\u003e\u003e\u003e                 image = manish.get_image(data)\n\u003e\u003e\u003e                 image_id, mime_type = image[\"id\"], image[\"mime_type\"]\n\u003e\u003e\u003e                 image_url = manish.query_media_url(image_id)\n\u003e\u003e\u003e                 image_filename = manish.download_media(image_url, mime_type)\n\u003e\u003e\u003e                 logger.info(f\"{mobile} sent image {image_filename}\")\n\u003e\u003e\u003e             elif message_type == \"video\":\n\u003e\u003e\u003e                 video = manish.get_video(data)\n\u003e\u003e\u003e                 video_id, mime_type = video[\"id\"], video[\"mime_type\"]\n\u003e\u003e\u003e                 video_url = manish.query_media_url(video_id)\n\u003e\u003e\u003e                 video_filename = manish.download_media(video_url, mime_type)\n\u003e\u003e\u003e                 logger.info(f\"{mobile} sent video {video_filename}\")\n\u003e\u003e\u003e             elif message_type == \"audio\":\n\u003e\u003e\u003e                 audio = manish.get_audio(data)\n\u003e\u003e\u003e                 audio_id, mime_type = audio[\"id\"], audio[\"mime_type\"]\n\u003e\u003e\u003e                 audio_url = manish.query_media_url(audio_id)\n\u003e\u003e\u003e                 audio_filename = manish.download_media(audio_url, mime_type)\n\u003e\u003e\u003e                 logger.info(f\"{mobile} sent audio {audio_filename}\")\n\u003e\u003e\u003e             elif message_type == \"file\":\n\u003e\u003e\u003e                 file = manish.get_file(data)\n\u003e\u003e\u003e                 file_id, mime_type = file[\"id\"], file[\"mime_type\"]\n\u003e\u003e\u003e                 file_url = manish.query_media_url(file_id)\n\u003e\u003e\u003e                 file_filename = manish.download_media(file_url, mime_type)\n\u003e\u003e\u003e                 logger.info(f\"{mobile} sent file {file_filename}\")\n\u003e\u003e\u003e             else:\n\u003e\u003e\u003e                 logger.info(f\"{mobile} sent {message_type} \")\n\u003e\u003e\u003e                 logger.info(data)\n\u003e\u003e\u003e         else:\n\u003e\u003e\u003e             delivery = manish.get_delivery(data)\n\u003e\u003e\u003e             if delivery:\n\u003e\u003e\u003e                 logger.info(f\"Message : {delivery}\")\n\u003e\u003e\u003e             else:\n\u003e\u003e\u003e                 logger.info(\"No new message\")\n\u003e\u003e\u003e     return \"ok\"\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ft0mer%2Fma-nish","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ft0mer%2Fma-nish","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ft0mer%2Fma-nish/lists"}