{"id":13764389,"url":"https://github.com/hpreston/webexteamsbot","last_synced_at":"2026-03-08T02:05:36.981Z","repository":{"id":39007387,"uuid":"157026180","full_name":"hpreston/webexteamsbot","owner":"hpreston","description":"Python package for creating Webex Teams chat bots. ","archived":false,"fork":false,"pushed_at":"2022-12-26T20:46:37.000Z","size":235,"stargazers_count":51,"open_issues_count":12,"forks_count":33,"subscribers_count":12,"default_branch":"master","last_synced_at":"2024-04-30T18:31:46.665Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/hpreston.png","metadata":{"files":{"readme":"README.md","changelog":"HISTORY.md","contributing":"CONTRIBUTING.rst","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-11-10T22:13:34.000Z","updated_at":"2024-02-22T18:05:08.000Z","dependencies_parsed_at":"2023-01-31T01:31:08.239Z","dependency_job_id":null,"html_url":"https://github.com/hpreston/webexteamsbot","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hpreston%2Fwebexteamsbot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hpreston%2Fwebexteamsbot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hpreston%2Fwebexteamsbot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hpreston%2Fwebexteamsbot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hpreston","download_url":"https://codeload.github.com/hpreston/webexteamsbot/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230507051,"owners_count":18236944,"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","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":[],"created_at":"2024-08-03T16:00:19.884Z","updated_at":"2026-03-08T02:05:31.939Z","avatar_url":"https://github.com/hpreston.png","language":"Python","funding_links":[],"categories":["Bot frameworks"],"sub_categories":[],"readme":"# webexteamsbot\n\nThis package makes creating [Webex Teams](https://www.webex.com/products/teams/index.html) bots in Python super simple.  \n\n[![PyPI version](https://badge.fury.io/py/webexteamsbot.svg)](https://badge.fury.io/py/webexteamsbot) [![published](https://static.production.devnetcloud.com/codeexchange/assets/images/devnet-published.svg)](https://developer.cisco.com/codeexchange/github/repo/hpreston/webexteamsbot)\n\n\u003e This package is based on the previous [ciscosparkbot](https://github.com/imapex/ciscosparkbot) project.  This version will both move to new Webex Teams branding as well as add new functionality.  If you've used `ciscosparkbot` you will find this package very similar and familiar.  \n\n# Prerequisites\n\nIf you don't already have a [Webex Teams](https://www.webex.com/products/teams/index.html) account, go ahead and [register](https://www.webex.com/pricing/free-trial.html) for one.  They are free.\n\n1. You'll need to start by adding your bot to the Webex Teams website.\n\n    [https://developer.webex.com/my-apps](https://developer.webex.com/my-apps)\n\n1. Click **Create a New App**\n\n    ![add-app](https://github.com/hpreston/webexteamsbot/raw/master/images/newapp.jpg)\n\n1. Click **Create a Bot**.\n\n    ![create-bot](https://github.com/hpreston/webexteamsbot/raw/master/images/createbot.jpg)\n\n2. Fill out all the details about your bot.  You'll need to set a name, username, icon (either upload one or choose a sample), and provide a description.\n\n    ![add-bot](https://github.com/hpreston/webexteamsbot/raw/master/images/newbot.jpg)\n\n3. Click **Add Bot**.\n\n1. On the Congratulations screen, make sure to copy the *Bot's Access Token*, you will need this in a second.\n\n    ![enter-details](https://github.com/hpreston/webexteamsbot/raw/master/images/botcongrats.jpg)\n\n# Installation\n\n\u003e Python 3.6+ is recommended.  Python 2.7 should also work.  \n\n1. Create a virtualenv and install the module\n\n    ```\n    python3.6 -m venv venv\n    source venv/bin/activate\n    pip install webexteamsbot\n    ```\n\n# Usage\n\n1. The easiest way to use this module is to set a few environment variables\n\n    \u003e Note: See [ngrok](#ngrok) for details on setting up an easy HTTP tunnel for development.\n\n    ```\n    export TEAMS_BOT_URL=https://mypublicsite.io\n    export TEAMS_BOT_TOKEN=\u003cyour bots token\u003e\n    export TEAMS_BOT_EMAIL=\u003cyour bots email\u003e\n    export TEAMS_BOT_APP_NAME=\u003cyour bots name\u003e\n    ```\n\n1. A basic bot requires very little code to get going.  \n\n    ```python\n    import os\n    from webexteamsbot import TeamsBot\n\n    # Retrieve required details from environment variables\n    bot_email = os.getenv(\"TEAMS_BOT_EMAIL\")\n    teams_token = os.getenv(\"TEAMS_BOT_TOKEN\")\n    bot_url = os.getenv(\"TEAMS_BOT_URL\")\n    bot_app_name = os.getenv(\"TEAMS_BOT_APP_NAME\")\n\n    # Create a Bot Object\n    bot = TeamsBot(\n        bot_app_name,\n        teams_bot_token=teams_token,\n        teams_bot_url=bot_url,\n        teams_bot_email=bot_email,\n    )\n\n\n    # A simple command that returns a basic string that will be sent as a reply\n    def do_something(incoming_msg):\n        \"\"\"\n        Sample function to do some action.\n        :param incoming_msg: The incoming message object from Teams\n        :return: A text or markdown based reply\n        \"\"\"\n        return \"i did what you said - {}\".format(incoming_msg.text)\n\n\n    # Add new commands to the box.\n    bot.add_command(\"/dosomething\", \"help for do something\", do_something)\n\n\n    if __name__ == \"__main__\":\n        # Run Bot\n        bot.run(host=\"0.0.0.0\", port=5000)\n    ```\n\n1. A [sample script](https://github.com/hpreston/webexteamsbot/blob/master/sample.py) that shows more advanced bot features and customization is also provided in the repo.  \n\n## Advanced Options\n### Changing the Help Message\n1. Although \"set_greeting\" has existed for a while now, you may mostly like the internal greeting mechanism, but only want to change the help banner itself. You can do that with the \"set_help_message\" command like this:\n    ```python\n    bot.set_help_message(\"Welcome to the Super Cool Bot! You can use the following commands:\\n\")\n    ```\n### Working with events other than created messages\n1. By default, the bot will configure the webhook to listen for messages:created events. This behavior can be changed using the \"webhook_resource\" and \"webhook_event\" parameters. So, for example, if you wish for the bot to monitor any changes to a room's membership list, you would instanciate the bot like this:\n    ```python\n    # Create a Bot Object\n    bot = TeamsBot(\n        bot_app_name,\n        teams_bot_token=teams_token,\n        teams_bot_url=bot_url,\n        teams_bot_email=bot_email,\n        webhook_resource=\"memberships\",\n        webhook_event=\"all\",\n    )\n    ```\n\n    You also need a way to catch anything other than \"messages\", which is the only thing handled entirely inside the bot framework. Continuing the example of monitoring for membership changes in a room, you would also need to add a \"command\" to catch the membership events. You would use the following to do so:\n    ```python\n    # check membership:all webhook to verify that person added to room (or otherwise modified) is allowed to be in the room \n    def check_memberships(api, incoming_msg):\n        wl_dom = os.getenv(\"WHITELIST_DOMAINS\")\n        if wl_dom.find(\"[\") \u003c 0:\n            wl_dom = '[\"' + wl_dom + '\"]'\n            wl_dom = wl_dom.replace(\",\", '\",\"')\n    \n        if wl_dom and incoming_msg[\"event\"] != \"deleted\":\n            pemail = incoming_msg[\"data\"][\"personEmail\"]\n            pid = incoming_msg[\"data\"][\"personId\"]\n            pdom = pemail.split(\"@\")[1]\n            plist = json.loads(wl_dom)\n            print(pemail, pdom, plist)\n            if pdom in plist or pemail == bot_email:\n                # membership check succeeded\n                return \"\"\n            else:\n                # membership check failed\n                print(\"membership failed. deleting \" + incoming_msg[\"data\"][\"id\"])\n                api.memberships.delete(incoming_msg[\"data\"][\"id\"])\n                api.messages.create(toPersonId=pid, markdown=\"You were automatically removed from the space because \"\n                                            \"it is restricted to employees.\")\n                return \"'\" + pemail + \"' was automatically removed from this space; it is restricted to only \" \\\n                                        \"internal users.\"\n    \n        return \"\"\n    \n    ###### \n    \n    bot.add_command('memberships', '*', check_memberships)\n    ```\n    The first argument, \"memberships\", tells the bot to look for resources of the type \"memberships\", the second argument \"*\" instructs the bot that this is not something that should be included in the internal \"help\" command, and the third command is the function to execute to handle the membership creation.\n\n1. The bot can also be configured to listen for multiple different events. So, for example, if you wish for the bot to monitor not only new messages in a room, but also any card actions in a room, you would instanciate the bot like this:\n    ```python\n    # Create a Bot Object\n    bot = TeamsBot(\n        bot_app_name,\n        teams_bot_token=teams_token,\n        teams_bot_url=bot_url,\n        teams_bot_email=bot_email,\n        webhook_resource_event=[{\"resource\": \"messages\", \"event\": \"created\"},\n                                {\"resource\": \"attachmentActions\", \"event\": \"created\"}]\n    )\n    ```\n    Once again, You also need a way to catch anything other than \"messages\". Continuing the example of monitoring card actions, you would also need to add a \"command\" to catch the card actions. You would use the following to do so:\n    ```python\n    # API request to get card actions (not currently covered in webexteamssdk==1.2)\n    def get_attachment_actions(attachmentid):\n        headers = {\n            'content-type': 'application/json; charset=utf-8',\n            'authorization': 'Bearer ' + teams_token\n        }\n    \n        url = 'https://api.ciscospark.com/v1/attachment/actions/' + attachmentid\n        response = requests.get(url, headers=headers)\n        return response.json()\n\n    # check attachmentActions:created webhook to handle any card actions \n    def handle_cards(api, incoming_msg):\n        m = get_attachment_actions(incoming_msg[\"data\"][\"id\"])\n        print(m)\n            \n        return m[\"inputs\"]\n    \n    ###### \n    \n    bot.add_command('attachmentActions', '*', handle_cards)\n    ```\n    The first argument, \"attachmentActions\", tells the bot to look for resources of the type \"attachmentActions\", the second argument \"*\" instructs the bot that this is not something that should be included in the internal \"help\" command, and the third command is the function to execute to handle the card action.\n\n### Creating arbitrary HTTP Endpoints/URLs \n1. You can also add a new path to Flask by using the \"add_new_url\" command. You can use this so that the bot can handle things other than Webex Teams Webhooks. For example, if you wanted to receive other webhooks to the \"/webhooks\" path, you would use this:\n    ```python\n    def handle_webhooks():\n        try:\n            webhook_event = json.loads(request.data.decode(\"UTF-8\"))\n        except:\n            return \"\"\n        netid = webhook_event[\"networkId\"]\n        print(netid)\n\n    ###### \n\n    bot.add_new_url(\"/webhooks\", \"webhooks\", handle_webhooks)\n    ```\n    The first argument, \"/webhooks\", represents the URL path to listen for, the second argument represents the Flask endpoint, and the third command is the function to execute to handle GET, PUT, or POST actions.\n\n### Limiting Who Can Interact with the Bot \n1. By default the bot will reply to any Webex Teams user who talks with it.  But you may want to setup a Bot that only talks to \"approved users\". \n1. Start by creating a list of email addresses of your approved users. \n\n    ```python\n    approved_users = [\n        \"josmith@demo.local\",\n    ]\n    ```\n\n1. Now when creating the bot object, simply add the `approved_users` parameter. \n\n    ```python\n    bot = TeamsBot(\n        bot_app_name,\n        teams_bot_token=teams_token,\n        teams_bot_url=bot_url,\n        teams_bot_email=bot_email,\n        approved_users=approved_users,\n    )\n    ```\n\n1. Now if a users **NOT** listed in the `approved_users` list attempts to communicate with the bot, the message will be ignored and a notification is logged. \n\n    ```\n    Message from: hapresto@cisco.com\n    User: hapresto@cisco.com is not approved to interact with bot. Ignoring.\n    ```\n# Deploy in Cisco Exchange Dev environment\n\nIf you run this project using Cisco Exchange Dev environment\n\n![webexteamsbot-exchange-devenv](https://raw.githubusercontent.com/CiscoDevNet/code-exchange-repo-template/master/manual-sample-repo/img/webexteamsbot-exchange-devenv.png)\n\nOpen a new terminal and run the command to get the external URL:\n\n`echo $DEVENV_APP_9082_URL`\n\nAs output, you will see an external URL for the webhook\n\nFor example\n`https://app-9082-8093942179345178980.devenv-int.ap-ne-1.devnetcloud.com`\n\nUpdate your environment with this url\n\n`export TEAMS_BOT_URL=https://this.is.the.url.you.need`\n\nIn VSCode DevEnv open file `sample.py`\nAt the bottom, in code `bot.run(host=\"0.0.0.0\", port=5000)` change the port from `5000` to `9082`\nHow it should look like: `bot.run(host=\"0.0.0.0\", port=9082)`  \n\nLaunch your bot\n\n```\npython sample.py\n```\n\n# ngrok\n\n[ngrok](http://ngrok.com) will make easy for you to develop your code with a live bot.\n\nYou can find installation instructions here: [https://ngrok.com/download](https://ngrok.com/download)\n\n1. After you've installed `ngrok`, in another window start the service\n\n    ```\n    ngrok http 5000\n    ```\n\n1. You should see a screen that looks like this:\n\n    ```\n    ngrok by @inconshreveable                                                                                                                                 (Ctrl+C to quit)\n\n    Session Status                online\n    Version                       2.2.4\n    Region                        United States (us)\n    Web Interface                 http://127.0.0.1:4040\n    Forwarding                    http://this.is.the.url.you.need -\u003e localhost:5000\n    Forwarding                    https://this.is.the.url.you.need -\u003e localhost:5000\n\n    Connections                   ttl     opn     rt1     rt5     p50     p90\n                                  2       0       0.00    0.00    0.77    1.16\n\n    HTTP Requests\n    -------------\n\n    POST /                         200 OK\n    ```\n\n1. Make sure and update your environment with this url:\n\n    ```\n    export TEAMS_BOT_URL=https://this.is.the.url.you.need\n\n    ```\n\n1. Now launch your bot!!\n\n    ```\n    python sample.py\n    ```\n\n## Local Development\n\nIf you have an idea for a feature you would like to see, we gladly accept pull requests.  To get started developing, simply run the following..\n\n```\ngit clone https://github.com/hpreston/webexteamsbot\ncd webexteamsbot\npip install -r requirements_dev.txt\npython setup.py develop\n```\n\n### Linting\n\nWe use flake 8 to lint our code. Please keep the repository clean by running:\n\n```\nflake8\n```\n\n### Testing\n\nTests are located in the [tests](./tests) directory.\n\nTo run the tests in the `tests` folder, you can run the following command\nfrom the project root.\n\n```\ncoverage run --source=webexteamsbot setup.py test\ncoverage html\n```\n\nThis will generate a code coverage report in a directory called `htmlcov`\n\n# Credits\nThe initial packaging of the original `ciscosparkbot` project was done by [Kevin Corbin](https://github.com/kecorbin).  \n\nThis package was created with\n[Cookiecutter](https://github.com/audreyr/cookiecutter) and the\n[audreyr/cookiecutter-pypackage](https://github.com/audreyr/cookiecutter-pypackage)\nproject template.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhpreston%2Fwebexteamsbot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhpreston%2Fwebexteamsbot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhpreston%2Fwebexteamsbot/lists"}