Example: creating a bot
This section walks you through developing a bot that supports auto-reply and approval. Also you can download the bot sample and deploy it to heroku. This information will be useful for application developers.
Create a page with an HTTPS address on your website, e.g. https://example.com/autoresponse. This event handler page will receive requests from your Pyrus bot. Add code to the event handler as follows:
Verify the signature to make sure that a request really comes from Pyrus.
Calculate the request body signature:
python:
def _is_signature_correct(message, secret, signature): secret = str.encode(secret) digest = hmac.new(secret, msg=message, digestmod=hashlib.sha1).hexdigest() return hmac.compare_digest(digest, signature.lower())
php:
strtoupper(hash_hmac("sha1", $response_body_as_string, $security_key))
ruby:
OpenSSL::HMAC.hexdigest('sha1', security_key, response_body_as_string).upcase
C#:
public static Boolean IsSignatureCorrect(String msg, String sig, String secret) { byte[] hashValue; using (HMACSHA1 hmac = new HMACSHA1(Encoding.UTF8.GetBytes(secret))) using (var outStream = new MemoryStream()) { hashValue = hmac.ComputeHash(Encoding.UTF8.GetBytes(msg)); outStream.Write(hashValue, 0, hashValue.Length); } var hashString = ToHexString(hashValue); return hashString == sig; } public static string ToHexString(IList<byte> hash, bool lowerCase = false) { if (hash == null) throw new ArgumentNullException(nameof(hash)); var chArrayLength = hash.Count * 2; var chArray = new char[chArrayLength]; for (int i = 0, index = 0; i < chArrayLength; i += 2, index++) { var b = hash[index]; chArray[i] = GetHexValue(b / 16, lowerCase); chArray[i + 1] = GetHexValue(b % 16, lowerCase); } return new String(chArray); } private static char GetHexValue(int i, bool lowerCase) { var startChar = lowerCase ? 'a' : 'A'; return i < 10 ? (char) (i + '0') : (char) (i - 10 + startChar); }
These functions convert a string request into a UTF byte array, and calculate an HMAC digest using the SHA1 secure hash algorithm.
Compare it to the X-Pyrus-Sig header to verify that the request has truly come from Pyrus. If the headers do not to match, the script is terminated.
Select author.email value from received task object (see the complete description):
{ "id": 5600, "text": "New task", "create_date": "2016-12-02T11:20:22Z", "last_modified_date": "2016-12-02T11:20:22Z", "parent_task_id": 0, "author": { "id": 1731, "first_name": "tester", "last_name": "papirus", "email": "test@pyrus.com" }, "approvals": [[{ "person": { "id": 21913, "first_name": "bot", "last_name": "papirus", "email": "bot@pyrus.com" }, "approval_choice": "waiting" }], [{ "person": { "id": 1731, "first_name": "tester", "last_name": "papirus", "email": "test@pyrus.com" }, "approval_choice": "waiting" }]], "comments": [{ "create_date": "2016-12-02T11:20:22Z", "author": { "id": 1731, "first_name": "tester", "last_name": "papirus", "email": "test@pyrus.com" }, "approvals_added": [{ "person": { "id": 21913, "first_name": "bot", "last_name": "papirus", "email": "bot@pyrus.com" }, "step": 1 }, { "person": { "id": 1731, "first_name": "tester", "last_name": "papirus", "email": "test@pyrus.com" }, "step": 2 }], "id": 12208 }] }
In the above example author.email = test@pyrus.com.
Generate the response body:
{ "text": "Hello, test@pyrus.com. This task approved by bot.", "approval_choice": "approved" }
In this example:
- text (optional parameter): Comment text. If it is blank, the bot adds an empty text comment.
- approval_choice (optional parameter): Bot approval option. If no approval is required, the server ignores this parameter.
Return the HTTP response '200 ОК' and the body as described above.
Here is a full example of a bot in python. You can find the previous example of bot's code with the signature verifying here.
import hmac import hashlib import json from flask import Flask from flask import request app = Flask(__name__) @app.route("/", methods=['GET', 'POST']) def index(): body = request.data signature = request.headers['x-pyrus-sig'] secret = 'This-is-bot-secret-key-VtBOEesdOnIcqGaWQeFkWFqyzgdt2PGsZVWBc8h8H0-xU9ux-dN37IjcAqf2pzeqoo5FqdtoH' return _prepare_response(body.decode('utf-8')) def _prepare_response(body): task = json.loads(body)["task"] task_author = task["author"]["email"] return "{{\"text\": \"Hello, {}. This task approved by bot.\", \"approval_choice\": \"approved\"}}".format(task_author) if __name__ == "__main__": app.run("127.0.0.1", 5001) # !!!Do not forget to replace the address!!!
Now, add the new bot and enter the address of event handler in the URL field (in our example, https://example.com/autoresponse).
To check out your work, assign a task to the bot in Pyrus with an approval request. Make sure that the task receives the Approved by bot reply, and that bot approval is enabled.