├── .gitignore ├── CONTRIBUTING.md ├── LICENSE ├── MANIFEST.in ├── README ├── README.md ├── chatbase ├── __init__.py ├── base_message.py ├── facebook_agent_message.py ├── facebook_chatbase_fields.py ├── facebook_user_message.py └── tests │ ├── test_agent_message.py │ ├── test_base_message.py │ └── test_user_message.py └── setup.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.py[cod] 2 | *.sw[op] 3 | 4 | # C extensions 5 | *.so 6 | 7 | # Packages 8 | *.egg 9 | *.egg-info 10 | dist 11 | build 12 | eggs 13 | parts 14 | bin 15 | var 16 | sdist 17 | develop-eggs 18 | .installed.cfg 19 | lib 20 | lib64 21 | __pycache__ 22 | 23 | # Installer logs 24 | pip-log.txt 25 | 26 | # Unit test / coverage reports 27 | .coverage 28 | .nox 29 | .tox 30 | .cache 31 | htmlcov 32 | 33 | # Translations 34 | *.mo 35 | 36 | # Mac 37 | .DS_Store 38 | 39 | # Mr Developer 40 | .mr.developer.cfg 41 | .project 42 | .pydevproject 43 | 44 | # JetBrains 45 | .idea 46 | 47 | # Built documentation 48 | docs/_build 49 | docs/_build_doc2dash 50 | 51 | # Virtual environment 52 | env/ 53 | coverage.xml 54 | 55 | # System test environment variables. 56 | system_tests/local_test_setup 57 | 58 | # Make sure a generated file isn't accidentally committed. 59 | pylintrc 60 | pylintrc.test 61 | 62 | # Directories used for creating generated PB2 files 63 | generated_python/ 64 | cloud-bigtable-client/ 65 | googleapis-pb/ 66 | grpc_python_venv/ 67 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | We'd love to accept your patches and contributions to this project. There are 4 | just a few small guidelines you need to follow. 5 | 6 | ## Contributor License Agreement 7 | 8 | Contributions to this project must be accompanied by a Contributor License 9 | Agreement. You (or your employer) retain the copyright to your contribution, 10 | this simply gives us permission to use and redistribute your contributions as 11 | part of the project. Head over to to see 12 | your current agreements on file or to sign a new one. 13 | 14 | You generally only need to submit a CLA once, so if you've already submitted one 15 | (even if it was for a different project), you probably don't need to do it 16 | again. 17 | 18 | ## Code reviews 19 | 20 | All submissions, including submissions by project members, require review. We 21 | use GitHub pull requests for this purpose. Consult 22 | [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more 23 | information on using pull requests. 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright 2016 Google Inc. 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | # License & Info 2 | include LICENSE 3 | include README -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | # Python Client for Chatbase 2 | ##### A Python library for the [Chatbase API](https://chatbase.com/documentation/ref) 3 | 4 | > This is not an official Google product 5 | 6 | ## Quick Start 7 | 8 | ```SH 9 | $ pip install git+git://github.com/google/chatbase-python.git 10 | ``` 11 | 12 | ## Account Setup 13 | Please see the [Getting Started Section](https://chatbase.com/documentation/quickstart) for information 14 | on configuring one's account and obtaining and API key. 15 | 16 | ## Using the module 17 | 18 | #### One can send individual messages to the Generic and Facebook rest APIs: 19 | 20 | Generic: 21 | 22 | ```PYTHON 23 | from chatbase import Message 24 | 25 | msg = Message(api_key="x", 26 | platform="kik", 27 | version="0.1", 28 | user_id="unique-str", 29 | message="this is a test", 30 | intent="test") 31 | resp = msg.send() 32 | ``` 33 | 34 | Facebook: 35 | 36 | ```PYTHON 37 | from chatbase import FacebookAgentMessage, FacebookUserMessage 38 | 39 | # Agent messages 40 | agnMsg = FacebookAgentMessage(api_key="x", intent="y", version="1", message="a") 41 | # Make sure to set the recipient and message IDs 42 | agnMsg.set_recipient_id("123") 43 | agnMsg.set_message_id("xyz") 44 | resp = agnMsg.send() 45 | 46 | # User messages 47 | usrMsg = FacebookUserMessage(api_key="x", intent="y", version="1", message="a") 48 | # Make sure to set the recipient, sender and message IDs 49 | usrMsg.set_recipient_id("123") 50 | usrMsg.set_sender_id("456") 51 | usrMsg.set_message_id("xyz") 52 | resp = usrMsg.send() 53 | ``` 54 | 55 | #### One can send sets of messages as well to the Generic and Facebook rest APIs: 56 | 57 | Generic: 58 | 59 | 60 | ```PYTHON 61 | from chatbase import MessageSet 62 | 63 | # When we init the message set we can set several properties which will be 64 | # propagated to all message created from the set! 65 | set = MessageSet(api_key="x", platform="x", version="1", user_id="123") 66 | msg = set.new_message(intent="impress", content="goes to 11") 67 | # one can still edit the message normally and these changes will be reflected 68 | # in the containing set 69 | msg.user_id = "shark-sandwich" 70 | # Message type objects can be appended: 71 | msg2 = Message(api_key="x", 72 | platform="my_platform", 73 | version="0.1", 74 | user_id="unique-str", 75 | message="this is a test", 76 | intent="test") 77 | set.append_message(msg2) 78 | # Sending the set will send all contained messages to the batch endpoint 79 | resp = set.send() 80 | ``` 81 | 82 | Facebook: 83 | 84 | ```PYTHON 85 | from chatbase import FacebookAgentMessageSet, FacebookUserMessageSet 86 | 87 | # Agent Message Set 88 | agnSet = FacebookAgentMessageSet(api_key="x", version="y") 89 | msg = agnSet.new_message(intent="a", message="b") 90 | # Don't forget to set the message and recipient ids 91 | msg.set_recipient_id("123") 92 | msg.set_message_id("xyz") 93 | resp = agnSet.send() 94 | 95 | # User Message Set 96 | usrSet = FacebookUserMessageSet(api_key="a", version="b") 97 | msg = usrSet.new_message(intent="c", message="d") 98 | # Don't for get to set the message, recipient and sender ids 99 | msg.set_recipient_id("123") 100 | msg.set_sender_id("456") 101 | msg.set_message_id("xyz") 102 | resp = usrSet.send() 103 | ``` 104 | 105 | #### Tests 106 | Please place tests in `tests` directory. To run tests, from the repository 107 | root run the following command: 108 | 109 | ``` 110 | $ python -m unittest discover ./chatbase/tests/ 111 | ``` 112 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python Client for Chatbase 2 | ##### A Python library for the [Chatbase API](https://chatbase.com/documentation/ref) 3 | 4 | > This is not an official Google product 5 | 6 | ## Quick Start 7 | 8 | ```SH 9 | $ pip install git+git://github.com/google/chatbase-python.git 10 | ``` 11 | 12 | ## Account Setup 13 | Please see the [Getting Started Section](https://chatbase.com/documentation/quickstart) for information 14 | on configuring one's account and obtaining and API key. 15 | 16 | ## Using the module 17 | 18 | #### One can send individual messages to the Generic and Facebook rest APIs: 19 | 20 | Generic: 21 | 22 | ```PYTHON 23 | from chatbase import Message 24 | 25 | msg = Message(api_key="x", 26 | platform="kik", 27 | version="0.1", 28 | user_id="unique-str", 29 | message="this is a test", 30 | intent="test") 31 | resp = msg.send() 32 | ``` 33 | 34 | Facebook: 35 | 36 | ```PYTHON 37 | from chatbase import FacebookAgentMessage, FacebookUserMessage 38 | 39 | # Agent messages 40 | agnMsg = FacebookAgentMessage(api_key="x", intent="y", version="1", message="a") 41 | # Make sure to set the recipient and message IDs 42 | agnMsg.set_recipient_id("123") 43 | agnMsg.set_message_id("xyz") 44 | resp = agnMsg.send() 45 | 46 | # User messages 47 | usrMsg = FacebookUserMessage(api_key="x", intent="y", version="1", message="a") 48 | # Make sure to set the recipient, sender and message IDs 49 | usrMsg.set_recipient_id("123") 50 | usrMsg.set_sender_id("456") 51 | usrMsg.set_message_id("xyz") 52 | resp = usrMsg.send() 53 | ``` 54 | 55 | #### One can send sets of messages as well to the Generic and Facebook rest APIs: 56 | 57 | Generic: 58 | 59 | ```PYTHON 60 | from chatbase import MessageSet 61 | 62 | # When we init the message set we can set several properties which will be 63 | # propagated to all message created from the set! 64 | set = MessageSet(api_key="x", platform="x", version="1", user_id="123") 65 | msg = set.new_message(intent="impress", content="goes to 11") 66 | # one can still edit the message normally and these changes will be reflected 67 | # in the containing set 68 | msg.user_id = "shark-sandwich" 69 | # Message type objects can be appended: 70 | msg2 = Message(api_key="x", 71 | platform="my_platform", 72 | version="0.1", 73 | user_id="unique-str", 74 | message="this is a test", 75 | intent="test") 76 | set.append_message(msg2) 77 | # Sending the set will send all contained messages to the batch endpoint 78 | resp = set.send() 79 | ``` 80 | 81 | Facebook: 82 | 83 | ```PYTHON 84 | from chatbase import FacebookAgentMessageSet, FacebookUserMessageSet 85 | 86 | # Agent Message Set 87 | agnSet = FacebookAgentMessageSet(api_key="x", version="y") 88 | msg = agnSet.new_message(intent="a", message="b") 89 | # Don't forget to set the message and recipient ids 90 | msg.set_recipient_id("123") 91 | msg.set_message_id("xyz") 92 | resp = agnSet.send() 93 | 94 | # User Message Set 95 | usrSet = FacebookUserMessageSet(api_key="a", version="b") 96 | msg = usrSet.new_message(intent="c", message="d") 97 | # Don't for get to set the message, recipient and sender ids 98 | msg.set_recipient_id("123") 99 | msg.set_sender_id("456") 100 | msg.set_message_id("xyz") 101 | resp = usrSet.send() 102 | ``` 103 | 104 | #### Tests 105 | Please place tests in `tests` directory. To run tests, from the repository 106 | root run the following command: 107 | 108 | ``` 109 | $ python -m unittest discover ./chatbase/tests/ 110 | ``` 111 | -------------------------------------------------------------------------------- /chatbase/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """Init handles module initialization.""" 16 | 17 | from chatbase.base_message import * 18 | from chatbase.facebook_agent_message import * 19 | from chatbase.facebook_chatbase_fields import * 20 | from chatbase.facebook_user_message import * 21 | -------------------------------------------------------------------------------- /chatbase/base_message.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """Define the core attributes/methods on a Message instance.""" 16 | import json 17 | import requests 18 | import time 19 | 20 | 21 | class InvalidMessageTypeError(Exception): 22 | """Error raised when attribute values are set on a 23 | Message instance which is not compatible with the 24 | the msg_type attribute. 25 | """ 26 | 27 | def __init___(self, val): 28 | self.value = val 29 | 30 | def __str__(self): 31 | return repr(self.value) 32 | 33 | 34 | class MessageTypes(object): 35 | """Defines message types.""" 36 | USER = "user" 37 | AGENT = "agent" 38 | 39 | 40 | class Message(object): 41 | """Base Message. 42 | Define attributes present on all variants of the Message Class. 43 | """ 44 | 45 | def __init__(self, 46 | api_key="", 47 | platform="", 48 | message="", 49 | intent="", 50 | version="", 51 | user_id="", 52 | type=None, 53 | not_handled=False, 54 | time_stamp=None): 55 | self.api_key = api_key 56 | self.platform = platform 57 | self.message = message 58 | self.intent = intent 59 | self.version = version 60 | self.user_id = user_id 61 | self.not_handled = not_handled 62 | self.feedback = False 63 | self.time_stamp = time_stamp or Message.get_current_timestamp() 64 | self.type = type or MessageTypes.USER 65 | 66 | @staticmethod 67 | def get_current_timestamp(): 68 | """Returns the current epoch with MS precision.""" 69 | return int(round(time.time() * 1e3)) 70 | 71 | @staticmethod 72 | def get_content_type(): 73 | """Returns the content-type for requesting against the Chatbase API""" 74 | return {'Content-type': 'application/json', 'Accept': 'text/plain'} 75 | 76 | def set_as_type_user(self): 77 | """Set the message as type user.""" 78 | self.type = MessageTypes.USER 79 | 80 | def set_as_type_agent(self): 81 | """Set the message as type agent.""" 82 | self.type = MessageTypes.AGENT 83 | 84 | def set_as_not_handled(self): 85 | """Set the message's not_handled attribute to True. 86 | Will throw if the message is of type Agent. Only user-type 87 | Messages can have the not_handled attribute as True. 88 | """ 89 | if self.type == MessageTypes.AGENT: 90 | raise InvalidMessageTypeError( 91 | 'Cannot set not_handled as True when msg is of type Agent') 92 | self.not_handled = True 93 | 94 | def set_as_handled(self): 95 | """Set the message's not_handled attribute to False.""" 96 | self.not_handled = False 97 | 98 | def set_as_feedback(self): 99 | """Set the message's feedback attribute to True. 100 | Will throw if the message is of type Agent. Only user-type 101 | Messages can have the feedback attribute as True. 102 | """ 103 | if self.type == MessageTypes.AGENT: 104 | raise InvalidMessageTypeError( 105 | 'Cannot set feedback as True when msg is of type Agent') 106 | self.feedback = True 107 | 108 | def set_as_not_feedback(self): 109 | """Set the message's feeback attribute to False.""" 110 | self.feedback = False 111 | 112 | def to_json(self): 113 | """Return a JSON version for use with the Chatbase API""" 114 | return json.dumps(self, default=lambda i: i.__dict__) 115 | 116 | def send(self): 117 | """Send the message to the Chatbase API.""" 118 | url = "https://chatbase.com/api/message" 119 | return requests.post(url, 120 | data=self.to_json(), 121 | headers=Message.get_content_type()) 122 | 123 | 124 | class MessageSet(object): 125 | """Message Set. 126 | Add messages to a set and send to the Batch API. 127 | """ 128 | 129 | def __init__(self, 130 | api_key="", 131 | platform="", 132 | version="", 133 | user_id=""): 134 | self.api_key = api_key 135 | self.platform = platform 136 | self.version = version 137 | self.user_id = user_id 138 | self.messages = [] 139 | 140 | def append_message(self, message_object): 141 | """Append a Message object to the set.""" 142 | self.messages.append(message_object) 143 | 144 | def new_message(self, 145 | intent="", 146 | message="", 147 | type=None, 148 | not_handled=False, 149 | time_stamp=None): 150 | """Add a message to the internal messages list and return it""" 151 | self.messages.append(Message(api_key=self.api_key, 152 | platform=self.platform, 153 | version=self.version, 154 | user_id=self.user_id, 155 | intent=intent, 156 | message=message, 157 | type=type, 158 | not_handled=not_handled, 159 | time_stamp=time_stamp)) 160 | return self.messages[-1] 161 | 162 | def to_json(self): 163 | """Return a JSON version for use with the Chatbase API""" 164 | return json.dumps({'messages': self.messages}, 165 | default=lambda i: i.__dict__) 166 | 167 | def send(self): 168 | """Send the message set to the Chatbase API""" 169 | url = ("https://chatbase.com/api/messages?api_key=%s" % self.api_key) 170 | return requests.post(url, 171 | data=self.to_json(), 172 | headers=Message.get_content_type()) 173 | -------------------------------------------------------------------------------- /chatbase/facebook_agent_message.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """Define the attributes on facebook agent messages.""" 16 | 17 | import json 18 | import requests 19 | from .base_message import Message 20 | from .facebook_chatbase_fields import * 21 | 22 | 23 | class FacebookAgentMessageRequestBody(object): 24 | """Request body for facebook agent message.""" 25 | 26 | def __init__(self): 27 | self.recipient = FacebookID() 28 | self.message = FacebookUserMessageContent() 29 | self.timestamp = Message.get_current_timestamp() 30 | 31 | 32 | class FacebookAgentMessageResponseBody(object): 33 | """Request body for facebook agent message.""" 34 | 35 | def __init__(self): 36 | self.recipient_id = '' 37 | self.message_id = '' 38 | 39 | 40 | class FacebookAgentMessage(Message): 41 | """FacebookAgentMessage represents a message 42 | garnered from an agent via facebook. 43 | """ 44 | 45 | def __init__(self, api_key="", intent="", version="", message=""): 46 | super(FacebookAgentMessage, self).__init__(api_key=api_key, 47 | intent=intent, 48 | version=version, 49 | message=message) 50 | self.request_body = FacebookAgentMessageRequestBody() 51 | self.response_body = FacebookAgentMessageResponseBody() 52 | self.chatbase_fields = ChatbaseFields() 53 | 54 | def set_recipient_id(self, rec_id): 55 | """Set the recipient id.""" 56 | self.response_body.recipient_id = rec_id 57 | self.request_body.recipient.id = rec_id 58 | 59 | def set_message_id(self, msg_id): 60 | """Set the message id.""" 61 | self.response_body.message_id = msg_id 62 | self.request_body.message.mid = msg_id 63 | 64 | def set_chatbase_fields(self): 65 | """Extract chatbase fields from instance and format for transmission.""" 66 | self.chatbase_fields.intent = self.intent 67 | self.chatbase_fields.version = self.version 68 | self.chatbase_fields.not_handled = self.not_handled 69 | self.chatbase_fields.feedback = self.feedback 70 | self.request_body.message.text = self.message 71 | 72 | def to_json(self): 73 | """Return a JSON version for use with the Chatbase API""" 74 | self.set_chatbase_fields() 75 | return json.dumps({ 76 | 'request_body': self.request_body, 77 | 'response_body': self.response_body, 78 | 'chatbase_fields': self.chatbase_fields 79 | }, default=lambda i: i.__dict__) 80 | 81 | def send(self): 82 | """Send the message to the Chatbase API.""" 83 | url = ("https://chatbase.com/api/facebook/message_received?api_key=%s" % 84 | self.api_key) 85 | return requests.post(url, 86 | data=self.to_json(), 87 | headers=Message.get_content_type()) 88 | 89 | 90 | class FacebookAgentMessageSet(object): 91 | """Message Set. 92 | Add messages to a set and send to the Batch API. 93 | """ 94 | 95 | def __init__(self, 96 | api_key="", 97 | version=""): 98 | self.api_key = api_key 99 | self.version = version 100 | self.messages = [] 101 | 102 | def new_message(self, intent="", message=""): 103 | """Add a message to the internal messages list and return it""" 104 | self.messages.append(FacebookAgentMessage(api_key=self.api_key, 105 | version=self.version, 106 | intent=intent, 107 | message=message)) 108 | return self.messages[-1] 109 | 110 | def to_json(self): 111 | """Return a JSON version for use with the Chatbase API""" 112 | [(lambda m: m.set_chatbase_fields())(m) for m in self.messages] 113 | return json.dumps({'messages': self.messages}, 114 | default=lambda i: i.__dict__) 115 | 116 | def send(self): 117 | """Send the message set to the Chatbase API""" 118 | url = ("https://chatbase.com/api/facebook/send_message_batch?api_key=%s" 119 | % self.api_key) 120 | return requests.post(url, 121 | data=self.to_json(), 122 | headers=Message.get_content_type()) 123 | -------------------------------------------------------------------------------- /chatbase/facebook_chatbase_fields.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """Define the form and function of the chatbase_fields attribute""" 16 | 17 | 18 | class FacebookID(object): 19 | """Defines the form of facebook ids.""" 20 | 21 | def __init__(self): 22 | self.id = "" 23 | 24 | 25 | class FacebookUserMessageContent(object): 26 | """Defines the form of facebook message content.""" 27 | 28 | def __init__(self): 29 | self.mid = "" 30 | self.text = "" 31 | 32 | 33 | class ChatbaseFields(object): 34 | """Attribute used to store Chatbase params when sending FB messages.""" 35 | 36 | def __init__(self): 37 | self.intent = "" 38 | self.version = "" 39 | self.not_handled = False 40 | self.feedback = False 41 | -------------------------------------------------------------------------------- /chatbase/facebook_user_message.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """Define the attributes on facebook user messages.""" 16 | 17 | import json, requests 18 | from .base_message import Message 19 | from .facebook_chatbase_fields import * 20 | 21 | 22 | class FacebookUserMessage(Message): 23 | """FacebookUserMessage represents a message 24 | garnered from a user via facebook. 25 | """ 26 | 27 | def __init__(self, api_key="", intent="", version="", message=""): 28 | super(FacebookUserMessage, self).__init__(api_key=api_key, 29 | intent=intent, 30 | version=version, 31 | message=message) 32 | self.sender = FacebookID() 33 | self.recipient = FacebookID() 34 | self.fb_message = FacebookUserMessageContent() 35 | self.timestamp = Message.get_current_timestamp() 36 | self.chatbase_fields = ChatbaseFields() 37 | 38 | def set_recipient_id(self, rec_id): 39 | """Set the recipient id.""" 40 | self.recipient.id = rec_id 41 | 42 | def set_sender_id(self, snd_id): 43 | """Set the sender id.""" 44 | self.sender.id = snd_id 45 | 46 | def set_message_id(self, msg_id): 47 | """Set the message id.""" 48 | self.fb_message.mid = msg_id 49 | 50 | def set_chatbase_fields(self): 51 | """Extract chatbase fields from instance and format for transmission.""" 52 | self.chatbase_fields.intent = self.intent 53 | self.chatbase_fields.version = self.version 54 | self.chatbase_fields.not_handled = self.not_handled 55 | self.chatbase_fields.feedback = self.feedback 56 | self.fb_message.text = self.message 57 | 58 | def to_json(self): 59 | """Return a JSON version for use with the Chatbase API""" 60 | self.set_chatbase_fields() 61 | return json.dumps({ 62 | 'sender': self.sender, 63 | 'recipient': self.recipient, 64 | 'timestamp': self.timestamp, 65 | 'message': self.fb_message, 66 | 'chatbase_fields': self.chatbase_fields 67 | }, default=lambda i: i.__dict__) 68 | 69 | def to_set_format(self): 70 | """Return a dictionary version of the message for a set""" 71 | self.set_chatbase_fields() 72 | return { 73 | 'sender': self.sender, 74 | 'recipient': self.recipient, 75 | 'timestamp': self.timestamp, 76 | 'message': self.fb_message, 77 | 'chatbase_fields': self.chatbase_fields 78 | } 79 | 80 | def send(self): 81 | """Send the message to the Chatbase API.""" 82 | url = ("https://chatbase.com/api/facebook/send_message?api_key=%s" % 83 | self.api_key) 84 | return requests.post(url, 85 | data=self.to_json(), 86 | headers=Message.get_content_type()) 87 | 88 | class FacebookUserMessageSet(object): 89 | """Message Set. 90 | Add messages to a set and send to the Batch API. 91 | """ 92 | 93 | def __init__(self, 94 | api_key="", 95 | version=""): 96 | self.api_key = api_key 97 | self.version = version 98 | self.messages = [] 99 | 100 | def new_message(self, intent="", message=""): 101 | """Add a message to the internal messages list and return it""" 102 | self.messages.append(FacebookUserMessage(api_key=self.api_key, 103 | version=self.version, 104 | intent=intent, 105 | message=message)) 106 | return self.messages[-1] 107 | 108 | def to_json(self): 109 | """Return a JSON version for use with the Chatbase API""" 110 | msgs = [msg.to_set_format() for msg in self.messages] 111 | return json.dumps({"messages": msgs}, default=lambda i: i.__dict__) 112 | 113 | def send(self): 114 | """Send the message set to the Chatbase API""" 115 | url = ("https://chatbase.com/api/facebook/message_received_batch?api_key=%s" 116 | % self.api_key) 117 | return requests.post(url, 118 | data=self.to_json(), 119 | headers=Message.get_content_type()) 120 | -------------------------------------------------------------------------------- /chatbase/tests/test_agent_message.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import json, os, unittest 16 | from chatbase import * 17 | 18 | 19 | class TestAgentMessage(unittest.TestCase): 20 | def __init__(self, *args, **kwargs): 21 | super(TestAgentMessage, self).__init__(*args, **kwargs) 22 | # allow long diffs for dictionary comparison outputs 23 | self.maxDiff = None 24 | self.inst = FacebookAgentMessage() 25 | 26 | def test_init(self): 27 | self.assertTrue(isinstance( 28 | self.inst.request_body, FacebookAgentMessageRequestBody)) 29 | self.assertTrue(isinstance( 30 | self.inst.response_body, FacebookAgentMessageResponseBody)) 31 | self.assertTrue(isinstance(self.inst.chatbase_fields, ChatbaseFields)) 32 | 33 | def test_setting_rec_id(self): 34 | rec_id = "test-1234" 35 | i = FacebookAgentMessage() 36 | i.set_recipient_id(rec_id) 37 | self.assertEqual(i.request_body.recipient.id, rec_id) 38 | self.assertEqual(i.response_body.recipient_id, rec_id) 39 | 40 | def test_setting_msg_id(self): 41 | msg_id = "4567-test" 42 | i = FacebookAgentMessage() 43 | i.set_message_id(msg_id) 44 | self.assertEqual(i.response_body.message_id, msg_id) 45 | 46 | def test_json_encoding(self): 47 | intent = 'test' 48 | version = 'test1' 49 | msg_cnt = 'this is a test.' 50 | msg_id = '123' 51 | rec_id = '456' 52 | i = FacebookAgentMessage(intent=intent, version=version, message=msg_cnt) 53 | i.set_as_not_handled() 54 | i.set_as_feedback() 55 | i.set_recipient_id(rec_id) 56 | i.set_message_id(msg_id) 57 | json_out = i.to_json() 58 | self.assertEqual(json.loads(json_out), { 59 | 'request_body': { 60 | 'timestamp': i.request_body.timestamp, 61 | 'message': { 62 | 'text': msg_cnt, 63 | 'mid': msg_id 64 | }, 65 | 'recipient': {'id': rec_id}, 66 | }, 67 | 'response_body': { 68 | 'recipient_id': rec_id, 69 | 'message_id': msg_id 70 | }, 71 | 'chatbase_fields': { 72 | 'intent': intent, 73 | 'version': version, 74 | 'not_handled': True, 75 | 'feedback': True 76 | } 77 | }) 78 | 79 | def test_live_send(self): 80 | test_api_key = os.environ.get('CB_TEST_API_KEY') 81 | if test_api_key is None: 82 | print("Warning: Skipping live integration test without test API key.") 83 | return 84 | i = FacebookAgentMessage(api_key=test_api_key, 85 | message="test-message", 86 | intent="test-library", 87 | version="0.1") 88 | i.set_recipient_id("123") 89 | i.set_message_id("456") 90 | resp = i.send() 91 | self.assertEqual(resp.status_code, 200) 92 | 93 | def test_live_set_send(self): 94 | test_api_key = os.environ.get('CB_TEST_API_KEY') 95 | if test_api_key is None: 96 | print("Warning: Skipping live integration test without test API key.") 97 | return 98 | s = FacebookAgentMessageSet(api_key=test_api_key, 99 | version="0.1") 100 | i = s.new_message() 101 | i.message = "msg-1" 102 | i.intent = "int-1" 103 | i.set_recipient_id("123") 104 | i.set_message_id("123") 105 | i = s.new_message() 106 | i.message = "msg-2" 107 | i.intent = "int-2" 108 | i.set_recipient_id("456") 109 | i.set_message_id("456") 110 | resp = s.send() 111 | self.assertEqual(resp.status_code, 200) 112 | 113 | 114 | if __name__ == '__main__': 115 | unittest.main() 116 | -------------------------------------------------------------------------------- /chatbase/tests/test_base_message.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import json 16 | import time 17 | import os 18 | import unittest 19 | from chatbase import Message, MessageSet, MessageTypes, InvalidMessageTypeError 20 | 21 | 22 | class TestMessage(unittest.TestCase): 23 | def __init__(self, *args, **kwargs): 24 | super(TestMessage, self).__init__(*args, **kwargs) 25 | self.inst = Message() 26 | 27 | def test_init(self): 28 | self.assertEqual(self.inst.api_key, '') 29 | self.assertEqual(self.inst.platform, '') 30 | self.assertEqual(self.inst.message, '') 31 | self.assertEqual(self.inst.intent, '') 32 | self.assertEqual(self.inst.version, '') 33 | self.assertEqual(self.inst.user_id, '') 34 | self.assertTrue(type(self.inst.time_stamp) is int) 35 | self.assertEqual(self.inst.type, MessageTypes.USER) 36 | self.assertFalse(self.inst.not_handled) 37 | self.assertFalse(self.inst.feedback) 38 | 39 | def test_ts_method(self): 40 | self.assertTrue(type(Message.get_current_timestamp()) is int) 41 | 42 | def test_type_setting(self): 43 | # instance the entity in function to eliminate test-case bleeding 44 | i = Message() 45 | i.set_as_type_user() 46 | self.assertEqual(i.type, MessageTypes.USER) 47 | i.set_as_type_agent() 48 | self.assertEqual(i.type, MessageTypes.AGENT) 49 | 50 | def test_not_handled_setting(self): 51 | i = Message() 52 | i.set_as_not_handled() 53 | self.assertTrue(i.not_handled) 54 | i.set_as_handled() 55 | self.assertFalse(i.not_handled) 56 | 57 | def test_feedback_setting(self): 58 | i = Message() 59 | i.set_as_feedback() 60 | self.assertTrue(i.feedback) 61 | i.set_as_not_feedback() 62 | self.assertFalse(i.feedback) 63 | 64 | def test_to_json(self): 65 | api_key = '1234' 66 | platform = '1' 67 | message = '2' 68 | intent = '3' 69 | version = '4' 70 | user_id = '5' 71 | time_stamp = int(round(time.time() * 1e3)) 72 | i = Message(api_key=api_key, platform=platform, message=message, 73 | intent=intent, version=version, user_id=user_id, 74 | type=MessageTypes.USER, not_handled=True, 75 | time_stamp=time_stamp) 76 | i.set_as_feedback() 77 | self.assertEqual(json.loads(i.to_json()), { 78 | 'api_key': api_key, 79 | 'platform': platform, 80 | 'message': message, 81 | 'intent': intent, 82 | 'version': version, 83 | 'user_id': user_id, 84 | 'time_stamp': time_stamp, 85 | 'type': MessageTypes.USER, # since we did not set as type agent 86 | 'not_handled': True, 87 | 'feedback': True 88 | }) 89 | 90 | def test_message_set_append_message(self): 91 | api_key = '1234' 92 | platform = '1' 93 | message = '2' 94 | intent = '3' 95 | version = '4' 96 | user_id = '5' 97 | time_stamp = int(round(time.time() * 1e3)) 98 | msg1 = Message(api_key=api_key, platform=platform, message=message, 99 | intent=intent, version=version, user_id=user_id, 100 | type=MessageTypes.USER, not_handled=True, 101 | time_stamp=time_stamp) 102 | msg1.set_as_feedback() 103 | msg2 = Message(api_key=api_key, platform=platform, message=message, 104 | version=version, user_id=user_id, 105 | type=MessageTypes.AGENT) 106 | message_set = MessageSet(api_key=api_key, platform=platform, 107 | version=version, user_id=user_id) 108 | message_set.append_message(msg1) 109 | message_set.append_message(msg2) 110 | msg1 = message_set.messages[0] 111 | self.assertEqual(json.loads(msg1.to_json()), { 112 | 'api_key': api_key, 113 | 'platform': platform, 114 | 'message': message, 115 | 'intent': intent, 116 | 'version': version, 117 | 'user_id': user_id, 118 | 'time_stamp': time_stamp, 119 | 'type': MessageTypes.USER, # since we did not set as type agent 120 | 'not_handled': True, 121 | 'feedback': True 122 | }) 123 | msg2 = message_set.messages[1] 124 | self.assertEqual(json.loads(msg2.to_json()), { 125 | 'api_key': api_key, 126 | 'platform': platform, 127 | 'message': message, 128 | 'intent': msg2.intent, 129 | 'version': version, 130 | 'user_id': user_id, 131 | 'time_stamp': msg2.time_stamp, 132 | 'type': MessageTypes.AGENT, # since we did set as type agent 133 | 'not_handled': False, 134 | 'feedback': False 135 | }) 136 | 137 | def test_message_set_new_message(self): 138 | api_key = '1234' 139 | platform = '1' 140 | message = '2' 141 | intent = '3' 142 | version = '4' 143 | user_id = '5' 144 | time_stamp = int(round(time.time() * 1e3)) 145 | message_set = MessageSet(api_key=api_key, platform=platform, 146 | version=version, user_id=user_id) 147 | msg1 = message_set.new_message(intent=intent, message=message, 148 | type=MessageTypes.USER, 149 | not_handled=True, time_stamp=time_stamp) 150 | msg1.set_as_feedback() 151 | msg2 = message_set.new_message(message=message, type=MessageTypes.AGENT) 152 | self.assertEqual(json.loads(msg1.to_json()), { 153 | 'api_key': api_key, 154 | 'platform': platform, 155 | 'message': message, 156 | 'intent': intent, 157 | 'version': version, 158 | 'user_id': user_id, 159 | 'time_stamp': time_stamp, 160 | 'type': MessageTypes.USER, # since we did not set as type agent 161 | 'not_handled': True, 162 | 'feedback': True 163 | }) 164 | self.assertEqual(json.loads(msg2.to_json()), { 165 | 'api_key': api_key, 166 | 'platform': platform, 167 | 'message': message, 168 | 'intent': msg2.intent, 169 | 'version': version, 170 | 'user_id': user_id, 171 | 'time_stamp': msg2.time_stamp, 172 | 'type': MessageTypes.AGENT, # since we did not set as type agent 173 | 'not_handled': False, 174 | 'feedback': False 175 | }) 176 | 177 | def test_live_send(self): 178 | test_api_key = os.environ.get('CB_TEST_API_KEY') 179 | if test_api_key is None: 180 | print("Warning: Skipping live integration test without test API key.") 181 | return 182 | i = Message(api_key=test_api_key, 183 | platform="python-lib-test", 184 | message="test-message", 185 | intent="test-library", 186 | version="0.1", 187 | user_id="12345") 188 | resp = i.send() 189 | self.assertEqual(resp.status_code, 200) 190 | 191 | def test_live_set_send(self): 192 | test_api_key = os.environ.get('CB_TEST_API_KEY') 193 | if test_api_key is None: 194 | print("Warning: Skipping live integration test without test API key.") 195 | return 196 | s = MessageSet(api_key=test_api_key, 197 | platform="python-lib-test", 198 | version="0.1", 199 | user_id="12345") 200 | i = s.new_message() 201 | i.message = "msg-1" 202 | i.intent = "int-1" 203 | i = s.new_message() 204 | i.message = "msg-2" 205 | i.intent = "int-2" 206 | resp = s.send() 207 | self.assertEqual(resp.status_code, 200) 208 | 209 | 210 | if __name__ == '__main__': 211 | unittest.main() 212 | -------------------------------------------------------------------------------- /chatbase/tests/test_user_message.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import json, unittest, os 16 | from chatbase import * 17 | 18 | 19 | class TestUserMessage(unittest.TestCase): 20 | def __init__(self, *args, **kwargs): 21 | super(TestUserMessage, self).__init__(*args, **kwargs) 22 | # allow long diffs for dictionary comparison outputs 23 | self.maxDiff = None 24 | 25 | def test_init(self): 26 | api_key = '123-abc' 27 | intent = '1' 28 | version = '2' 29 | message = '3' 30 | i = FacebookUserMessage(api_key=api_key, 31 | intent=intent, 32 | version=version, 33 | message=message) 34 | self.assertEqual(i.api_key, api_key) 35 | self.assertEqual(i.intent, intent) 36 | self.assertEqual(i.version, version) 37 | self.assertEqual(i.message, message) 38 | 39 | def test_set_recipient_id(self): 40 | rec_id = '1234' 41 | i = FacebookUserMessage() 42 | i.set_recipient_id(rec_id) 43 | self.assertEqual(i.recipient.id, rec_id) 44 | 45 | def test_set_sender_id(self): 46 | snd_id = '5678' 47 | i = FacebookUserMessage() 48 | i.set_sender_id(snd_id) 49 | self.assertEqual(i.sender.id, snd_id) 50 | 51 | def test_set_message_id(self): 52 | msg_id = 'abc-123' 53 | i = FacebookUserMessage() 54 | i.set_message_id(msg_id) 55 | self.assertEqual(i.fb_message.mid, msg_id) 56 | 57 | def test_to_json(self): 58 | api_key = '123-abc' 59 | intent = '1' 60 | version = '2' 61 | message = '3' 62 | rec_id = '1234' 63 | snd_id = '5678' 64 | msg_id = 'abc-123' 65 | i = FacebookUserMessage( 66 | intent=intent, version=version, message=message) 67 | i.set_recipient_id(rec_id) 68 | i.set_sender_id(snd_id) 69 | i.set_message_id(msg_id) 70 | i.set_as_not_handled() 71 | i.set_as_feedback() 72 | self.assertEqual(json.loads(i.to_json()), { 73 | 'sender': {'id': snd_id}, 74 | 'recipient': {'id': rec_id}, 75 | 'timestamp': i.timestamp, 76 | 'message': { 77 | 'mid': msg_id, 78 | 'text': message 79 | }, 80 | 'chatbase_fields': { 81 | 'intent': intent, 82 | 'version': version, 83 | 'not_handled': True, 84 | 'feedback': True 85 | } 86 | }) 87 | 88 | def test_live_send(self): 89 | test_api_key = os.environ.get('CB_TEST_API_KEY') 90 | if test_api_key is None: 91 | print("Warning: Skipping live integration test without test API key.") 92 | return 93 | i = FacebookUserMessage(api_key=test_api_key, 94 | message="test-message", 95 | intent="test-library", 96 | version="0.1") 97 | i.set_recipient_id("123") 98 | i.set_message_id("456") 99 | i.set_sender_id("789") 100 | resp = i.send() 101 | self.assertEqual(resp.status_code, 200) 102 | 103 | def test_live_set_send(self): 104 | test_api_key = os.environ.get('CB_TEST_API_KEY') 105 | if test_api_key is None: 106 | print("Warning: Skipping live integration test without test API key.") 107 | return 108 | s = FacebookUserMessageSet(api_key=test_api_key, 109 | version="0.1") 110 | i = s.new_message() 111 | i.message = "msg-1" 112 | i.intent = "int-1" 113 | i.set_recipient_id("123") 114 | i.set_message_id("123") 115 | i.set_sender_id("123") 116 | i = s.new_message() 117 | i.message = "msg-2" 118 | i.intent = "int-2" 119 | i.set_recipient_id("456") 120 | i.set_message_id("456") 121 | i.set_sender_id("456") 122 | resp = s.send() 123 | self.assertEqual(resp.status_code, 200) 124 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """Setup defines metadata for the python Chatbase Module.""" 16 | from setuptools import setup 17 | 18 | setup(name='chatbase', 19 | version='0.2.1', 20 | description='Python module for interacting with Chatbase APIs', 21 | url='https://chatbase.com/documentation', 22 | author='Google Inc.', 23 | author_email='chatbase-feedback@google.com', 24 | license='Apache-2.0', 25 | packages=['chatbase'], 26 | install_requires=['requests'], 27 | zip_safe=False) 28 | --------------------------------------------------------------------------------