How to Create a Contact Form using Telegram Bot API

Collect your visitors' form submissions on Telegram

Hello! Welcome to Fineshop Design.

As we know, Blogger Contact Form API was updated recently and now it requires a token each an every time to successfully submit the form, that means you need to add Contact Form Widget through Layout which results in slow page loading due to blogger widgets javascripts, which we were using in only the form page earlier. Most of Bloggers use Telegram, so I have come up with a new post titled How to Create a Contact Form using Telegram Bot API.

Today, I will share codes which will allow you to receive the form submissions directly to your Telegram Group. You can also add extra fields in this form, i.e. Mobile Number, Website or anything, which was not possible in Blogger Contact Form.

This is an educational tutorial. Please consider using it for good intension.

Contact Form - Telegram Bot API
© Fineshop Design | Contact Form

Before we start let's take a look at its Demo.

Requirements

  1. A telegram bot, if you don't have, you can read documentation here. Bot API token is required.
  2. A Telegram Group's ID, for that create a private group, login to Telegram Web, open the group you will get Group ID in url, i.e. -1200190470, add 100 just after - sign and before 1200190470, now the chat id will be -1001200190470 just note it. Don't forget to add the bot in your group.

It is not recommended to use a supergroup, as anyone having the groupname can easily join and read your visitors' submissions.

Limitations

  1. User cannot send messages containing more than 3000 chars as Telegram has a limit when sending message of more than 4096 chars. To make sure all the submissions are successful, we have to set a limit of less than 4096 chars that is 3000 chars.

How to Create a Contact Form?

Step 1: First of all Login to your Blogger Dashboard.

Step 2: On Blogger Dashboard, click Pages.

Step 3: Either create a new page by clicking on icon or click on the existing page to add codes there.

Step 4: Switch to HTML view.

Step 5: Paste the following codes in it and Publish your page.

<style>
/* Toast Notification */
.tNtf span{position:fixed;left:24px;bottom:-70px;display:inline-flex;align-items:center;text-align:center;justify-content:center;margin-bottom:20px;z-index:99981;background:#323232;color:rgba(255,255,255,.8);font-size:14px;font-family:inherit;border-radius:3px;padding:13px 24px; box-shadow:0 5px 35px rgba(149,157,165,.3);opacity:0;transition:all .1s ease;animation:slideinwards 2s ease forwards;-webkit-animation:slideinwards 2s ease forwards}
@media screen and (max-width:500px){.tNtf span{margin-bottom:20px;left:20px;right:20px;font-size:13px}}
@keyframes slideinwards{0%{opacity:0}20%{opacity:1;bottom:0}50%{opacity:1;bottom:0}80%{opacity:1;bottom:0}100%{opacity:0;bottom:-70px;visibility:hidden}}
@-webkit-keyframes slideinwards{0%{opacity:0}20%{opacity:1;bottom:0}50%{opacity:1;bottom:0}80%{opacity:1;bottom:0}100%{opacity:0;bottom:-70px;visibility:hidden}}
.drK .tNtf span{box-shadow:0 10px 40px rgba(0,0,0,.2)}
</style>

<!--[ Toast Notification ]-->
<div id='toast_notification' class='tNtf'></div>

<!--[ Form ]-->
<form id="telegram_form">
  <input name="name" type="text" placeholder="Name" />
  <input name="email" type="text" placeholder="Email Address" />
  <input name="phone" type="text" placeholder="Phone Number" />
  <input name="files" type="file" placeholder="Attachments" multiple="true" />
  <textarea name="message" placeholder="Message"></textarea>
  <button type="submit">Submit</button>
</form>

<script>
/*! Telegram Bot Form Handler by Fineshop Design */
function handleTelegram(e={}){const t={get title(){return document.title},get homepage(){return c.origin},get page(){this.homepage,c.pathname}},r={stringify:e=>`${"string"==typeof e?e:JSON.stringify(e)}`,escapeHTML:e=>e.replace(/&/g,"&amp;").replace(/>/g,"&gt;").replace(/>/g,"&lt;"),objectToFormData(e){const t=new FormData,r=(e,r,n)=>{["string","number","boolean"].includes(typeof r)?t.append(e,`${r}`):r instanceof Blob&&t.append(e,r,n)};return Object.keys(e).forEach((t=>{const n=e[t];Array.isArray(n)?n.forEach((e=>r(t,e))):r(t,n)})),t},getFormData(e){const t=Object.defineProperties({},{toArray:{value(){return Object.keys(this).map((e=>this[e]))}},toValues:{value(){return Object.keys(this).reduce(((e,t)=>(e[t]=this[t].value,e)),{})}}}),{elements:r}=e,n=Object.keys(r).map((e=>r[e].name)).filter(((e,t,r)=>r.indexOf(e)===t&&e));for(let e=0;e<n.length;e+=1){const o=n[e],a=r[o],i={element:a,name:o,type:a.type};switch(a.type){case"checkbox":i.value=a.checked;break;case"file":i.value=Array.from(a.files),i.multiple=a.multiple;break;case"select-multiple":i.value=Array.from(a.options).filter((e=>e.selected)).map((e=>e.value));break;case"date":case"datetime-local":i.value=[""===a.value?null:a.value,isNaN(a.valueAsNumber)?null:a.valueAsNumber];break;default:i.value=""===a.value?null:a.value}t[o]=i}return t}},n={error(r,n){if("function"!=typeof e.onError)throw r;e.onError(r,n,t)},validate:(r,n)=>"function"!=typeof e.validate||!0===e.validate(r,n,t),submit(r,n,o){"function"==typeof e.onSubmit&&e.onSubmit(r,n,o,t)},sent(r,n,o){"function"==typeof e.onSent&&e.onSent(r,n,o,t)},notSent(r,n,o,a){"function"==typeof e.onNotSent&&e.onNotSent(r,n,o,a,t)},complete(r,n,o,a){"function"==typeof e.onComplete&&e.onComplete(r,n,o,a,t)},format(n,o,a){if("function"==typeof e.format){const r=e.format(n,o,a,t);if("string"==typeof r)return r}let i="";return Object.keys(n).forEach((e=>{const t=n[e];"file"!==t.type&&(i&&(i+="\n\n"),i+=`Field: ${r.escapeHTML(e)}\nValue: <pre><code>${r.escapeHTML("string"==typeof t.value?t.value:JSON.stringify(t.value))}</code></pre>`)})),i},caption(n,o,a,i){if("function"==typeof e.caption){const r=e.caption(n,o,a,i,t);if("string"==typeof r)return r}return`Field: ${r.escapeHTML(o.name)}\nName: ${r.escapeHTML(n.name)}\nType: ${r.escapeHTML(n.type)}\nModified at: ${new Date(n.lastModified).toJSON()}`}},{form:o,token:a,chat:i,thread:s}=e,{location:c}=window,l=()=>{};if(!o instanceof HTMLFormElement)return n.error(new TypeError("Field 'form' must be an HTMLFormElement")),l;if("string"!=typeof a)return n.error(new TypeError("Field 'token' must be of type string"),o),l;if("string"!=typeof i&&"number"!=typeof i)return n.error(new TypeError("Field 'chat' must be of type string or number"),o),l;if("thread"in e&&"string"!=typeof s&&"number"!=typeof s)return n.error(new TypeError("Field 'thread' must be of type string or number"),o),l;const p=(e=>({get token(){return e},get url(){return`https://api.telegram.org/bot${this.token}`},async request(e,t){const n=`${this.url}/${e}`;let o=t;t&&(o.reply_markup||o.entities)&&(o={...t},o.reply_markup&&(o.reply_markup=r.stringify(o.reply_markup)),o.entities&&(o.entities=r.stringify(o.entities)));const a=o?r.objectToFormData(o):void 0,i=new Request(n,{method:"POST",body:a,headers:{Accept:"application/json"}}),s=await fetch(i).then((e=>{const t=e.headers.get("Content-Type");return t&&t.startsWith("application/json")?e.json():null}));if(s){if(s.ok)return s.result;if(s.description)throw new Error(s.description)}throw new Error("Response is invalid")},async sendMessage(e,t,r){return this.request("sendMessage",{...r,chat_id:e,text:t})},async sendMediaGroup(e,t,n){const o={};return t&&t.forEach(((e,r)=>{if(e&&e.media instanceof Blob){const n=`file_attach_id_${r}`;o[n]=e.media,t[r]={...e,media:`attach://${n}`}}})),this.request("sendMediaGroup",{...n,...o,chat_id:e,media:r.stringify(t)})}}))(a),u=e=>{e.preventDefault();const a=r.getFormData(o);if(n.submit(e,a,o),n.validate(a,t,o)){const e=a.toArray().filter((e=>"file"===e.type)).reduce(((e,t)=>(t.value.forEach((r=>{const i=n.caption(r,t,a,o);e.push({type:"document",media:r,caption:i,parse_mode:"html"})})),e)),[]);if(0!==e.length){e[e.length-1].caption+=`\n\n${n.format(a,e,o)}`,p.sendMediaGroup(i,e,{message_thread_id:s}).then((e=>{try{n.sent(e,a,o),n.complete(!0,e,a,o)}catch(e){n.error(e,o)}})).catch((e=>{n.notSent(e,"bot",a,o),n.error(e,o),n.complete(!1,e,a,o)}))}else p.sendMessage(i,n.format(a,void 0,o),{message_thread_id:s,parse_mode:"html"}).then((e=>{try{n.sent(e,a,o),n.complete(!0,e,a,o)}catch(e){n.error(e,o)}})).catch((e=>{n.notSent(e,"bot",a,o),n.error(e,o),n.complete(!1,e,a,o)}))}else{const e=new Error("Validation Failed");n.notSent(e,"validation",a,o),n.complete(!1,e,a,o)}};return o.addEventListener("submit",u),()=>{o.removeEventListener("submit",u)}}
</script>

<script>
// Toast Notification function
function toast(m){
  var e = document.getElementById('toast_notification');
  if (e !== null) {
    e.innerHTML = `<span>${m}</span>`
  } else {
    alert(m);
  }
};

const formElement = document.getElementById("telegram_form");
const submitButton = formElement.querySelector("button");

// Attach onSubmit Event listener and send data to telegram
const unsubscribe = handleTelegram({
  form: formElement,
  token: "208*******:AAG*******_**********-7*********Z0I",
  chat: -1002200000000,

  // Formatting
  format(data, media, form) {},
  caption(file, field, data, form) {},

  // Validation
  validate(data, form) {
    if (!data.name.value) {
      data.name.element.focus();
      return toast("Enter your name!");
    }

    if (!data.email.value) {
      data.email.element.focus();
      return toast("Enter your email!")
    }

    return true;
  },

  // Callbacks
  onSubmit(event, data, form) {
    submitButton.disabled = true;
  },
  onComplete(success, response, data, form) {
    submitButton.disabled = false;
  },
  onSent(response, data, form) {
    toast(`Hey, ${data.name.value}! Form submitted!`);
    // Reset form after submission
    formElement.reset();
  },
  onNotSent(error, reason, data, form) {
    if (reason !== "validation") {
      toast(`Form failed to submit! (${(error || {}).message || "Unknown"})`);
    }
  },
  onError(error, form) {
    console.log(error)
  },
});

// Call the unsubscribe function to remove listener
// unsubscribe();
</script>

Replace the marked parts with correct informations.

It is not at all safe to make your Bot API Token publicly available. Use any javascript obfuscator to obfuscate the Forms Configuration codes after making all the changes. You can revoke and generate new API Token of your bot through Bot Father at any time you think something is going wrong with the bot token.

Conclusion

This is all about making a Contact Form using Telegram Bot API. I hope you enjoy this article. Please do share this article. And if you are facing problem in any section or you have any question then ask us in .

© Copyright:
www.fineshopdesign.com

About the author

Deo Kumar
deo@fineshopdesign:~$ echo "Hello World!"

9 comments

  1. Chocolate con leche
    Chocolate con leche
    How can I know the chat ID?
    1. Deo Kumar
      Deo Kumar
      Login to Telegram Web, open the group you will get Group ID in url.
    2. Farhan
      Farhan
      I followed every steps.And when I tried to send a message via contact us page,It shows "An error occured".
    3. M. M. Anik
      M. M. Anik
      Just awesome. Perfectly working. Thank you so much
    4. Deo Kumar
      Deo Kumar
      @Farhan Have you added the correct Group Chat ID? Also make sure bot is in that group.
    5. Yacine Bagua
      Yacine Bagua
      @Deo K. i follow step by step and still have the same problem , is "An error occured" , i need help
    6. Deo Kumar
      Deo Kumar
      @Yacine, Make sure you have put the correct details. Or can you share your page link?
  2. Thabresh Syed
    Thabresh Syed
    I followed every steps.And when I tried to send a message via contact us page,It shows "An error occured". please help
    1. Deo Kumar
      Deo Kumar
      Make sure you have added the correct Chat ID
To avoid SPAM, all comments will be moderated before being displayed.