[{"data":1,"prerenderedAt":45},["Reactive",2],{"featurePages":3,"blogPosts-manage-external-service-callbacks-with-local-tunnel":4},[],{"slug":5,"id":6,"uuid":7,"title":8,"html":9,"comment_id":6,"feature_image":10,"featured":11,"visibility":12,"created_at":13,"updated_at":14,"published_at":15,"custom_excerpt":16,"codeinjection_head":17,"codeinjection_foot":17,"custom_template":17,"canonical_url":18,"tags":19,"authors":33,"primary_author":40,"primary_tag":41,"url":42,"excerpt":16,"reading_time":43,"access":44,"comments":11,"og_image":17,"og_title":17,"og_description":17,"twitter_image":17,"twitter_title":17,"twitter_description":17,"meta_title":8,"meta_description":17,"email_subject":17,"frontmatter":17,"feature_image_alt":17,"feature_image_caption":17},"manage-external-service-callbacks-with-local-tunnel","610cd46fb9956c0555c7f79b","4679c264-8e80-4af8-8875-ca2d0363364a","Access localhost from the internet – External service callbacks made easy with LocalTunnel","\u003Cp>\u003Cem>Improve development experience with external service callbacks from Facebook, Twitter, Twilio etc., using LocalTunnel.\u003C/em>\u003C/p>\u003Ch2 id=\"working-with-third-party-integrations\">Working with third-party integrations\u003C/h2>\u003Cp>As a product developer, one of the biggest pain points that you come across might be related to working with callbacks (mostly webhooks) from third party systems in your local development environment. Most of us use some tunnelling software to expose our local server to the internet and then use that URL for the callbacks.\u003C/p>\u003Cp>There are some pain points with this setup. Usually, tunnelling software has this annoying side-effect of changing the exposed URL every time you restart. If you have shared it with your colleagues for testing, you would have to send the new URL again. If you are working on the webhook callbacks with third-party integrations, like Facebook, Twitter, Zapier, Twilio, etc., this becomes frustrating. Every time you restart the tunnel, you have to go to the developer console and update the callback URL. This workflow is cumbersome, and often we forget this and spend a good amount of time debugging on other things.\u003C/p>\u003Ch2 id=\"chatwoots-context\">Chatwoot's Context\u003C/h2>\u003Cp>At Chatwoot, we have multi-channel support and have inbox support for Facebook, Twitter, Twilio, Slack, chatbots, and various email platforms. We constantly struggled with this problem.\u003C/p>\u003Cp>One way to mitigate the problem was by getting individual paid accounts for every team member and get a static URL for the tunnel. This approach solved some of the issues as we don't need to update the callback URLs every time we restart the local system. For the entire period of development, the URL stays the same.\u003C/p>\u003Cp>Everything seemed good initially. After some time, we started running into problems again with this setup. When multiple engineers work on a single integration, they have to change the callback URL to their tunnel URL whenever they work on it. Nobody called dibs on this, and often we forget to check the callback URL when we start the work. We were on the path to expand our integrations as a part of the omnichannel support and we wanted a better development experience.\u003C/p>\u003Cp>We needed the API callback URLs to stay constant, and it should be easy for any developer to get hold of that tunnel URL. As a possible solution, we looked for open source tunnelling softwares that we could host and customize. That is when we came across LocalTunnel and fell in love with it.\u003C/p>\u003Ch2 id=\"what-is-localtunnel\">What is LocalTunnel?\u003C/h2>\u003Cp>LocalTunnel exposes your localhost to the world for easy testing and sharing. It is an open-source software. (\u003Ca target=\"_blank\" rel=\"noopener\" href=\"https://github.com/localtunnel/localtunnel?ref=www-internal-blog.chatwoot.com\">https://github.com/localtunnel/localtunnel\u003C/a>). From the number of stars and forks of this project, you can see that the community loves this product.\u003C/p>\u003Ch2 id=\"how-did-we-set-it-up\">How did we set it up?\u003C/h2>\u003Cp>We decided to set up our own LocalTunnel on a Digital Ocean droplet. We followed \u003Ca target=\"_blank\" rel=\"noopener\" href=\"https://medium.com/quark-works/running-your-own-reverse-proxy-with-localtunnel-b1658e239c35?ref=www-internal-blog.chatwoot.com\">this\u003C/a> excellent article written by Alex to host LocalTunnel on Digital Ocean. In addition to the setup guide, we had to open a range of ports on the droplet to allow TCP connections.\u003C/p>\u003Cp>We pointed one of the subdomains to the droplet that runs LocalTunnel, which looks something like \u003Ccode>https://tunnel.example.com\u003C/code>.\u003C/p>\u003Ch2 id=\"development-workflow\">Development Workflow\u003C/h2>\u003Cp>To start working with LocalTunnel, you have to install the LocalTunnel client on your machine using the following command.\u003C/p>\u003Cpre>\u003Ccode class=\"language-bash\">npm install -g localtunnel\n\u003C/code>\u003C/pre>\u003Cp>You can connect to the LocalTunnel server by specifying the port and a host name.\u003C/p>\u003Cpre>\u003Ccode class=\"language-bash\">lt --port 3000 --host http://tunnel.example.com\n\u003C/code>\u003C/pre>\u003Cp>By default, LocalTunnel would generate a subdomain using random characters. The URL would look like \u003Ccode>https://[random-characters].tunnel.example.com\u003C/code>\u003C/p>\u003Cp>In addition to this, LocalTunnel allows you to request a named subdomain on the LocalTunnel server.\u003C/p>\u003Cpre>\u003Ccode class=\"language-bash\">lt --port 3000 --host http://tunnel.example.com --subdomain customsubdomain\n\u003C/code>\u003C/pre>\u003Cp>This feature allowed us to standardize the list of subdomains to the external services as seen below:\u003C/p>\u003C!--kg-card-begin: html-->\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Service\u003C/th>\n\u003Cth>Subdomain\u003C/th>\n\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>Facebook\u003C/td>\n\u003Ctd>fb-dev.tunnel.example.com\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>Sendgrid\u003C/td>\n\u003Ctd>sendgrid-dev.tunnel.example.com\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>Mailgun\u003C/td>\n\u003Ctd>mailgun-staging.tunnel.example.com\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>Twitter\u003C/td>\n\u003Ctd>twitter-staging.tunnel.example.com\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>Twilio\u003C/td>\n\u003Ctd>twilio-dev.tunnel.example.com\u003C/td>\n\u003C/tr>\n\u003C/tbody>\n\u003C/table>\u003C!--kg-card-end: html-->\u003Cp>An important thing to note here is that when we use a subdomain, for example, Facebook development as \u003Ccode>fb-dev.tunnel.example.com\u003C/code>, we set all the callbacks on the Facebook developer account to this subdomain. Similarly, we set the callback URL on the Twitter developer account for Twitter app development to \u003Ccode>twitter-dev.tunnel.example.com\u003C/code> and so on.\u003C/p>\u003Cp>For working on Facebook inbox, we would connect to the standard tunnel URL:\u003C/p>\u003Cpre>\u003Ccode class=\"language-bash\">lt --host http://tunnel.example.com --subdomain fb-dev --port 3000\n\u003C/code>\u003C/pre>\u003Cp>With this approach, we solved both problems mentioned above.\u003C/p>\u003Col>\u003Cli>Now that you had a standard set of URLs, you don't have to go to the developer console every time to change it.\u003C/li>\u003Cli>Any team member can get hold of any of these tunnels using their LocalTunnel Client seamlessly.\u003C/li>\u003C/ol>\u003Cp>This approach has improved our development workflow to a great extend. The developers don't have to worry about the URL they would use in development. If they conform to the standard URL, everything works seamlessly.\u003C/p>\u003Cp>Let us know if you have any questions or if this article helped you in improving your development experience. We are all ears. :)\u003C/p>","https://www-internal-blog.chatwoot.com/content/images/2021/08/local_tunnel_ts.png",false,"public","2021-08-06T06:19:27.000+00:00","2022-09-20T09:27:19.000+00:00","2021-05-06T06:20:00.000+00:00","Improve development experience with external service callbacks from Facebook, Twitter, Twilio etc., using LocalTunnel. Working with third-party integrations As a product developer, one of the biggest pain points that you come across might be related to working with…",null,"https://www.chatwoot.com/blog/manage-external-service-callbacks-with-local-tunnel",[20,24],{"id":21,"name":22,"slug":22,"description":17,"feature_image":17,"visibility":12,"og_image":17,"og_title":17,"og_description":17,"twitter_image":17,"twitter_title":17,"twitter_description":17,"meta_title":17,"meta_description":17,"codeinjection_head":17,"codeinjection_foot":17,"canonical_url":17,"accent_color":17,"url":23},"6118da864b8f26503f72d530","blog","https://www-internal-blog.chatwoot.com/tag/blog/",{"id":25,"name":26,"slug":27,"description":28,"feature_image":17,"visibility":12,"og_image":17,"og_title":17,"og_description":17,"twitter_image":17,"twitter_title":17,"twitter_description":17,"meta_title":29,"meta_description":30,"codeinjection_head":17,"codeinjection_foot":17,"canonical_url":31,"accent_color":17,"url":32},"6308cfbf730b190d1c2d7f42","Engineering","engineering","We're always experimenting with new features and complex solutions, as well as improving our existing offerings. Read about how we do it, directly from Chatwoot engineers.","Engineering Blog | Learnings, tips, stories from Chatwoot Engineers","We're always experimenting with new features, & complex solutions, & improving our existing offerings. Read about how we do it – written by our engineers.","https://www.chatwoot.com/tags/engineering","https://www-internal-blog.chatwoot.com/tag/engineering/",[34],{"id":35,"name":36,"slug":37,"profile_image":38,"cover_image":17,"bio":17,"website":17,"location":17,"facebook":17,"twitter":17,"meta_title":17,"meta_description":17,"url":39},"6118d8e34b8f26503f72d51e","Sony Mathew","sony","https://www-internal-blog.chatwoot.com/content/images/2021/08/zQK4swoV_400x400.jpg","https://www-internal-blog.chatwoot.com/author/sony/",{"id":35,"name":36,"slug":37,"profile_image":38,"cover_image":17,"bio":17,"website":17,"location":17,"facebook":17,"twitter":17,"meta_title":17,"meta_description":17,"url":39},{"id":21,"name":22,"slug":22,"description":17,"feature_image":17,"visibility":12,"og_image":17,"og_title":17,"og_description":17,"twitter_image":17,"twitter_title":17,"twitter_description":17,"meta_title":17,"meta_description":17,"codeinjection_head":17,"codeinjection_foot":17,"canonical_url":17,"accent_color":17,"url":23},"https://www-internal-blog.chatwoot.com/manage-external-service-callbacks-with-local-tunnel/",3,true,1775212115580]