Getting Started

Intro

Get straight to building bots. Avoid the complexity of each instant message service and focus on your bot app

Permabots Architecture

This tutorial will have you building and deploying a chatbot that look for users and fetches some information from Github for Telegram, Kik and Facebook Messenger platforms in minutes.

The tutorial assumes that you have:

This tutorial uses the Permabots API, so you need to set API token in header, Authentication: Token api_token. However you can fulfill all this tutorial with the web dashboard.

Bots

A Permabot has all the chatbot logic. With the same definition it works with several instant messaging platforms. Create a bot in Permabots with a given name.

			
POST /api/v1/bots/ HTTP/1.1
Host: www.permabots.com
Authorization: Token yourpermabotstoken
Content-Type: application/json				
{
	"name": "Permabots GitHub Tutorial"
}
			
		
			
{
	"id": "799e96f2-93eb-44eb-918c-c5bd14560c54",
	"name": "Permabots GitHub Tutorial",
	"created_at": "2016-04-20T10:46:04.179353Z",
	"updated_at": "2016-04-20T10:46:04.179384Z",
	"telegram_bot": null,
	"kik_bot": null
}
			
		

Telegram

Follow the instructions to create a Telegram bot. Permabots only requires token.

			
POST /api/v1/bots/799e96f2-93eb-44eb-918c-c5bd14560c54/telegram/ HTTP/1.1
Host: www.permabots.com
Authorization: Token yourpermabotstoken
Content-Type: application/json
{
	"token": "your_telegram_bot_token",
	"enabled": true
}	
				
		
	
{
"id": "92a0e12c-9512-4aae-a4e6-2ebeb3fb3328",
"token": ""your_telegram_bot_token",
"created_at": "2016-04-20T10:49:57.295249Z",
"updated_at": "2016-04-20T10:49:57.295303Z",
"enabled": true,
"info": {
   "first_name": "PermaGithub",
   "last_name": null,
   "username": "PermaGithubBot"
	}
}	

Kik

Follow the instructions to create a Kik bot. Permabots only requires username and api key.

	
POST /api/v1/bots/799e96f2-93eb-44eb-918c-c5bd14560c54/kik/ HTTP/1.1
Host: www.permabots.com
Authorization: Token yourpermabotstoken
Content-Type: application/json
{
	"api_key": "your_kik_api_key",
	"username": "permagithubtutorial",
	"enabled": true
}
	
	

	
{
	"id": "8e51a392-c464-4225-99e7-ff3d1189ec34",
	"api_key": "your_kik_api_key",
	"created_at": "2016-04-20T10:50:23.252650Z",
	"updated_at": "2016-04-20T10:50:23.252683Z",
	"enabled": true,
	"username": "permagithubtutorial"
}
	

Facebook Messenger

Follow the instructions to create a Facebook Messenger bot. Permabots only requires Page Access Token. However you need to set webhook url in your facebook account. Take id generated in permabots an use it to generate Callback Url https://permabots.herokuapp.com/processing/messengerbot/permabots_messenger_bot_id/and Verify Token.

	
POST /api/v1/bots/799e96f2-93eb-44eb-918c-c5bd14560c54/messenger/ HTTP/1.1
Host: www.permabots.com
Authorization: Token yourpermabotstoken
Content-Type: application/json
{
	"token": "your_page_access_token",
	"enabled": true
}
	
	

	
{
	"id": "8e51aa92-c664-4cz25-9re7-ffy8d1189ec34",
	"token": "your_page_access_token",
	"created_at": "2016-04-20T10:50:28.252650Z",
	"updated_at": "2016-04-20T10:50:28.252683Z",
	"enabled": true,
}
	

In this example we should use 8e51aa92-c664-4cz25-9re7-ffy8d1189ec34 in Facebook Apps dashboard as Verify Token and for Callback Url generation https://permabots.herokuapp.com/processing/messengerbot/8e51aa92-c664-4cz25-9re7-ffy8d1189ec34/

These bots are created already enabled but it is useful to disable it until you have already built and consider it as ready.

Message Handlers

When a message is received a handler is selected to attend it generating a response. A handler defines how this response is built.


POST /api/v1/bots/799e96f2-93eb-44eb-918c-c5bd14560c54/handlers/ HTTP/1.1
Host: www.permabots.com
Authorization: Token yourpermabotstoken
Content-Type: application/json
{
  "name": "Wellcome",
  "enabled": true,
  "pattern": "/start|Hi|Hello|hi|hello",
  "response": {"text_template": "Wellcome to PermaGithub Tutorial bot  \\n Which github username do you want me to look for?",
               "keyboard_template": ""
               }

}


{
  "id": "82bb4c1b-3a4e-4f52-bed4-0f1ddf2a62c6",
  "created_at": "2016-05-04T14:21:05.251207Z",
  "updated_at": "2016-05-04T14:21:05.251230Z",
  "name": "Wellcome",
  "pattern": "/start|Hi|Hello|hi|hello",
  "enabled": true,
  "request": null,
  "response": {
    "text_template": "Wellcome to PermaGithub Tutorial bot  \\n Which github username do you want me to look for?",
    "keyboard_template": ""
  },
  "target_state": null,
  "source_states": [],
  "priority": 0
}

Note: Permabots identifies with /start when chat starts. This is Telegram original method but Permabot uses for Kik too.

A wellcome message is set as response. In this case only a text response is defined but keyboards can be part of it.

Context

A context is used to parametrize handlers. Some context data is available just when handler starts its processing and other is attached as a result of the processing.

Our bot is requesting for Github username in wellcome handlers. Create a handler with a Github request generated dynamically with context


POST /api/v1/bots/799e96f2-93eb-44eb-918c-c5bd14560c54/handlers/ HTTP/1.1
Host: www.permabots.com
Authorization: Token yourpermabotstoken
Content-Type: application/json
{
  "name": "Username",
  "enabled": true,
  "pattern": "(?P<username>\\w+)",
  "request": {"url_template": "https://api.github.com/users/{{pattern.username }}",
              "method": "Get"},
  "response": {"text_template": "{% if response.status == 404 %}{{ pattern.username }} not found {{ emoji.black_question_mark_ornament}} Try with another one.{% else %}{% if service == 'telegram' %}{{ response.data.login }}{% else %}{{ response.data.login }} with url {{ response.data.html_url }}{% endif %}{% endif %} it has {{ response.data.public_repos }} public repos {{ emoji.public_address_loudspeaker }} and {{ response.data.followers}} followers {{ emoji.family}} \\n View repos or go back",
               "keyboard_template": "{% if response.status == 200 %}[['Repos'],['Back']]{% endif %}"
               }

}


{
  "id": "1861cdd7-72aa-413e-b628-328c7087d00b",
  "created_at": "2016-05-04T14:22:38.264460Z",
  "updated_at": "2016-05-04T14:22:38.264492Z",
  "name": "Username",
  "pattern": "(?P<username>\\w+)",
  "enabled": true,
  "request": {
    "url_template": "https://api.github.com/users/{{pattern.username }}",
    "method": "Get",
    "data": null,
    "url_parameters": [],
    "header_parameters": []
  },
  "response": {
    "text_template": "{% if response.status == 404 %}{{ pattern.username }} not found {{ emoji.black_question_mark_ornament}} Try with another one.{% else %}{% if service == 'telegram' %}{{ response.data.login }}{% else %}{{ response.data.login }} with url {{ response.data.html_url }}{% endif %}{% endif %} it has {{ response.data.public_repos }} public repos {{ emoji.public_address_loudspeaker }} and {{ response.data.followers}} followers {{ emoji.family}} \\n View repos or go back",
    "keyboard_template": "{% if response.status == 200 %}[['Repos'],['Back']]{% endif %}"
  },
  "target_state": null,
  "source_states": [],
  "priority": 0
}

Emoji

Emoticons are attached to context as emoji. Use any emoticon from this table and use description in lower case and replacing spaces with _. Notice how we use it in our example {{emoji.back_with_leftwards_arrow_above}}}.

Pattern

Check the pattern, it has a regular expression (?P<username>\\w+) to get the word as a variable to later use it for generating the request to Github API. Patterns use regular expressions using python syntax. Variables obtained in pattern are attached to context in pattern variable.

Priority

Some times more than one handler pattern can match the message received. To resolve this collision you can set priority weights. Higher the value is higher is the priority

Request

A handler can use a http request as part of its processing. Data returned by request is attached to context as response.data. Request status code is also available in response.status.

Response

The response is generated with context. Jinja2 is used as template engine.

In our example, text response is generated using data returned by Github API. We also set a keyboard response to let the user get some of the Github user info. Notice the format is an array of arrays.

States

At this moment the bot is capable of getting Github user information but it can’t decide whether /start message is username or the starting command. To tell bot when to execute handlers we must use states.

We can design the state machine of the example

Chatbot state machine

The diagram give us some clues of what we still need to define. It is obvious we need three states ('User', 'User Detail' and 'Repo Detail') but also that we need six handlers. Notice when receiving a 404 error is not handler.

Let's create the states

	
POST /api/v1/bots/799e96f2-93eb-44eb-918c-c5bd14560c54/states/ HTTP/1.1
Host: www.permabots.com
Authorization: Token yourpermabotstoken
Content-Type: application/json
{
  "name": "Username"
}
	

{
  "id": "5bf426f6-3cd3-4999-ad4a-d282e107860e",
  "created_at": "2016-05-04T14:22:54.272625Z",
  "updated_at": "2016-05-04T14:22:54.272657Z",
  "name": "Username"
}


POST /api/v1/bots/799e96f2-93eb-44eb-918c-c5bd14560c54/states/ HTTP/1.1
Host: www.permabots.com
Authorization: Token yourpermabotstoken
Content-Type: application/json
{
  "name": "User Detail"
}


{
  "id": "dfdab2ff-d50c-4d6f-8e47-fc4ab5399559",
  "created_at": "2016-05-04T14:23:10.262180Z",
  "updated_at": "2016-05-04T14:23:10.262211Z",
  "name": "User Detail"
}


POST /api/v1/bots/799e96f2-93eb-44eb-918c-c5bd14560c54/states/ HTTP/1.1
Host: www.permabots.com
Authorization: Token yourpermabotstoken
Content-Type: application/json
{
  "name": "Repo"
}


{
  "id": "fce06ff0-889f-400c-a01a-99f90c9f48be",
  "created_at": "2016-05-04T14:23:24.058554Z",
  "updated_at": "2016-05-04T14:23:24.058601Z",
  "name": "Repo"
}

Each handler sets a new state, target_state, if all processing was correct but also needs a list of states, source_states, when it can be executed.

Let's update our handlers with target_state and source_states.

	
PUT /api/v1/bots/799e96f2-93eb-44eb-918c-c5bd14560c54/handlers/82bb4c1b-3a4e-4f52-bed4-0f1ddf2a62c6/ HTTP/1.1
Host: www.permabots.com
Authorization: Token yourpermabotstoken
Content-Type: application/json
{
    "target_state": {"name": "Username"}
}



{
  "id": "82bb4c1b-3a4e-4f52-bed4-0f1ddf2a62c6",
  "created_at": "2016-05-04T14:21:05.251207Z",
  "updated_at": "2016-05-04T14:24:14.510917Z",
  "name": "Wellcome",
  "pattern": "/start|Hi|Hello|hi|hello",
  "enabled": true,
  "request": null,
  "response": {
    "text_template": "Wellcome to PermaGithub Tutorial bot {{ emoji.waving_hand_sign}} \\n Which github username do you want me to look for?",
    "keyboard_template": ""
  },
  "target_state": {
    "id": "5bf426f6-3cd3-4999-ad4a-d282e107860e",
    "created_at": "2016-05-04T14:22:54.272625Z",
    "updated_at": "2016-05-04T14:22:54.272657Z",
    "name": "Username"
  },
  "source_states": [],
  "priority": 0
}


PUT /api/v1/bots/799e96f2-93eb-44eb-918c-c5bd14560c54/handlers/1861cdd7-72aa-413e-b628-328c7087d00b/ HTTP/1.1
Host: www.permabots.com
Authorization: Token yourpermabotstoken
Content-Type: application/json
{
"target_state": {"name": "User Detail"}
}



{
  "id": "1861cdd7-72aa-413e-b628-328c7087d00b",
  "created_at": "2016-05-04T14:22:38.264460Z",
  "updated_at": "2016-05-04T14:24:35.748834Z",
  "name": "Username",
  "pattern": "(?P<username>\\w+)",
  "enabled": true,
  "request": {
    "url_template": "https://api.github.com/users/{{pattern.username }}",
    "method": "Get",
    "data": null,
    "url_parameters": [],
    "header_parameters": []
  },
  "response": {
    "text_template": "{% if response.status == 404 %}{{ pattern.username }} not found {{ emoji.black_question_mark_ornament}} Try with another one.{% else %}{% if service == 'telegram' %}{{ response.data.login }}{% else %}{{ response.data.login }} with url {{ response.data.html_url }}{% endif %}{% endif %} it has {{ response.data.public_repos }} public repos {{ emoji.public_address_loudspeaker }} and {{ response.data.followers}} followers {{ emoji.family}} \\n View repos or go back",
    "keyboard_template": "{% if response.status == 200 %}[['Repos'],['Back']]{% endif %}"
  },
  "target_state": {
    "id": "dfdab2ff-d50c-4d6f-8e47-fc4ab5399559",
    "created_at": "2016-05-04T14:23:10.262180Z",
    "updated_at": "2016-05-04T14:23:10.262211Z",
    "name": "User Detail"
  },
  "source_states": [],
  "priority": 0
}


		
POST /api/v1/bots/799e96f2-93eb-44eb-918c-c5bd14560c54/handlers/1861cdd7-72aa-413e-b628-328c7087d00b/sourcestates/ HTTP/1.1
Host: www.permabots.com
Authorization: Token yourpermabotstoken
Content-Type: application/json
{
    "name": "Username"
}
	


{
  "id": "5bf426f6-3cd3-4999-ad4a-d282e107860e",
  "created_at": "2016-05-04T14:22:54.272625Z",
  "updated_at": "2016-05-04T14:22:54.272657Z",
  "name": "Username"
}

State Context

When setting a state, the context used for that processing is stored associated to that state in state_context. Then we can keep clean keyboards and still generate requests with context.

Remember the state machine diagram and set the rest of handlers. Notice how we use context associated to the state.


POST /api/v1/bots/799e96f2-93eb-44eb-918c-c5bd14560c54/handlers/ HTTP/1.1
Host: www.permabots.com
Authorization: Token yourpermabotstoken
Content-Type: application/json
{
    "name": "Repos",
    "enabled": true,
    "pattern": "Repos",
    "request": {"url_template": "https://api.github.com/users/{{state_context.username.pattern.username}}/repos", "method": "Get"},
    "response": {"text_template": "Select a repository",
                 "keyboard_template": "[['Back']{% for repo in response.data %}{% if loop.first %},{% endif %}['{{repo.name}}']{% if not loop.last %},{% endif %}{% endfor%}]"
    },
    "target_state": {"name": "Repo"}
    
}



{
  "id": "dbb5d6f1-1a51-4db0-a9f3-b639a4064a94",
  "created_at": "2016-05-04T14:25:11.670401Z",
  "updated_at": "2016-05-04T14:25:11.670424Z",
  "name": "Repos",
  "pattern": "Repos",
  "enabled": true,
  "request": {
    "url_template": "https://api.github.com/users/{{state_context.username.pattern.username}}/repos",
    "method": "Get",
    "data": null,
    "url_parameters": [],
    "header_parameters": []
  },
  "response": {
    "text_template": "Select a repository",
    "keyboard_template": "[['Back']{% for repo in response.data %}{% if loop.first %},{% endif %}['{{repo.name}}']{% if not loop.last %},{% endif %}{% endfor%}]"
  },
  "target_state": {
    "id": "fce06ff0-889f-400c-a01a-99f90c9f48be",
    "created_at": "2016-05-04T14:23:24.058554Z",
    "updated_at": "2016-05-04T14:23:24.058601Z",
    "name": "Repo"
  },
  "source_states": [],
  "priority": 0
}



POST /api/v1/bots/799e96f2-93eb-44eb-918c-c5bd14560c54/handlers/dbb5d6f1-1a51-4db0-a9f3-b639a4064a94/sourcestates/ HTTP/1.1
Host: www.permabots.com
Authorization: Token yourpermabotstoken
Content-Type: application/json
{
    "name": "User Detail"
}


	
{
  "id": "dfdab2ff-d50c-4d6f-8e47-fc4ab5399559",
  "created_at": "2016-05-04T14:23:10.262180Z",
  "updated_at": "2016-05-04T14:23:10.262211Z",
  "name": "User Detail"
}
	


POST /api/v1/bots/799e96f2-93eb-44eb-918c-c5bd14560c54/handlers/ HTTP/1.1
Host: www.permabots.com
Authorization: Token yourpermabotstoken
Content-Type: application/json
{
    "name": "Back from User Detail",
    "enabled": true,
    "pattern": "Back",
    "response": {"text_template": "Type github username do you want me to search?",
                 "keyboard_template": ""
    },
    "target_state" : {"name": "Username"}
    
}



{
  "id": "f9458cb7-db8a-4280-a951-d12c107ca707",
  "created_at": "2016-05-04T14:26:06.774088Z",
  "updated_at": "2016-05-04T14:26:06.774120Z",
  "name": "Back from User Detail",
  "pattern": "Back",
  "enabled": true,
  "request": null,
  "response": {
    "text_template": "Type github username do you want me to search?",
    "keyboard_template": ""
  },
  "target_state": {
    "id": "5bf426f6-3cd3-4999-ad4a-d282e107860e",
    "created_at": "2016-05-04T14:22:54.272625Z",
    "updated_at": "2016-05-04T14:22:54.272657Z",
    "name": "Username"
  },
  "source_states": [],
  "priority": 0
}


POST /api/v1/bots/799e96f2-93eb-44eb-918c-c5bd14560c54/handlers/f9458cb7-db8a-4280-a951-d12c107ca707/sourcestates/ HTTP/1.1
Host: www.permabots.com
Authorization: Token yourpermabotstoken
Content-Type: application/json
{
    "name": "User Detail"
}


{
  "id": "dfdab2ff-d50c-4d6f-8e47-fc4ab5399559",
  "created_at": "2016-05-04T14:23:10.262180Z",
  "updated_at": "2016-05-04T14:23:10.262211Z",
  "name": "User Detail"
}


POST /api/v1/bots/799e96f2-93eb-44eb-918c-c5bd14560c54/handlers/ HTTP/1.1
Host: www.permabots.com
Authorization: Token yourpermabotstoken
Content-Type: application/json
{
    "name": "Repo Detail",
    "enabled": true,
    "pattern": "(?P<repo>.+)",
    "request": {"url_template": "https://api.github.com/repos/{{state_context.username.pattern.username}}/{{ pattern.repo }}",
                "method": "Get"},
    "response": {"text_template": "{% if response.status == 404 %} Repository {{ pattern.repo }} from {{ pattern.username}} not found {{ emoji.cross_mark}}\\n Select one from menu{% else %} {% if service == 'telegram' %} {{ response.data.name }}: {{ response.data.description}}{% else %} {{ response.data.name}} with url {{response.data.html_url }}: {{ response.data.description }}{% endif %}\\n Select repo or go back{% endif %}",
                 "keyboard_template": "[['Back']{% for repo in state_context.user_detail.response.data %}{% if loop.first %},{% endif %}['{{repo.name}}']{% if not loop.last %},{% endif %}{% endfor%}]"
    }
}


{
  "id": "fa00fc42-48f2-4668-a9b5-e37aceda26e1",
  "created_at": "2016-05-04T14:27:29.766527Z",
  "updated_at": "2016-05-04T14:27:29.766570Z",
  "name": "Repo Detail",
  "pattern": "(?P.+)",
  "enabled": true,
  "request": {
    "url_template": "https://api.github.com/repos/{{state_context.username.pattern.username}}/{{ pattern.repo }}",
    "method": "Get",
    "data": null,
    "url_parameters": [],
    "header_parameters": []
  },
  "response": {
    "text_template": "{% if response.status == 404 %} Repository {{ pattern.repo }} from {{ pattern.username}} not found {{ emoji.cross_mark}}\\n Select one from menu{% else %} {% if service == 'telegram' %} {{ response.data.name }}: {{ response.data.description}}{% else %} {{ response.data.name}} with url {{response.data.html_url }}: {{ response.data.description }}{% endif %}\\n Select repo or go back{% endif %}",
    "keyboard_template": "[['Back']{% for repo in state_context.user_detail.response.data %}{% if loop.first %},{% endif %}['{{repo.name}}']{% if not loop.last %},{% endif %}{% endfor%}]"
  },
  "target_state": null,
  "source_states": [],
  "priority": 0
}



POST /api/v1/bots/799e96f2-93eb-44eb-918c-c5bd14560c54/handlers/fa00fc42-48f2-4668-a9b5-e37aceda26e1/sourcestates/ HTTP/1.1
Host: www.permabots.com
Authorization: Token yourpermabotstoken
Content-Type: application/json
{
    "name": "Repo"
}



}
{
  "id": "fce06ff0-889f-400c-a01a-99f90c9f48be",
  "created_at": "2016-05-04T14:23:24.058554Z",
  "updated_at": "2016-05-04T14:23:24.058601Z",
  "name": "Repo"
}


POST /api/v1/bots/799e96f2-93eb-44eb-918c-c5bd14560c54/handlers/ HTTP/1.1
Host: www.permabots.com
Authorization: Token yourpermabotstoken
Content-Type: application/json
{
    "name": "Back from Repo Detail",
    "enabled": true,
    "pattern": "Back",
    "request": {"url_template": "https://api.github.com/users/{{ state_context.username.pattern.username}}",
                "method": "Get"},
    "response": {"text_template": "{% if service == 'telegram' %}{{ response.data.login }}{% else %}{{ response.data.login }} with url {{ response.data.html_url}}{% endif %} it has {{ response.data.public_repos }} public repos and {{ response.data.followers}} followers\\n View repos or go back",
                 "keyboard_template": "{% if response.status == 200 %}[['Repos'],['Back']]{% endif %}"
    },
    "target_state": {"name": "User Detail"},
    "priority": 1,
}


{
  "id": "72264903-0748-45fd-b9a4-78a2e1185f22",
  "created_at": "2016-05-04T14:28:18.617941Z",
  "updated_at": "2016-05-04T14:28:18.617965Z",
  "name": "Back from Repo Detail",
  "pattern": "Back",
  "enabled": true,
  "request": {
    "url_template": "https://api.github.com/users/{{ state_context.username.pattern.username}}",
    "method": "Get",
    "data": null,
    "url_parameters": [],
    "header_parameters": []
  },
  "response": {
    "text_template": "{% if service == 'telegram' %}{{ response.data.login }}{% else %}{{ response.data.login }} with url {{ response.data.html_url}}{% endif %} it has {{ response.data.public_repos }} public repos and {{ response.data.followers}} followers\\n View repos or go back",
    "keyboard_template": "{% if response.status == 200 %}[['Repos'],['Back']]{% endif %}"
  },
  "target_state": {
    "id": "dfdab2ff-d50c-4d6f-8e47-fc4ab5399559",
    "created_at": "2016-05-04T14:23:10.262180Z",
    "updated_at": "2016-05-04T14:23:10.262211Z",
    "name": "User Detail"
  },
  "source_states": [],
  "priority": 1
}




POST /api/v1/bots/799e96f2-93eb-44eb-918c-c5bd14560c54/handlers/72264903-0748-45fd-b9a4-78a2e1185f22/sourcestates/ HTTP/1.1
Host: www.permabots.com
Authorization: Token yourpermabotstoken
Content-Type: application/json
{
    "name": "Repo"
}


{
  "id": "fce06ff0-889f-400c-a01a-99f90c9f48be",
  "created_at": "2016-05-04T14:23:24.058554Z",
  "updated_at": "2016-05-04T14:23:24.058601Z",
  "name": "Repo"
}

Notice how we set priority to this handler ir order to avoid collisions. Otherwise it will take "Back" as parameter to look for repository details.

Environment

Permabots allow you to declare key value variables shared in all bot.

We need to generate client_key and client_secret_key from Github. Not to get banned quickly.


POST /api/v1/bots/799e96f2-93eb-44eb-918c-c5bd14560c54/env/ HTTP/1.1
Host: www.permabots.com
Authorization: Token yourpermabotstoken
Content-Type: application/json
{
    "key": "client_id",
    "value": "yourgithubclientid"
    
}



{
  "id": "e2c2a556-a493-4594-9e4a-f7966a8945c6",
  "created_at": "2016-05-04T14:29:40.825853Z",
  "updated_at": "2016-05-04T14:29:40.825902Z",
  "key": "client_id",
  "value": "yourgithubclientid"
}



POST /api/v1/bots/799e96f2-93eb-44eb-918c-c5bd14560c54/env/ HTTP/1.1
Host: www.permabots.com
Authorization: Token yourpermabotstoken
Content-Type: application/json
{
    "key": "client_secret",
    "value": "yourgithubclientsecret"
    
}



{
  "id": "0f65b649-c95f-41a7-b600-9f06c713132e",
  "created_at": "2016-05-04T14:29:40.825853Z",
  "updated_at": "2016-05-04T14:29:40.825902Z",
  "key": "client_secret",
  "value": "yourgithubclientsecret"
}


Environment variables are attached in context and used to render templates {{env.client_id }}.

Request Url and Header Parameters

Handler requests can have some parameters in the url and in the header. In our bot we should attach some url parameters to the Github request to avoid getting banned quickly. Don't hard code these values, use env.


POST /api/v1/bots/799e96f2-93eb-44eb-918c-c5bd14560c54/handlers/1861cdd7-72aa-413e-b628-328c7087d00b/urlparams/ HTTP/1.1
Host: www.permabots.com
Authorization: Token yourpermabotstoken
Content-Type: application/json
{
    "key": "client_secret",
    "value_template": "{{env.client_secret}}"
    
}


{
  "id": "e83566ae-1d8c-4ab7-96e5-66fdb17d9b17",
  "created_at": "2016-05-04T14:30:30.780113Z",
  "updated_at": "2016-05-04T14:30:30.780167Z",
  "key": "client_secret",
  "value_template": "{{env.client_secret}}"
}


POST /api/v1/bots/799e96f2-93eb-44eb-918c-c5bd14560c54/handlers/1861cdd7-72aa-413e-b628-328c7087d00b/urlparams/ HTTP/1.1
Host: www.permabots.com
Authorization: Token yourpermabotstoken
Content-Type: application/json
{
    "key": "client_id",
    "value_template": "{{env.client_id}}"
    
}


{
  "id": "f2c92c74-b1d2-4d5f-a702-8aafe9a13cb8",
  "created_at": "2016-05-04T14:30:46.335365Z",
  "updated_at": "2016-05-04T14:30:46.335395Z",
  "key": "client_id",
  "value_template": "{{env.client_id}}"
}


POST /api/v1/bots/799e96f2-93eb-44eb-918c-c5bd14560c54/handlers/dbb5d6f1-1a51-4db0-a9f3-b639a4064a94/urlparams/ HTTP/1.1
Host: www.permabots.com
Authorization: Token yourpermabotstoken
Content-Type: application/json
{
    "key": "client_secret",
    "value_template": "{{env.client_secret}}"
    
}


{
  "id": "eb2ff24e-6352-47b5-8907-000355a10062",
  "created_at": "2016-05-04T14:31:01.181979Z",
  "updated_at": "2016-05-04T14:31:01.182008Z",
  "key": "client_secret",
  "value_template": "{{env.client_secret}}"
}


POST /api/v1/bots/799e96f2-93eb-44eb-918c-c5bd14560c54/handlers/dbb5d6f1-1a51-4db0-a9f3-b639a4064a94/urlparams/ HTTP/1.1
Host: www.permabots.com
Authorization: Token yourpermabotstoken
Content-Type: application/json
{
    "key": "client_id",
    "value_template": "{{env.client_id}}"
    
}


{
  "id": "ce2cecc5-e81a-47a5-94ec-bf799d22eced",
  "created_at": "2016-05-04T14:31:12.475815Z",
  "updated_at": "2016-05-04T14:31:12.475866Z",
  "key": "client_id",
  "value_template": "{{env.client_id}}"
}


POST /api/v1/bots/799e96f2-93eb-44eb-918c-c5bd14560c54/handlers/72264903-0748-45fd-b9a4-78a2e1185f22/urlparams/ HTTP/1.1
Host: www.permabots.com
Authorization: Token yourpermabotstoken
Content-Type: application/json
{
    "key": "client_secret",
    "value_template": "{{env.client_secret}}"
    
}


{
  "id": "5d94182d-a37c-4b02-9942-0ef05051a838",
  "created_at": "2016-05-04T14:31:22.401526Z",
  "updated_at": "2016-05-04T14:31:22.401556Z",
  "key": "client_secret",
  "value_template": "{{env.client_secret}}"
}


POST /api/v1/bots/799e96f2-93eb-44eb-918c-c5bd14560c54/handlers/72264903-0748-45fd-b9a4-78a2e1185f22/urlparams/ HTTP/1.1
Host: www.permabots.com
Authorization: Token yourpermabotstoken
Content-Type: application/json
{
    "key": "client_id",
    "value_template": "{{env.client_id}}"
    
}


{
  "id": "7daeb459-d1b5-4353-aab4-738815ec409f",
  "created_at": "2016-05-04T14:31:34.579262Z",
  "updated_at": "2016-05-04T14:31:34.579313Z",
  "key": "client_id",
  "value_template": "{{env.client_id}}"
}


POST /api/v1/bots/799e96f2-93eb-44eb-918c-c5bd14560c54/handlers/fa00fc42-48f2-4668-a9b5-e37aceda26e1/urlparams/ HTTP/1.1
Host: www.permabots.com
Authorization: Token yourpermabotstoken
Content-Type: application/json
{
    "key": "client_secret",
    "value_template": "{{env.client_secret}}"
    
}


{
  "id": "f17708d1-9113-41af-8ae5-045c0363ce89",
  "created_at": "2016-05-04T14:31:46.424320Z",
  "updated_at": "2016-05-04T14:31:46.424351Z",
  "key": "client_secret",
  "value_template": "{{env.client_secret}}"
}


POST /api/v1/bots/799e96f2-93eb-44eb-918c-c5bd14560c54/handlers/fa00fc42-48f2-4668-a9b5-e37aceda26e1/urlparams/ HTTP/1.1
Host: www.permabots.com
Authorization: Token yourpermabotstoken
Content-Type: application/json
{
    "key": "client_id",
    "value_template": "{{env.client_id}}"
    
}


{
  "id": "94b86a39-9c95-4b4a-91a2-9f422417a53c",
  "created_at": "2016-05-04T14:31:59.334883Z",
  "updated_at": "2016-05-04T14:31:59.334912Z",
  "key": "client_id",
  "value_template": "{{env.client_id}}"
}

Next steps

You now know how to build a Permabot for Telegram using, handlers, context, states, environment and request parameters. Visit API docs to learn more about Permabots.

Some more upcoming docs will explain how to use Hooks. A mechanism to send messages to clients as notifications when your API requires.

You can try this bot with your Telegram client or search permagithubtutorial with your Kik client.