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:

  1. 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
    

    С#:

    public static bool IsSignatureCorrect(string msg, string sig, string secret)
    {
      if (msg is null)
        throw new ArgumentNullException(nameof(msg));
      if (secret is null)
        throw new ArgumentNullException(nameof(secret));
    
      byte[] hashValue;
      using (var hmac = new HMACSHA1(Encoding.UTF8.GetBytes(secret)))
      {
        hashValue = hmac.ComputeHash(Encoding.UTF8.GetBytes(msg));
      }
    
      return ToHexString(hashValue) == sig;
    }
    
    private static string ToHexString(IReadOnlyList<byte> hash)
    {
      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);
        chArray[i + 1] = GetHexValue(b % 16);
      }
    
      return new string(chArray);
    }
    
    private static char GetHexValue(int i)
    {
      return i < 10
        ? (char)('0' + i)
        : (char)('A' + i - 10);
    }
    
  2. 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.

  3. 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.
  4. 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.

Was this article helpful?