Blog

  • hkm2014ESA

    #hkm2014ESAPoster

    This is the source for ESA PS1-12

    EPA Disclaimer

    The United States Environmental Protection Agency (EPA) GitHub project code is provided on an “as is” basis and the user assumes responsibility for its use. EPA has relinquished control of the information and no longer has responsibility to protect the integrity , confidentiality, or availability of the information. Any reference to specific commercial products, processes, or services by service mark, trademark, manufacturer, or otherwise, does not constitute or imply their endorsement, recomendation or favoring by EPA. The EPA seal and logo shall not be used in any manner to imply endorsement of any commercial product or activity by EPA or the United States Government.

    Visit original content creator repository
    https://github.com/USEPA/hkm2014ESA

  • forest

    logo

    JDK License Documentation Author

    Forest – 声明式HTTP客户端框架

    项目介绍:

    Forest是一个高层的、极简的声明式HTTP调用API框架
    相比于直接使用Httpclient您不再用写一大堆重复的代码了,而是像调用本地方法一样去发送HTTP请求

    获得荣誉

    • 2021 年度 OSC 中国开源项目评选「最受欢迎项目」
    • 2022 年度 OSC 中国开源项目评选「最火热中国开源项目社区」

    文档和示例:

    Forest有哪些特性?

    • 同时支持编程式与声明式的请求发送方式
    • 以Httpclient和OkHttp为后端框架
    • 通过调用本地方法的方式去发送Http请求, 实现了业务逻辑与Http协议之间的解耦
    • 因为针对第三方接口,所以不需要依赖Spring Cloud和任何注册中心
    • 支持所有请求方法:GET, HEAD, OPTIONS, TRACE, POST, DELETE, PUT, PATCH
    • 支持文件上传和下载
    • 支持灵活的模板表达式
    • 支持拦截器处理请求的各个生命周期
    • 支持自定义注解
    • 支持OAuth2验证
    • 支持过滤器来过滤传入的数据
    • 基于注解、配置化的方式定义Http请求
    • 支持Spring和Springboot集成
    • JSON格式数据序列化和反序列化
    • XML格式数据序列化和反序列化
    • Protobuf格式数据序列化和反序列化
    • JSON、XML或其他类型转换器可以随意扩展和替换
    • 支持JSON转换框架: Fastjson2, Fastjson1, Jackson, Gson
    • 支持JAXB形式的XML转换
    • 可以通过OnSuccess和OnError接口参数实现请求结果的回调
    • 配置简单,一般只需要@Request一个注解就能完成绝大多数请求的定义
    • 支持异步请求调用
    • 支持SSE

    极速开始

    以下例子基于Spring Boot

    第一步:添加Maven依赖

    直接添加以下maven依赖即可

    <dependency>
        <groupId>com.dtflys.forest</groupId>
        <artifactId>forest-spring-boot-starter</artifactId>
        <version>${LATEST_VERSION}</version>
    </dependency>

    第二步:创建一个interface

    就以高德地图API为栗子吧

    package com.yoursite.client;
    
    import com.dtflys.forest.annotation.Request;
    import com.dtflys.forest.annotation.DataParam;
    
    public interface AmapClient {
    
        /**
         * 聪明的你一定看出来了@Get注解代表该方法专做GET请求
         * 在url中的{0}代表引用第一个参数,{1}引用第二个参数
         */
        @Get("http://ditu.amap.com/service/regeo?longitude={0}&latitude={1}")
        Map getLocation(String longitude, String latitude);
    }

    第三步:扫描接口

    在Spring Boot的配置类或者启动类上加上@ForestScan注解,并在basePackages属性里填上远程接口的所在的包名

    @SpringBootApplication
    @Configuration
    @ForestScan(basePackages = "com.yoursite.client")
    public class MyApplication {
      public static void main(String[] args) {
          SpringApplication.run(MyApplication.class, args);
       }
    }

    第四步:调用接口

    OK,我们可以愉快地调用接口了

    // 注入接口实例
    @Autowired
    private AmapClient amapClient;
    ...
    // 调用接口
    Map result = amapClient.getLocation("121.475078", "31.223577");
    System.out.println(result);

    发送JSON数据

    /**
     * 将对象参数解析为JSON字符串,并放在请求的Body进行传输
     */
    @Post("/register")
    String registerUser(@JSONBody MyUser user);
    
    /**
     * 将Map类型参数解析为JSON字符串,并放在请求的Body进行传输
     */
    @Post("/test/json")
    String postJsonMap(@JSONBody Map mapObj);
    
    /**
     * 直接传入一个JSON字符串,并放在请求的Body进行传输
     */
    @Post("/test/json")
    String postJsonText(@JSONBody String jsonText);

    发送XML数据

    /**
     * 将一个通过JAXB注解修饰过的类型对象解析为XML字符串
     * 并放在请求的Body进行传输
     */
    @Post("/message")
    String sendXmlMessage(@XMLBody MyMessage message);
    
    /**
     * 直接传入一个XML字符串,并放在请求的Body进行传输
     */
    @Post("/test/xml")
    String postXmlBodyString(@XMLBody String xml);

    发送Protobuf数据

    /**
     * ProtobufProto.MyMessage 为 Protobuf 生成的数据类
     * 将 Protobuf 生成的数据对象转换为 Protobuf 格式的字节流
     * 并放在请求的Body进行传输
     * 
     * 注: 需要引入 google protobuf 依赖
     */
    @Post(url = "/message", contentType = "application/octet-stream")
    String sendProtobufMessage(@ProtobufBody ProtobufProto.MyMessage message);

    文件上传

    /**
     * 用@DataFile注解修饰要上传的参数对象
     * OnProgress参数为监听上传进度的回调函数
     */
    @Post("/upload")
    Map upload(@DataFile("file") String filePath, OnProgress onProgress);

    可以用一个方法加Lambda同时解决文件上传和上传的进度监听

    Map result = myClient.upload("D:\\TestUpload\\xxx.jpg", progress -> {
        System.out.println("progress: " + Math.round(progress.getRate() * 100) + "%");  // 已上传百分比
        if (progress.isDone()) {   // 是否上传完成
            System.out.println("--------   Upload Completed!   --------");
        }
    });

    多文件批量上传

    /**
     * 上传Map包装的文件列表,其中 {_key} 代表Map中每一次迭代中的键值
     */
    @Post("/upload")
    ForestRequest<Map> uploadByteArrayMap(@DataFile(value = "file", fileName = "{_key}") Map<String, byte[]> byteArrayMap);
    
    /**
     * 上传List包装的文件列表,其中 {_index} 代表每次迭代List的循环计数(从零开始计)
     */
    @Post("/upload")
    ForestRequest<Map> uploadByteArrayList(@DataFile(value = "file", fileName = "test-img-{_index}.jpg") List<byte[]> byteArrayList);

    文件下载

    下载文件也是同样的简单

    /**
     * 在方法上加上@DownloadFile注解
     * dir属性表示文件下载到哪个目录
     * OnProgress参数为监听上传进度的回调函数
     * {0}代表引用第一个参数
     */
    @Get("http://localhost:8080/images/xxx.jpg")
    @DownloadFile(dir = "{0}")
    File downloadFile(String dir, OnProgress onProgress);

    调用下载接口以及监听下载进度的代码如下:

    File file = myClient.downloadFile("D:\\TestDownload", progress -> {
        System.out.println("progress: " + Math.round(progress.getRate() * 100) + "%");  // 已下载百分比
        if (progress.isDone()) {   // 是否下载完成
            System.out.println("--------   Download Completed!   --------");
        }
    });

    基本签名验证

    @Post("/hello/user?username={username}")
    @BasicAuth(username = "{username}", password = "bar")
    String send(@DataVariable("username") String username);

    OAuth 2.0

    @OAuth2(
            tokenUri = "/auth/oauth/token",
            clientId = "password",
            clientSecret = "xxxxx-yyyyy-zzzzz",
            grantType = OAuth2.GrantType.PASSWORD,
            scope = "any",
            username = "root",
            password = "xxxxxx"
    )
    @Get("/test/data")
    String getData();

    自定义注解

    Forest允许您根据需要自行定义注解,不但让您可以简单优雅得解决各种需求,而且极大得扩展了Forest的能力。

    定义一个注解

    /**
     * 用Forest自定义注解实现一个自定义的签名加密注解
     * 凡用此接口修饰的方法或接口,其对应的所有请求都会执行自定义的签名加密过程
     * 而自定义的签名加密过程,由这里的@MethodLifeCycle注解指定的生命周期类进行处理
     * 可以将此注解用在接口类和方法上
     */
    @Documented
    /** 重点: @MethodLifeCycle注解指定该注解的生命周期类*/
    @MethodLifeCycle(MyAuthLifeCycle.class)
    @RequestAttributes
    @Retention(RetentionPolicy.RUNTIME)
    /** 指定该注解可用于类上或方法上 */
    @Target({ElementType.TYPE, ElementType.METHOD})
    public @interface MyAuth {
    
        /** 
         * 自定义注解的属性:用户名
         * 所有自定注解的属性可以在生命周期类中被获取到
         */
        String username();
    
        /** 
         * 自定义注解的属性:密码
         * 所有自定注解的属性可以在生命周期类中被获取到
         */
        String password();
    }

    定义注解生命周期类

    /**
     *  MyAuthLifeCycle 为自定义的 @MyAuth 注解的生命周期类
     * 因为 @MyAuth 是针对每个请求方法的,所以它实现自 MethodAnnotationLifeCycle 接口
     * MethodAnnotationLifeCycle 接口带有泛型参数
     * 第一个泛型参数是该生命周期类绑定的注解类型
     * 第二个泛型参数为请求方法返回的数据类型,为了尽可能适应多的不同方法的返回类型,这里使用 Object
     */
    public class MyAuthLifeCycle implements MethodAnnotationLifeCycle<MyAuth, Object> {
    
     
        /**
         * 当方法调用时调用此方法,此时还没有执行请求发送
         * 次方法可以获得请求对应的方法调用信息,以及动态传入的方法调用参数列表
         */
        @Override
        public void onInvokeMethod(ForestRequest request, ForestMethod method, Object[] args) {
            System.out.println("Invoke Method '" + method.getMethodName() + "' Arguments: " + args);
        }
    
        /**
         * 发送请求前执行此方法,同拦截器中的一样
         */
        @Override
        public boolean beforeExecute(ForestRequest request) {
            // 通过getAttribute方法获取自定义注解中的属性值
            // getAttribute第一个参数为request对象,第二个参数为自定义注解中的属性名
            String username = (String) getAttribute(request, "username");
            String password = (String) getAttribute(request, "password");
            // 使用Base64进行加密
            String basic = "MyAuth " + Base64Utils.encode("{" + username + ":" + password + "}");
            // 调用addHeader方法将加密结构加到请求头MyAuthorization中
            request.addHeader("MyAuthorization", basic);
            return true;
        }
    
        /**
         * 此方法在请求方法初始化的时候被调用
         */
        @Override
        public void onMethodInitialized(ForestMethod method, BasicAuth annotation) {
            System.out.println("Method '" + method.getMethodName() + "' Initialized, Arguments: " + args);
        }
    }

    使用自定义的注解

    /**
     * 在请求接口上加上自定义的 @MyAuth 注解
     * 注解的参数可以是字符串模板,通过方法调用的时候动态传入
     * 也可以是写死的字符串
     */
    @Get("/hello/user?username={username}")
    @MyAuth(username = "{username}", password = "bar")
    String send(@DataVariable("username") String username);

    编程式请求

    Forest 的编程式请求支持链式调用,极为方便、高效、简洁

    // GET 请求访问百度
    String baidu = Forest.get("http://www.baidu.com").execute(String.class);
    
    // POST 请求注册用户信息
    String result = Forest.post("/user/register")
            .contentType("application/json")
            .addBody("username", "公子骏")
            .addBody("password", "12345678")
            .execute(String.class);

    详细文档请看:官方文档

    获得奖项

    2021 年度 OSC 中国开源项目评选「最受欢迎项目」

    联系作者

    亲,进群前记得先star一下哦~

    扫描二维码关注公众号,点击菜单中的 进群 按钮即可进群

    avatar

    他们在用

    已在使用Forest的公司列表(排名不分先后)

    华为
    野兽派花店
    吉利集团
    中科院计算所大数据研究院
    人人都是产品经理
    神州通立电梯
    万智维度
    壹润
    尚融网络科技
    华方智联
    趣链科技
    百应
    聚云位智
    嗨宝贝
    仟奇
    朝前智能
    满意吧
    源一科技
    欣网视讯
    嘉之会科技
    星晟工程

    参与贡献

    1. 进群讨论,可以在群里抛出您遇到的问题,或许已经有人解决了您的问题。
    2. 提issue,如果在issue中已经有您想解决的问题,可以直接将该issue分配给您自己。如若没有,可以自己创建一个issue。
    3. Fork 本项目的仓库
    4. 新建分支,如果是加新特性,分支名格式为feat_${issue的ID号},如果是修改bug,则命名为fix_${issue的ID号}
    5. 本地自测,提交前请通过所有的已经单元测试,以及为您要解决的问题新增单元测试。
    6. 提交代码
    7. 新建 Pull Request
    8. 我会对您的PR进行验证和测试,如通过测试,我会合到dev分支上随新版本发布时再合到master分支上。

    欢迎小伙伴们多提issue和PR,被接纳PR的小伙伴我会列在README上的贡献者列表中:)

    项目协议

    The MIT License (MIT)

    Copyright (c) 2016 Jun Gong

    Visit original content creator repository https://github.com/dromara/forest
  • forest

    logo

    JDK License Documentation Author

    Forest – 声明式HTTP客户端框架

    项目介绍:

    Forest是一个高层的、极简的声明式HTTP调用API框架
    相比于直接使用Httpclient您不再用写一大堆重复的代码了,而是像调用本地方法一样去发送HTTP请求

    获得荣誉

    • 2021 年度 OSC 中国开源项目评选「最受欢迎项目」
    • 2022 年度 OSC 中国开源项目评选「最火热中国开源项目社区」

    文档和示例:

    Forest有哪些特性?

    • 同时支持编程式与声明式的请求发送方式
    • 以Httpclient和OkHttp为后端框架
    • 通过调用本地方法的方式去发送Http请求, 实现了业务逻辑与Http协议之间的解耦
    • 因为针对第三方接口,所以不需要依赖Spring Cloud和任何注册中心
    • 支持所有请求方法:GET, HEAD, OPTIONS, TRACE, POST, DELETE, PUT, PATCH
    • 支持文件上传和下载
    • 支持灵活的模板表达式
    • 支持拦截器处理请求的各个生命周期
    • 支持自定义注解
    • 支持OAuth2验证
    • 支持过滤器来过滤传入的数据
    • 基于注解、配置化的方式定义Http请求
    • 支持Spring和Springboot集成
    • JSON格式数据序列化和反序列化
    • XML格式数据序列化和反序列化
    • Protobuf格式数据序列化和反序列化
    • JSON、XML或其他类型转换器可以随意扩展和替换
    • 支持JSON转换框架: Fastjson2, Fastjson1, Jackson, Gson
    • 支持JAXB形式的XML转换
    • 可以通过OnSuccess和OnError接口参数实现请求结果的回调
    • 配置简单,一般只需要@Request一个注解就能完成绝大多数请求的定义
    • 支持异步请求调用
    • 支持SSE

    极速开始

    以下例子基于Spring Boot

    第一步:添加Maven依赖

    直接添加以下maven依赖即可

    <dependency>
        <groupId>com.dtflys.forest</groupId>
        <artifactId>forest-spring-boot-starter</artifactId>
        <version>${LATEST_VERSION}</version>
    </dependency>

    第二步:创建一个interface

    就以高德地图API为栗子吧

    package com.yoursite.client;
    
    import com.dtflys.forest.annotation.Request;
    import com.dtflys.forest.annotation.DataParam;
    
    public interface AmapClient {
    
        /**
         * 聪明的你一定看出来了@Get注解代表该方法专做GET请求
         * 在url中的{0}代表引用第一个参数,{1}引用第二个参数
         */
        @Get("http://ditu.amap.com/service/regeo?longitude={0}&latitude={1}")
        Map getLocation(String longitude, String latitude);
    }

    第三步:扫描接口

    在Spring Boot的配置类或者启动类上加上@ForestScan注解,并在basePackages属性里填上远程接口的所在的包名

    @SpringBootApplication
    @Configuration
    @ForestScan(basePackages = "com.yoursite.client")
    public class MyApplication {
      public static void main(String[] args) {
          SpringApplication.run(MyApplication.class, args);
       }
    }

    第四步:调用接口

    OK,我们可以愉快地调用接口了

    // 注入接口实例
    @Autowired
    private AmapClient amapClient;
    ...
    // 调用接口
    Map result = amapClient.getLocation("121.475078", "31.223577");
    System.out.println(result);

    发送JSON数据

    /**
     * 将对象参数解析为JSON字符串,并放在请求的Body进行传输
     */
    @Post("/register")
    String registerUser(@JSONBody MyUser user);
    
    /**
     * 将Map类型参数解析为JSON字符串,并放在请求的Body进行传输
     */
    @Post("/test/json")
    String postJsonMap(@JSONBody Map mapObj);
    
    /**
     * 直接传入一个JSON字符串,并放在请求的Body进行传输
     */
    @Post("/test/json")
    String postJsonText(@JSONBody String jsonText);

    发送XML数据

    /**
     * 将一个通过JAXB注解修饰过的类型对象解析为XML字符串
     * 并放在请求的Body进行传输
     */
    @Post("/message")
    String sendXmlMessage(@XMLBody MyMessage message);
    
    /**
     * 直接传入一个XML字符串,并放在请求的Body进行传输
     */
    @Post("/test/xml")
    String postXmlBodyString(@XMLBody String xml);

    发送Protobuf数据

    /**
     * ProtobufProto.MyMessage 为 Protobuf 生成的数据类
     * 将 Protobuf 生成的数据对象转换为 Protobuf 格式的字节流
     * 并放在请求的Body进行传输
     * 
     * 注: 需要引入 google protobuf 依赖
     */
    @Post(url = "/message", contentType = "application/octet-stream")
    String sendProtobufMessage(@ProtobufBody ProtobufProto.MyMessage message);

    文件上传

    /**
     * 用@DataFile注解修饰要上传的参数对象
     * OnProgress参数为监听上传进度的回调函数
     */
    @Post("/upload")
    Map upload(@DataFile("file") String filePath, OnProgress onProgress);

    可以用一个方法加Lambda同时解决文件上传和上传的进度监听

    Map result = myClient.upload("D:\\TestUpload\\xxx.jpg", progress -> {
        System.out.println("progress: " + Math.round(progress.getRate() * 100) + "%");  // 已上传百分比
        if (progress.isDone()) {   // 是否上传完成
            System.out.println("--------   Upload Completed!   --------");
        }
    });

    多文件批量上传

    /**
     * 上传Map包装的文件列表,其中 {_key} 代表Map中每一次迭代中的键值
     */
    @Post("/upload")
    ForestRequest<Map> uploadByteArrayMap(@DataFile(value = "file", fileName = "{_key}") Map<String, byte[]> byteArrayMap);
    
    /**
     * 上传List包装的文件列表,其中 {_index} 代表每次迭代List的循环计数(从零开始计)
     */
    @Post("/upload")
    ForestRequest<Map> uploadByteArrayList(@DataFile(value = "file", fileName = "test-img-{_index}.jpg") List<byte[]> byteArrayList);

    文件下载

    下载文件也是同样的简单

    /**
     * 在方法上加上@DownloadFile注解
     * dir属性表示文件下载到哪个目录
     * OnProgress参数为监听上传进度的回调函数
     * {0}代表引用第一个参数
     */
    @Get("http://localhost:8080/images/xxx.jpg")
    @DownloadFile(dir = "{0}")
    File downloadFile(String dir, OnProgress onProgress);

    调用下载接口以及监听下载进度的代码如下:

    File file = myClient.downloadFile("D:\\TestDownload", progress -> {
        System.out.println("progress: " + Math.round(progress.getRate() * 100) + "%");  // 已下载百分比
        if (progress.isDone()) {   // 是否下载完成
            System.out.println("--------   Download Completed!   --------");
        }
    });

    基本签名验证

    @Post("/hello/user?username={username}")
    @BasicAuth(username = "{username}", password = "bar")
    String send(@DataVariable("username") String username);

    OAuth 2.0

    @OAuth2(
            tokenUri = "/auth/oauth/token",
            clientId = "password",
            clientSecret = "xxxxx-yyyyy-zzzzz",
            grantType = OAuth2.GrantType.PASSWORD,
            scope = "any",
            username = "root",
            password = "xxxxxx"
    )
    @Get("/test/data")
    String getData();

    自定义注解

    Forest允许您根据需要自行定义注解,不但让您可以简单优雅得解决各种需求,而且极大得扩展了Forest的能力。

    定义一个注解

    /**
     * 用Forest自定义注解实现一个自定义的签名加密注解
     * 凡用此接口修饰的方法或接口,其对应的所有请求都会执行自定义的签名加密过程
     * 而自定义的签名加密过程,由这里的@MethodLifeCycle注解指定的生命周期类进行处理
     * 可以将此注解用在接口类和方法上
     */
    @Documented
    /** 重点: @MethodLifeCycle注解指定该注解的生命周期类*/
    @MethodLifeCycle(MyAuthLifeCycle.class)
    @RequestAttributes
    @Retention(RetentionPolicy.RUNTIME)
    /** 指定该注解可用于类上或方法上 */
    @Target({ElementType.TYPE, ElementType.METHOD})
    public @interface MyAuth {
    
        /** 
         * 自定义注解的属性:用户名
         * 所有自定注解的属性可以在生命周期类中被获取到
         */
        String username();
    
        /** 
         * 自定义注解的属性:密码
         * 所有自定注解的属性可以在生命周期类中被获取到
         */
        String password();
    }

    定义注解生命周期类

    /**
     *  MyAuthLifeCycle 为自定义的 @MyAuth 注解的生命周期类
     * 因为 @MyAuth 是针对每个请求方法的,所以它实现自 MethodAnnotationLifeCycle 接口
     * MethodAnnotationLifeCycle 接口带有泛型参数
     * 第一个泛型参数是该生命周期类绑定的注解类型
     * 第二个泛型参数为请求方法返回的数据类型,为了尽可能适应多的不同方法的返回类型,这里使用 Object
     */
    public class MyAuthLifeCycle implements MethodAnnotationLifeCycle<MyAuth, Object> {
    
     
        /**
         * 当方法调用时调用此方法,此时还没有执行请求发送
         * 次方法可以获得请求对应的方法调用信息,以及动态传入的方法调用参数列表
         */
        @Override
        public void onInvokeMethod(ForestRequest request, ForestMethod method, Object[] args) {
            System.out.println("Invoke Method '" + method.getMethodName() + "' Arguments: " + args);
        }
    
        /**
         * 发送请求前执行此方法,同拦截器中的一样
         */
        @Override
        public boolean beforeExecute(ForestRequest request) {
            // 通过getAttribute方法获取自定义注解中的属性值
            // getAttribute第一个参数为request对象,第二个参数为自定义注解中的属性名
            String username = (String) getAttribute(request, "username");
            String password = (String) getAttribute(request, "password");
            // 使用Base64进行加密
            String basic = "MyAuth " + Base64Utils.encode("{" + username + ":" + password + "}");
            // 调用addHeader方法将加密结构加到请求头MyAuthorization中
            request.addHeader("MyAuthorization", basic);
            return true;
        }
    
        /**
         * 此方法在请求方法初始化的时候被调用
         */
        @Override
        public void onMethodInitialized(ForestMethod method, BasicAuth annotation) {
            System.out.println("Method '" + method.getMethodName() + "' Initialized, Arguments: " + args);
        }
    }

    使用自定义的注解

    /**
     * 在请求接口上加上自定义的 @MyAuth 注解
     * 注解的参数可以是字符串模板,通过方法调用的时候动态传入
     * 也可以是写死的字符串
     */
    @Get("/hello/user?username={username}")
    @MyAuth(username = "{username}", password = "bar")
    String send(@DataVariable("username") String username);

    编程式请求

    Forest 的编程式请求支持链式调用,极为方便、高效、简洁

    // GET 请求访问百度
    String baidu = Forest.get("http://www.baidu.com").execute(String.class);
    
    // POST 请求注册用户信息
    String result = Forest.post("/user/register")
            .contentType("application/json")
            .addBody("username", "公子骏")
            .addBody("password", "12345678")
            .execute(String.class);

    详细文档请看:官方文档

    获得奖项

    2021 年度 OSC 中国开源项目评选「最受欢迎项目」

    联系作者

    亲,进群前记得先star一下哦~

    扫描二维码关注公众号,点击菜单中的 进群 按钮即可进群

    avatar

    他们在用

    已在使用Forest的公司列表(排名不分先后)

    华为
    野兽派花店
    吉利集团
    中科院计算所大数据研究院
    人人都是产品经理
    神州通立电梯
    万智维度
    壹润
    尚融网络科技
    华方智联
    趣链科技
    百应
    聚云位智
    嗨宝贝
    仟奇
    朝前智能
    满意吧
    源一科技
    欣网视讯
    嘉之会科技
    星晟工程

    参与贡献

    1. 进群讨论,可以在群里抛出您遇到的问题,或许已经有人解决了您的问题。
    2. 提issue,如果在issue中已经有您想解决的问题,可以直接将该issue分配给您自己。如若没有,可以自己创建一个issue。
    3. Fork 本项目的仓库
    4. 新建分支,如果是加新特性,分支名格式为feat_${issue的ID号},如果是修改bug,则命名为fix_${issue的ID号}
    5. 本地自测,提交前请通过所有的已经单元测试,以及为您要解决的问题新增单元测试。
    6. 提交代码
    7. 新建 Pull Request
    8. 我会对您的PR进行验证和测试,如通过测试,我会合到dev分支上随新版本发布时再合到master分支上。

    欢迎小伙伴们多提issue和PR,被接纳PR的小伙伴我会列在README上的贡献者列表中:)

    项目协议

    The MIT License (MIT)

    Copyright (c) 2016 Jun Gong

    Visit original content creator repository https://github.com/dromara/forest
  • SimpleSoC

    SimpleSoC

    The purpose of this project is to illustrate how to create from scratch a simple SoC (System on Chip) using ARM Design Start resources. Various tutorials already exist online on this subject, but they are mostly ‘connect the dots’ guides based on pre-canned projects which require specific Vivado versions and mostly fail their objective to enable the user to create and customize on his own SoC.

    First, download the Cortex-M1 design start files available from ARM. They are available at this address: https://www.arm.com/resources/free-arm-cortex-m-on-fpga

    Make sure you have the board files installed in Vivado under

    C:\Xilinx\Vivado\2021.1\data\boards\board_files

    If not, download them from https://github.com/Digilent/vivado-boards

    Creating the project from scratch

    Create a new Vivado project using e.g.: Arty as target board. Then, copy the contents of ‘Arm_ipi_repository’ directory included in the Cortex-M1 Design Start package into the IPs ‘directory’ and restart Vivado.

    Now, go to IP Integrator/Create Block design and add the Cortex-M processor to the design. If this is not yet there, create a new project to reflect changes to IP repository applied before. You can now add other AXI blocks, such as an AXI Interconnect and an AXI BRAM controller. Selecting the ‘Board’ tab it is possible to add the board resources to the block design and the relevant IPs will be automatically added and connected by the tool. If, for example, board LEDs are added to the block design, Vivado will create an AXI slave GPIO block to manage them.

    With the help of the connection wizard, something similar should appear:

    SimpleSoc Block Diagram

    Before building, a TOP level module must be specified. Right-click the top level design where all blocks are belonging to and select “Create HDLwrapper”. Now you can run design synthesis. Remember to add proper constraints file to map the top signals to the correct IOs. Template files for all Digilent boards can be found here https://github.com/Digilent/digilent-xdc

    The SWD debugger connection requires an INOUT buffer to bring SWD connections towards external pins. For some unknown reason, IOBUF resource is not present in the ‘Utility Buffer’ V2.2 package which comes with Vivado 2021.1. So, I crafted my own one in a separate VHDL project and packaged it with the Vivado package tools: go to Tools/Create and Package new IP/Package your Current Project. This new IP can be easily connected to the processor’s SWD signals but there’s a catch: Vivado will complain about not being able to assign INOUT signals. To work this around, use the Global synthesis as opposed to the default Out of Context one. These settings are well hidden in Vivado: you need to go to the ‘Design Runs’ tab, right click the design, and reset it. Now, a dialog will show up asking whether to use Global or Out Of Context. Other cleaner approaches might exist: figure out why the IOBUF is not there; put the inout logic in the Top wrapper created by Vivado; tweak the different units in Design Runs. Vivado will finally complain about the SWD clock not being correctly mapped. Just add the suggested constraint in the constraints file. Finally, remember to remap the BRAM memory in 0x0 instead of 0xC0000000 as the VTOR cannot be modified in the Cortex-M1.

    Now, connect a J-Link probe to the SWD signals and check that the debugger recognizes the core. If yes, try to read/write some memory using w4 and mem32 commands.

    Test also the LEDs connections via by programming the the GPIO peripheral: w4 0x40000004 0 w4 0x40000000 0xf

    If everything is fine, build the Keil project (free version limited to 32kB is more than enough) and try blinky LED application.

    Resources

    Cortex-M1 based Design Start is shown in this virtual event: https://events.hackster.io/designstart

    More resources here https://www.arm.com/products/silicon-ip-cpu/cortex-m/cortex-m1

    Some tutorial on block level design https://digilent.com/reference/vivado/getting-started-with-ipi/2018.2

    Visit original content creator repository https://github.com/siorpaes/SimpleSoC
  • KenKen-Solver

    KenKen-Solver

    KenKen is an arithmetic and logic puzzle . It is a Constraint Satisfaction Problem (CSP), that the particular program solves using algorithms like BT, BT+MRV, FC, FC+MRV and MAC provided by aima-code.

    Table of Contents

    Puzzle representation

    Inputs

    Algorithms

    Prerequisites

    How to run

    Board

    kenken board

    The KenKen board is represented by a square n-by-n grid of cells. The grid may contain between 1 and n boxes (cages) represented by a heavily outlined perimeter. Each cage will contain in superscript: the target digit value for the cage followed by a mathematical operator.

    Constraints

    Each valid solution must follow the below rules:

    • The only numbers you may write are 1 to N for a NxN size puzzle.
    • A number cannot be repeated within the same row.
    • A number cannot be repeated within the same column.
    • In a one-cell cage, just write the target number in that cell.
    • Each “cage” (region bounded by a heavy border) contains a “target number” and an arithmetic operation. You must fill that cage with numbers that produce the target number, using only the specified arithmetic operation. Numbers may be repeated within a cage, if necessary, as long as they do not repeat within a single row or column.

    There are some demo input KenKen files, of increasing complexity and difficulty, provided in the inputs folder.

    If you would like to use your own, you should place them in the inputs folder, as well.

    The input’s file format, used to describe a puzzle is:

    <puzzle_size>
    [Square_indexes1] Cage_operator1 Cage_target1
    [Square_indexes2] Cage_operator2 Cage_target2
    [Square_indexes3] Cage_operator3 Cage_target3
    ...
    [Square_indexesM] Cage_operatorM Cage_targetM
    

    For example, the text representing the above puzzle is:

    6
    [(0,0),(1,0)] add 11
    [(0,1),(0,2)] div 2
    [(0,3),(1,3)] mult 20
    [(0,4),(0,5),(1,5),(2,5)] mult 6
    [(1,1),(1,2)] sub 3
    [(1,4),(2,4)] div 3
    [(2,0),(2,1),(3,0),(3,1)] mult 240
    [(2,2),(2,3)] mult 6
    [(3,2),(4,2)] mult 6
    [(3,3),(4,3),(4,4)] add 7
    [(3,4),(3,5)] mult 30
    [(4,0),(4,1)] mult 6
    [(4,5),(5,5)] add 9
    [(5,0),(5,1),(5,2)] add 8
    [(5,3),(5,4)] div 2
    

    You can select among 5 algorithms to solve a puzzle:

    • Backtracking (command line parameter “BT”).
    • Backtracking with Minimum Remaining Values (command line parameter “BT+MRV”).
    • Forward Checking (command line parameter “FC”).
    • Forward Checking with Minimum Remaining Values (command line parameter “FC+MRV”).
    • Maintaining Arc Consistency (command line parameter “MAC”).

    Comparison

    The table below represents the number of assignments used from each algorithm, to solve different size puzzles:

    Size BT BT+MRV FC FC+MRV MAC
    3×3 10 10 9 10 9
    4×4 33 24 31 83 18
    5×5 89 FWerr 42 98 26
    6×6 947 FWerr 48 263 74
    7×7 2600 FWerr 281 1020 66

    The table below represents the time that each algorithm needed, to solve different size puzzles:

    Size BT BT+MRV FC FC+MRV MAC
    3×3 0.001619 0.002258 0.001833 0.002329 0.003514
    4×4 0.018993 0.040852 0.009197 0.015933 0.018328
    5×5 0.033648 FWerr 0.020142 0.064241 0.065805
    6×6 0.533216 FWerr 0.037589 0.434889 0.286044
    7×7 1.939305 FWerr 0.236317 13.71082 0.844914

    FWerr: AIMA-CSP framework error

    $ python kenken.py [input_file] [algorithm]
    
    Visit original content creator repository https://github.com/JohnPapad/KenKen-Solver
  • zoomcar-clone-backend

    Zoomcar Clone

    About

    This is a Backend for the Zoomcar Clone project, built using the MERN stack.

    Run

    Step 1:

    npm install
    

    Step 2: Create .env file

    .env
    

    Step 3: Name the key and value in your .env file as

    MONGO_CONNECTION_STRING=
    MONGO_URI=<Your MongoDB Connection String>
    PORT=5000
    JWT_SECRET=<Your JWT secret>
    EMAIL_USERNAME=<Your Email>
    EMAIL_PASSWORD=<Your App Password created from google account>
    CLIENT_URL=http://localhost:<Frontend PORT>
    STRIPE_SECRET_KEY=<Your Stripe Secret Key>
    STRIPE_WEBHOOK_SECRET=<Your Stripe Webhook Secret Key>
    

    Step 4: Add the .env in .gitignore file
    Step 5:

    npm run dev
    

    Step 6: Use the below API endpoints for Authentication and Base URL is http://localhost:<PORT>/api/v1/auth:

    "/me" -  Get authenticated user (GET)
    "/:token" - If the token is in VerifyUser collections, move the user to `users` collections (GET)
    "/register" - Signup user (POST). eg., {"name": "name", "email": "example@email.com", "password":"pass123"}
    "/login" - Login user (POST). eg., {"email": "example@email.com", "password":"pass123"}
    

    Step 7: Use the below API endpoints for User and Base URL is http://localhost:<PORT>/api/v1/user:

    "/getUserHostedVehicleStatus" - Get specific user hosted vehicles status list (GET)
    "/update" -  Update user details (PUT)
    "/forgotpassword" - User email is verified, and reset password link is sent to verified email. (POST)
    "/passwordreset/:resetToken" - Check the reset token is expired and update the password. (PUT)
    

    Step 8: Use the below API endpoints for Vehicle and Base URL is http://localhost:<PORT>/api/v1/vehicles:

    "https://github.com/" -  Get the filtered vehicles (GET).
    "/getAllVehicles" -  Search and Get all vehicles (GET) (Admin).
    "/getUnapprovedVehicles" - Get the unapproved host vehicles and update the hostCarStatus (Admin)
    "/:id" - Get specific vehicle details (GET).
    "https://github.com/" - Create new vehicle (POST).
    "/:id" - Update vehicle details (PUT) (Admin).
    "/:id" - Delete vehicle (Delete) (Admin).
    

    Step 9: Use the below API endpoints for Booking and Base URL is http://localhost:<PORT>/api/v1/bookings:

    "https://github.com/" -  Get the booked vehicles (GET).
    "https://github.com/" -  Book a vehicle (POST).
    "https://github.com/" - Update the booking (PUT).
    

    Step 10: Use the below API endpoints for Review and Base URL is http://localhost:<PORT>/api/v1/reviews:

    "https://github.com/" -  Get the reviews of specific user (GET).
    "https://github.com/" -  Post a reatings and comment for the booked vehicle (POST).
    

    Step 10: Use the below API endpoints for Payment and Base URL is http://localhost:<PORT>/api/v1/payment:

    "/create-checkout-session/:id" -  Proceed with the vehicle rental by initiating the checkout session (POST).
    

    Visit original content creator repository
    https://github.com/Selvan-S/zoomcar-clone-backend

  • IncusScripts

    Visit original content creator repository
    https://github.com/bketelsen/IncusScripts

  • Learn-Turing


    {Project icon} This image failed to load. It may be due to the file not being reached, or a general error. Reload the page to fix a possible general error.

    By:

    Seanpm2001, Et; Al.

    Top

    README.md


    Read this article in a different language

    Sorted by: A-Z

    Sorting options unavailable

    ( af Afrikaans Afrikaans | sq Shqiptare Albanian | am አማርኛ Amharic | ar عربى Arabic | hy հայերեն Armenian | az Azərbaycan dili Azerbaijani | eu Euskara Basque | be Беларуская Belarusian | bn বাংলা Bengali | bs Bosanski Bosnian | bg български Bulgarian | ca Català Catalan | ceb Sugbuanon Cebuano | ny Chichewa Chichewa | zh-CN 简体中文 Chinese (Simplified) | zh-t 中國傳統的) Chinese (Traditional) | co Corsu Corsican | hr Hrvatski Croatian | cs čeština Czech | da dansk Danish | nl Nederlands Dutch | en-us English English | EO Esperanto Esperanto | et Eestlane Estonian | tl Pilipino Filipino | fi Suomalainen Finnish | fr français French | fy Frysk Frisian | gl Galego Galician | ka ქართველი Georgian | de Deutsch German | el Ελληνικά Greek | gu ગુજરાતી Gujarati | ht Kreyòl ayisyen Haitian Creole | ha Hausa Hausa | haw Ōlelo Hawaiʻi Hawaiian | he עִברִית Hebrew | hi हिन्दी Hindi | hmn Hmong Hmong | hu Magyar Hungarian | is Íslenska Icelandic | ig Igbo Igbo | id bahasa Indonesia Icelandic | ga Gaeilge Irish | it Italiana/Italiano | ja 日本語 Japanese | jw Wong jawa Javanese | kn ಕನ್ನಡ Kannada | kk Қазақ Kazakh | km ខ្មែរ Khmer | rw Kinyarwanda Kinyarwanda | ko-south 韓國語 Korean (South) | ko-north 문화어 Korean (North) (NOT YET TRANSLATED) | ku Kurdî Kurdish (Kurmanji) | ky Кыргызча Kyrgyz | lo ລາວ Lao | la Latine Latin | lt Lietuvis Lithuanian | lb Lëtzebuergesch Luxembourgish | mk Македонски Macedonian | mg Malagasy Malagasy | ms Bahasa Melayu Malay | ml മലയാളം Malayalam | mt Malti Maltese | mi Maori Maori | mr मराठी Marathi | mn Монгол Mongolian | my မြန်မာ Myanmar (Burmese) | ne नेपाली Nepali | no norsk Norwegian | or ଓଡିଆ (ଓଡିଆ) Odia (Oriya) | ps پښتو Pashto | fa فارسی |Persian pl polski Polish | pt português Portuguese | pa ਪੰਜਾਬੀ Punjabi | No languages available that start with the letter Q | ro Română Romanian | ru русский Russian | sm Faasamoa Samoan | gd Gàidhlig na h-Alba Scots Gaelic | sr Српски Serbian | st Sesotho Sesotho | sn Shona Shona | sd سنڌي Sindhi | si සිංහල Sinhala | sk Slovák Slovak | sl Slovenščina Slovenian | so Soomaali Somali | [es en español Spanish | su Sundanis Sundanese | sw Kiswahili Swahili | sv Svenska Swedish | tg Тоҷикӣ Tajik | ta தமிழ் Tamil | tt Татар Tatar | te తెలుగు Telugu | th ไทย Thai | tr Türk Turkish | tk Türkmenler Turkmen | uk Український Ukrainian | ur اردو Urdu | ug ئۇيغۇر Uyghur | uz O’zbek Uzbek | vi Tiếng Việt Vietnamese | cy Cymraeg Welsh | xh isiXhosa Xhosa | yi יידיש Yiddish | yo Yoruba Yoruba | zu Zulu Zulu ) Available in 110 languages (108 when not counting English and North Korean, as North Korean has not been translated yet Read about it here)

    Translations in languages other than English are machine translated and are not yet accurate. No errors have been fixed yet as of March 21st 2021. Please report translation errors here. Make sure to backup your correction with sources and guide me, as I don’t know languages other than English well (I plan on getting a translator eventually) please cite wiktionary and other sources in your report. Failing to do so will result in a rejection of the correction being published.

    Note: due to limitations with GitHub’s interpretation of markdown (and pretty much every other web-based interpretation of markdown) clicking these links will redirect you to a separate file on a separate page that isn’t the intended page. You will be redirected to the .github folder of this project, where the README translations are hosted.

    Translations are currently done with Bing translate and DeepL. Support for Google Translate translations is coming to a close due to privacy concerns.


    Index

    00.0 – Top

    00.1 – Title

    00.2 – Read this article in a different language

    00.3 – Index

    01.0 – Description

    02.0 – About

    03.0 – Wiki

    04.0 – History

    04.1 – Pre-history

    04.2 – Alpha History

    04.3 – Beta History

    04.4 – Modern History

    05.0 – Copying

    06.0 – Credits

    07.0 – Installation

    08.0 – Version history

    09.0 – Version history

    10.0 – Software status

    11.0 – Sponsor info

    12.0 – Contributers

    13.0 – Issues

    13.1 – Current issues

    13.2 – Past issues

    13.3 – Past pull requests

    13.4 – Active pull requests

    14.0 – Resources

    15.0 – Contributing

    16.0 – About README

    17.0 – README Version history

    18.0 – Footer

    18.9 – End of file


    <repo_description>


    About

    See above.


    Wiki

    Click/tap here to view this projects Wiki

    If the project has been forked, the Wiki was likely removed. Luckily, I include an embedded version. You can view it here.


    History

    Write about this projects history here.

    Pre-history

    No pre-history to show for this project.

    Alpha history

    No Alpha history to show for this project.

    Beta history

    No Beta history to show for this project.

    Modern history

    No Modern history to show for this project.


    Copying

    View the copying license for this project here (if you haven’t built the project yet with the makefile, here is the original link: COPYINGL

    Please note that you also have to follow the rules of the GNU General Public License v3 (GPL3) which you can view here


    Credits

    View the credits file for this project and see the people who got together to make this project by clicking/tapping here


    Installation

    View the installation instructions file for this project here

    Requirements: Read the instructions for more info, and get the latest up-to-date instructions here


    Sponsor info

    SponsorButton.png

    You can sponsor this project if you like, but please specify what you want to donate to. See the funds you can donate to here

    You can view other sponsor info here

    Try it out! The sponsor button is right up next to the watch/unwatch button.


    Version history

    Version history currently unavailable

    No other versions listed


    Software status

    All of my works are free some restrictions. DRM (Digital Restrictions Management) is not present in any of my works.

    DRM-free_label.en.svg

    This sticker is supported by the Free Software Foundation. I never intend to include DRM in my works.

    I am using the abbreviation “Digital Restrictions Management” instead of the more known “Digital Rights Management” as the common way of addressing it is false, there are no rights with DRM. The spelling “Digital Restrictions Management” is more accurate, and is supported by Richard M. Stallman (RMS) and the Free Software Foundation (FSF)

    This section is used to raise awareness for the problems with DRM, and also to protest it. DRM is defective by design and is a major threat to all computer users and software freedom.

    Image credit: defectivebydesign.org/drm-free/…


    Contributers

    Currently, I am the only contributer. Contributing is allowed, as long as you follow the rules of the CONTRIBUTING.md file.

      1. seanpm2001 – x commits (As of Yr, DoW, Month, DoM, at ##:## a/pm)
      1. No other contributers.

    Issues

    Current issues

    • None at the moment

    • No other current issues

    If the repository has been forked, issues likely have been removed. Luckily I keep an archive of certain images here

    Read the privacy policy on issue archival here

    TL;DR

    I archive my own issues. Your issue won’t be archived unless you request it to be archived.

    Past issues

    • None at the moment

    • No other past issues

    If the repository has been forked, issues likely have been removed. Luckily I keep an archive of certain images here

    Read the privacy policy on issue archival here

    TL;DR

    I archive my own issues. Your issue won’t be archived unless you request it to be archived.

    Past pull requests

    • None at the moment

    • No other past pull requests

    If the repository has been forked, issues likely have been removed. Luckily I keep an archive of certain images here

    Read the privacy policy on issue archival here

    TL;DR

    I archive my own issues. Your issue won’t be archived unless you request it to be archived.

    Active pull requests

    • None at the moment

    • No other active pull requests

    If the repository has been forked, issues likely have been removed. Luckily I keep an archive of certain images here

    Read the privacy policy on issue archival here

    TL;DR

    I archive my own issues. Your issue won’t be archived unless you request it to be archived.


    Resources

    Here are some other resources for this project:

    Project language file A

    Join the discussion on GitHub

    No other resources at the moment.


    Contributing

    Contributing is allowed for this project, as long as you follow the rules of the CONTRIBUTING.md file.

    Click/tap here to view the contributing rules for this project


    About README

    File type: Markdown Document (*.md *.mkd *.markdown)

    File version: 0.1.6 (Monday, August 23rd 2021 at 6:37 pm)

    Line count (including blank lines and compiler line): 0,407


    README version history

    Version 0.1 (Sunday, March 21st 2021 at 7:50 pm)

    Changes:

    • Started the file
    • Added the title section
    • Added the index
    • Added the about section
    • Added the Wiki section
    • Added the version history section
    • Added the issues section.
    • Added the past issues section
    • Added the past pull requests section
    • Added the active pull requests section
    • Added the contributors section
    • Added the contributing section
    • Added the about README section
    • Added the README version history section
    • Added the resources section
    • Added a software status section, with a DRM free sticker and message
    • Added the sponsor info section

    ITERATION 5

    • Updated the title section
    • Updated the index
    • Added the history section
    • Updated the file info section
    • Updated the file history section

    ITERATION 6

    • Updated the title section
    • Fixed and update template links
    • Updated the index
    • Added the copying section
    • Added the credits section
    • Added the installation section
    • Updated the resources section
    • Updated the contributors section
    • Added the technical notes section
    • Updated the footer
    • Updated the file info section
    • Updated the file history section
    • No other changes in version 0.1

    Version 1 (Coming soon)

    Changes:

    • Coming soon
    • No other changes in version 1

    Version 2 (Coming soon)

    Changes:

    • Coming soon
    • No other changes in version 2

    You have reached the end of the README file

    ( Back to top | Exit to GitHub | Exit to Bing | Exit to DuckDuckGo | Exit to Ecosia )

    EOF


    Visit original content creator repository https://github.com/seanpm2001/Learn-Turing
  • fb-messenger-bot

    Guidelines to create your bot - Facebook Workplace

    Node.js website Npm website ExpressJS website Facebook Messenger
    GitHub release (latest by date) Travis (.org) GitHub

    💬 Note from developer

    This application is a starter for the creation of bots for Facebook Messenger and WorkChat (Workplace) for demonstration and education purposes. Its configuration is robust and scalable and can be used in a productive environment. Use this application to learn, experiment, retouch and practice the different options offered by the Facebook API.

    For more information about the Facebook API you can read the documentation that the Messenger team prepared.


    Glossary

    🤔 How does the Messenger platform work?

    Messaging bots use a web server to process the messages they receive or to find out which messages to send. It is also necessary for the bot to be authenticated to talk to the web server and for the bot to be approved by Facebook to talk to the public.

    When a person sends a message to a company in Messenger, the following happens, as long as the page uses an app to partially or completely automate the conversations. The Facebook server sends webhooks to the URL of the company’s server where the message app is hosted. That app can then reply to the person in Messenger using the Send API. This allows developers to create guided conversations for people to perform an automated process or develop an app that serves as a link between your agents and your company’s Messenger presence.

    Workflow API Messenger

    🤖 Live Demo

    You can try some functions of the bot by entering here.

    Live Demo

    And you can try other kind of messages from the server documentation, don’t forget to get your ID from the chat bot persistent menu.

    🙌 Let’s start

    Before starting to work on our bot, we must have installed some tools in our computer that will facilitate us to work locally and be able to test some functionalities that the starter has available, and I will take for granted some basic concepts so as not to go into detail and extend the documentation.

    📝 Basic requirements

    🛠 Install dependencies

    When we have the basic requirements, we clone the repository, go to the project folder and install its dependencies.

     npm install
    

    We download the latest version of Ngrok compatible with our operating system, and decompress it in the server root.

    ⚙ Configurations

    This application uses the config dependency to facilitate the configuration of environment variables, which makes it scalable and robust when deploying the application in different environments.

    In the path ./config you will find a file called development.json which contains the settings for a local environment, while the file custom-environment-variables.json gets the key values of the environment variables displayed on the server.

    Basically the file works as an object that is exported and can be consumed by invoking it in the file that requires consuming the loaded information. If you need to add another type of data to consume, like the connection to a database, the url of some microservice, etc. you just have to add it to both files keeping the scheme.

    You may find that you can’t configure some values for now, but that’s not a problem, when using the nodemon dependency, the server is in a watching state that at the slightest change of code, the server will run again.

    {
      server: {
        url: '',
        port: 8080,
        context: '/api',
        origins: 'http://localhost:3000,http://localhost:3001,http://localhost:8080',
        originsReadOnly: 'http://localhost:3001',
        corsEnabled: 'false',
        tz: 'America/Argentina/Buenos_Aires',
        showLogInterceptor: 'false',
      },
      params: {
        fbApiVersion: 'v8.0',
        verifyToken: 'my_awesome_bot_verify_token',
        appSecret: '',
        accessToken: '',
        subscribedFields: 'messages,messaging_postbacks',
        userFields: 'id,name,first_name,last_name,email',
        secrets: '',
        requireProof: false
      },
      services: {
        fbApiUrl: 'https://graph.facebook.com',
      },
      swagger: {
        enabled: 'true',
      },
    }
    See all available configuration properties in detail.

    Server

    url: It is the url of the server deployed in some environment, in the case of running it locally, you enter the url with ssl provided by ngrok.

    • Type: String
    • Default:

    port: Is the port in which the application is deployed.

    • Type: Number
    • Default: 8080

    context: It is the context from which the server’s api can be accessed, this way the routes in the main path of the application are not exposed.

    • Type: String
    • Default: /api

    origins: The origins serve so that the application can only be consumed by reliable urls and avoid any kind of unwanted and malicious requests. You should write the urls separated with comma.

    • Type: String
    • Default: http://localhost:3000,http://localhost:3001,http://localhost:8080

    originsReadOnly: It is the configuration of the urls for CORS, which allows you to validate who can consume the server.

    • Type: String
    • Default: http://localhost:3001

    corsEnabled: Enables or disables the use of CORS on the bot’s server.

    • Type: Boolean
    • Default: false

    tz: It is the configuration of the time zone. List of time zones

    • Type: String
    • Default: America/Argentina/Buenos_Aires

    showLogInterceptor: Enables the display of the request interceptors in the logs.

    • Type: Boolean
    • Default: false

    Params

    fbApiVersion: Is the api version of facebook

    • Type: String
    • Default: v8.0

    verifyToken: It is the verification token required by the application when invoked by facebook, this token is private and should not be exposed.

    • Type: String
    • Default: my_awesome_bot_verify_token

    appSecret: It is the secret key to the app, it is required if you are going to use the security settings for the requests.

    • Type: String
    • Default:

    accessToken: The access token is the alphanumeric hash that is generated when you create the application on Fecebook or Workplace.

    • Type: String
    • Default:

    subscribedFields: Are the permissions required to subscribe to the application in order to interact with the user. These permissions are only required for Facebook bots and must be typed separately by comma.

    • Type: String
    • Default: messages,messaging_postbacks,messaging_optins

    userFields: It is a comma-separated list to obtain the user’s information.Documentation

    • Type: String
    • Default: id,name,first_name,last_name,email

    secrets: Here you can enter any value you want to hide in the server logs of the bot, for example the id of the sender or the id of the sender. The values to hide must be written separated by comma.

    • Type: String
    • Default:

    requireProof: Enables or disables the use of appsecret_proof and appsecret_time for security requests, it is required to have configured the secret key of the app to work.

    • Type: Boolean
    • Default: false

    services

    fbApiUrl: It is the url of the Graph API of Feacebook

    • Type: String
    • Default: https://graph.facebook.com

    swagger

    enabled: Enable or disable the documentation of the bot’s server endpoints with swagger.

    • Type: Boolean
    • Default: true

    💻 Run server

    We start the bot’s server.

    npm run start
    

    Server Bot running in terminal

    Once the server is started, we must start ngrok to create the connection tunnel between the bot’s local server and the Facebook server.

    ./ngrok http 8080
    
    Windows
    ./ngrok.exe http 8080
    

    Server ngrok in terminal

    To see other tunnel configurations, you can check the documentation

    📚 Swagger

    The project has a Swagger that has documented the most important endpoints of the project, and facilitates the configuration of the fields for the bot, such as the get started button, persistent menu and the greeting.

    This documentation can be enabled or disabled from the configuration files.

    • Default: http://localhost:8080/api-docs

    URL Scheme

    <http|https>://<server_url><:port>/api-docs
    

    🖥️ Deploy server in heroku (free)

    You can run the bot server in a productive environment on any node server, in this case I will explain the steps to raise the server on the platform Heroku, which has a free version to deploy node servers, you can also hire a paid service which gives you more features.

    💬 If you don’t have a Heroku account, you can create one by going to https://signup.heroku.com/.

    We will need a file called Procfile, which is the one Heroku will use to initialize the server once deployed.

    Its content is:

    web: npm start
    
    1. After logging into Heroku, click on Create new app

    Create a new app in heroku 1

    1. We write the name of our app, and select a region, and then click on Create App.

      💬 note: Remember to save the name of the app, as you will need it later to replace the value of <app_name> with the name of the app.

    Create a new app in heroku 2

    1. Heroku gives you several options to deploy your server. You can do it with Heroku CLI by following the steps in the documentation, or you can deploy it directly from Github, which is much easier.

    Create a new app in heroku 3

    Deployment method: Heroku CLI

    Download and install the Heroku CLI.

    If you haven’t already, log in to your Heroku account and follow the prompts to create a new SSH public key.

    heroku login
    
    Create a new Git repository

    Initialize a git repository in a new or existing directory

    cd my-project/
    git init
    heroku git:remote -a <app_name>
    
    Deploy your application

    Commit your code to the repository and deploy it to Heroku using Git.

    git add .
    git commit -am "make it better"
    git push heroku master
    
    Deploy your application

    For existing repositories, simply add the heroku remote

    heroku git:remote -a <app_name>
    

    Deployment method: GitHub

    We click on the connect to GitHub button, if you’ve never connected Heroku to Github, a window will open to authorize the connection so you can continue with the step of entering the name of the repository and searching it in your GitHub account, and once you find it, we click on the Connect button.

    Create a new app in heroku 4

    Then we select the branch we want to deploy, and click on Deploy Branch, and it will start running the deployment, downloading the code from the repository, installing the dependencies, etc.

    Create a new app in heroku 5

    1. Now we have to configure the environment variables of the server, although we can do it manually from Settings > Config Vars, there is a bash script prepared that will raise the environment variables of our .env file that is located in the ./variables folder.
    npm run heroku:envs
    

    or

    bash heroku-envs.sh
    

    Create a new app in heroku 6

    📱 Setup the Facebook App

    The time has come to create and configure our app on Facebook.

    With the local server and the connection tunnel initialized, we will configure the app, and with the information that it will give us we will finish configuring the data that we are missing in the bot’s server.

    💬 Remember that the bot’s server is in watch mode, and any changes made will be re-initialized and take the changes made.

    1. Enter Facebook Developers and click on create app, it will open a modal to select the type of application, in our case we will create an application type “Manage business integrations“.

    Create a new app on facebook

    1. Now we will have to make some basic settings for the application.

      We assign a name of the app to identify it, we put a contact email, we select the purpose of the app, in this case is for us, and if we have a commercial administrator account, we select one from the list, if you do not have such an account, you can create it later.

      Once the information is completed, we click on Create App identifier

      Basic settings new app on facebook

    2. Then we look for Messenger in the app’s product list, and hit the configure button.

    Settings new app on facebook 1

    1. Now we are going to make the two necessary and essential configurations to be able to connect Facebook with our bot server.

      Settings new app on facebook 2

      Access tokens

      In this part of the configuration, we will be able to manage which page or pages of facebook will have the bot available. We click on Add or Remove pages, and select the page.

      Settings new app on facebook 3

      Once the page is linked to the app, we have to generate the token by clicking on the button Generate Token, and a window will open where you give us some instructions about the token.

      We must check accept in order to view the full hash, then copy it and place it in the configuration of our server, if it is for development it is put in the json of ./config/development.json in the key of accessToken, and if it is for a productive environment, we must put it in the envs file in ./variables.

      Settings new app on facebook 4

      {
        ...
        params: {
          ...
          accessToken: '<access_token>',
          ...
        },
       ...
      }

      Webhooks

      Now we have to configure the connection between Facebook and our server through Webhook, for this, you must have at hand the verifyToken that you configured and the bot’s server url, in this case, we will use the one provided by ngrok with ssl.

      https://<id_tunnel>.ngrok.io/api/webhook/
      

      Settings new app on facebook 5

      Then click on Verify and Save, and if everything goes well, in the server terminal you should see the successful subscription message.

      Config webhook subscription response terminal

      If the url of the webhook by ngrok changes, or you want to configure the url of the productive server, you can do it by clicking on the button Edit Callback URL and perform again the previous steps.

      Add subscriptions

      Now we have to add the subscriptions that will allow the bot to have certain permissions to perform the actions we need.

      For that we click on the button Add subscriptions

      Settings new app on facebook 6

      Select from the list the basic permissions and click on Save

      Then we add each permission to the configuration files separated by a comma.

      Settings new app on facebook 7

      {
        ...
        params: {
          ...
          subscribedFields: 'messages,messaging_postbacks,messaging_optins',
          ...
        },
        ...
      }
    2. These are the last settings to be made and are optional. It consists in executing a curl script in the terminal to implement some options, don’t forget to put the access token to make it work.

      💬 Note: You can run these scripts from Swagger, but you must adjust the files that are inside the ./templates/configs folder

      Add button Get Started

      curl -X POST -H "Content-Type: application/json" -d '{
           "get_started": {
               "payload": "GET_STARTED_PAYLOAD"
           }
      }' "https://graph.facebook.com/v8.0/me/messenger_profile?access_token=<access_token>"

      Add greeting

      curl -X POST -H "Content-Type: application/json" -d '{
      "greeting": [
           {
               "locale": "default",
               "text": "Hi {{user_first_name}}, i'm a bot!"
           }
      ]
      }' "https://graph.facebook.com/v8.0/me/messenger_profile?access_token=<access_token>"

      Add persistent menu

      curl -X POST -H "Content-Type: application/json" -d '{
         "persistent_menu":[
            {
               "locale":"default",
               "composer_input_disabled":false,
               "call_to_actions":[
                  {
                     "title":"About us",
                     "type":"postback",
                     "payload":"ABOUT_US_PAYLOAD"
                  },
                  {
                     "title":"Contact",
                     "type":"postback",
                     "payload":"CONTACT_PAYLOAD"
                  },
                  {
                     "type":"web_url",
                     "title":"💻 Visit my Website",
                     "url":"http://misite.com/",
                     "webview_height_ratio":"full"
                  }
               ]
            }
         ]
      }' "https://graph.facebook.com/v8.0/me/messenger_profile?access_token=<access_token>"

      Remove persistent menu

      curl -X DELETE -H "Content-Type: application/json" -d '{
          "fields":[
               "persistent_menu"
          ]
      }' "https://graph.facebook.com/v8.0/me/messenger_profile?access_token=<access_token>"

    🙌 End of configuration

    We have finished configuring the app so that Facebook connects to the bot’s server, now we have to test it, to do this we can enter the chat page and perform a test to verify that everything is working properly.

    📡 How to share your bot

    Add a chat button to your webpage, go here to learn how to add a chat button your page.

    🔗 Create a shortlink

    You can use page username to have someone start a chat.

    https://m.me/<PAGE_USERNAME>
    

    📱 Setup the Workplace App

    The configuration of the app for Workplace is quite similar to that of Facebook, it is required to have the Workplace paid account in order to enable custom integrations.

    1. Go to the Administrator Panel, and click on the Integrations button, and in the Custom integrations section click on the Create custom integration button.

      It will open a modal where we must write the name of the application and a description, then click on Create.

      Settings new app on workplace 1

    2. Once the application is created, it takes us to the configuration page of the application.

      Settings new app on workplace 2

      Access token

      Now we are going to generate an access token and then configure it in our config, as mentioned in the configuration of the Facebook app.

      Settings new app on workplace 3

    3. Now let’s select the permissions for our bot.

      Permissions

      In our case we are interested in the option of Sending a message to any member.

      Settings new app on workplace 4

    4. Now we are going to grant the integration access to groups, in this case it is going to be to a specific group.

    Settings new app on workplace 5

    1. And finally, we have to configure the Webhook and the verify token and select the subscriptions we need, as we did with the Facebook app.

      Settings new app on workplace 6

      💬 Note: depending on the webhook configuration you select in the tabs, the subscriptions will change.

    2. 🙌 Finally we click on the save button.

      💬 Note: there is an optional configuration which is the security one, where it is required to enter the ip of the bot’s server, the domain, etc.

      Settings new app on workplace 7

    🔐 Security Configuration

    To give more security to the application, both for Facebook and Workplace, it is important to have completed the environment variable appSecret and have set true the requireProof for the bot to work properly with these new settings.

    {
      ...
      "params": {
        "appSecret": "<app_secret_key>",
        ...    
        "requireProof": true
      }
      ...
    }

    For both cases, it is required to have the public IP of the server, since that way, it will only be limited to receive and send requests from a single authorized server.

    If you have more than one public IP, or another server to balance the bot’s requests, you can add it to the list.

    Facebook App

    In the configuration of the app, we go to the left side menu and go to Settings > Advanced, and then down to the Security section, where we will enter our public IP, and then we will activate the option Require secret key of the app.

    Settings new app on facebook 8

    Workplace App

    In the configuration of the app, we go down to the Security Settings section, where we will activate the option to require a secret key test of the app, and then we will enter our public IP.

    Settings new app on workplace 8

    🤦‍♂️Troubleshooting

    Workplace App

    ❌ (#200) To subscribe to the messages field

    (#200) To subscribe to the messages field, one of these permissions is needed: pages_messaging. To subscribe to the messaging_postbacks field, one of these permissions is needed: pages_messaging

    You can solve this problem by configuring the webhook without selecting the subscriptions, then saving the configuration, then re-entering the app configuration and re-validating the webhook with the selected subscriptions.

    💡 Contributing

    Requests are welcome. For important changes, please open a topic first to discuss what you would like to change.

    Please be sure to update the tests and documentation as appropriate.

    👨‍💻 Author

    badge

    📜 License MIT

    Visit original content creator repository https://github.com/rudemex/fb-messenger-bot
  • fb-messenger-bot

    Guidelines to create your bot - Facebook Workplace

    Node.js website Npm website ExpressJS website Facebook Messenger
    GitHub release (latest by date) Travis (.org) GitHub

    💬 Note from developer

    This application is a starter for the creation of bots for Facebook Messenger and WorkChat (Workplace) for demonstration and education purposes. Its configuration is robust and scalable and can be used in a productive environment. Use this application to learn, experiment, retouch and practice the different options offered by the Facebook API.

    For more information about the Facebook API you can read the documentation that the Messenger team prepared.


    Glossary

    🤔 How does the Messenger platform work?

    Messaging bots use a web server to process the messages they receive or to find out which messages to send. It is also necessary for the bot to be authenticated to talk to the web server and for the bot to be approved by Facebook to talk to the public.

    When a person sends a message to a company in Messenger, the following happens, as long as the page uses an app to partially or completely automate the conversations. The Facebook server sends webhooks to the URL of the company’s server where the message app is hosted. That app can then reply to the person in Messenger using the Send API. This allows developers to create guided conversations for people to perform an automated process or develop an app that serves as a link between your agents and your company’s Messenger presence.

    Workflow API Messenger

    🤖 Live Demo

    You can try some functions of the bot by entering here.

    Live Demo

    And you can try other kind of messages from the server documentation, don’t forget to get your ID from the chat bot persistent menu.

    🙌 Let’s start

    Before starting to work on our bot, we must have installed some tools in our computer that will facilitate us to work locally and be able to test some functionalities that the starter has available, and I will take for granted some basic concepts so as not to go into detail and extend the documentation.

    📝 Basic requirements

    🛠 Install dependencies

    When we have the basic requirements, we clone the repository, go to the project folder and install its dependencies.

     npm install
    

    We download the latest version of Ngrok compatible with our operating system, and decompress it in the server root.

    ⚙ Configurations

    This application uses the config dependency to facilitate the configuration of environment variables, which makes it scalable and robust when deploying the application in different environments.

    In the path ./config you will find a file called development.json which contains the settings for a local environment, while the file custom-environment-variables.json gets the key values of the environment variables displayed on the server.

    Basically the file works as an object that is exported and can be consumed by invoking it in the file that requires consuming the loaded information. If you need to add another type of data to consume, like the connection to a database, the url of some microservice, etc. you just have to add it to both files keeping the scheme.

    You may find that you can’t configure some values for now, but that’s not a problem, when using the nodemon dependency, the server is in a watching state that at the slightest change of code, the server will run again.

    {
      server: {
        url: '',
        port: 8080,
        context: '/api',
        origins: 'http://localhost:3000,http://localhost:3001,http://localhost:8080',
        originsReadOnly: 'http://localhost:3001',
        corsEnabled: 'false',
        tz: 'America/Argentina/Buenos_Aires',
        showLogInterceptor: 'false',
      },
      params: {
        fbApiVersion: 'v8.0',
        verifyToken: 'my_awesome_bot_verify_token',
        appSecret: '',
        accessToken: '',
        subscribedFields: 'messages,messaging_postbacks',
        userFields: 'id,name,first_name,last_name,email',
        secrets: '',
        requireProof: false
      },
      services: {
        fbApiUrl: 'https://graph.facebook.com',
      },
      swagger: {
        enabled: 'true',
      },
    }
    See all available configuration properties in detail.

    Server

    url: It is the url of the server deployed in some environment, in the case of running it locally, you enter the url with ssl provided by ngrok.

    • Type: String
    • Default:

    port: Is the port in which the application is deployed.

    • Type: Number
    • Default: 8080

    context: It is the context from which the server’s api can be accessed, this way the routes in the main path of the application are not exposed.

    • Type: String
    • Default: /api

    origins: The origins serve so that the application can only be consumed by reliable urls and avoid any kind of unwanted and malicious requests. You should write the urls separated with comma.

    • Type: String
    • Default: http://localhost:3000,http://localhost:3001,http://localhost:8080

    originsReadOnly: It is the configuration of the urls for CORS, which allows you to validate who can consume the server.

    • Type: String
    • Default: http://localhost:3001

    corsEnabled: Enables or disables the use of CORS on the bot’s server.

    • Type: Boolean
    • Default: false

    tz: It is the configuration of the time zone. List of time zones

    • Type: String
    • Default: America/Argentina/Buenos_Aires

    showLogInterceptor: Enables the display of the request interceptors in the logs.

    • Type: Boolean
    • Default: false

    Params

    fbApiVersion: Is the api version of facebook

    • Type: String
    • Default: v8.0

    verifyToken: It is the verification token required by the application when invoked by facebook, this token is private and should not be exposed.

    • Type: String
    • Default: my_awesome_bot_verify_token

    appSecret: It is the secret key to the app, it is required if you are going to use the security settings for the requests.

    • Type: String
    • Default:

    accessToken: The access token is the alphanumeric hash that is generated when you create the application on Fecebook or Workplace.

    • Type: String
    • Default:

    subscribedFields: Are the permissions required to subscribe to the application in order to interact with the user. These permissions are only required for Facebook bots and must be typed separately by comma.

    • Type: String
    • Default: messages,messaging_postbacks,messaging_optins

    userFields: It is a comma-separated list to obtain the user’s information.Documentation

    • Type: String
    • Default: id,name,first_name,last_name,email

    secrets: Here you can enter any value you want to hide in the server logs of the bot, for example the id of the sender or the id of the sender. The values to hide must be written separated by comma.

    • Type: String
    • Default:

    requireProof: Enables or disables the use of appsecret_proof and appsecret_time for security requests, it is required to have configured the secret key of the app to work.

    • Type: Boolean
    • Default: false

    services

    fbApiUrl: It is the url of the Graph API of Feacebook

    • Type: String
    • Default: https://graph.facebook.com

    swagger

    enabled: Enable or disable the documentation of the bot’s server endpoints with swagger.

    • Type: Boolean
    • Default: true

    💻 Run server

    We start the bot’s server.

    npm run start
    

    Server Bot running in terminal

    Once the server is started, we must start ngrok to create the connection tunnel between the bot’s local server and the Facebook server.

    ./ngrok http 8080
    
    Windows
    ./ngrok.exe http 8080
    

    Server ngrok in terminal

    To see other tunnel configurations, you can check the documentation

    📚 Swagger

    The project has a Swagger that has documented the most important endpoints of the project, and facilitates the configuration of the fields for the bot, such as the get started button, persistent menu and the greeting.

    This documentation can be enabled or disabled from the configuration files.

    • Default: http://localhost:8080/api-docs

    URL Scheme

    <http|https>://<server_url><:port>/api-docs
    

    🖥️ Deploy server in heroku (free)

    You can run the bot server in a productive environment on any node server, in this case I will explain the steps to raise the server on the platform Heroku, which has a free version to deploy node servers, you can also hire a paid service which gives you more features.

    💬 If you don’t have a Heroku account, you can create one by going to https://signup.heroku.com/.

    We will need a file called Procfile, which is the one Heroku will use to initialize the server once deployed.

    Its content is:

    web: npm start
    
    1. After logging into Heroku, click on Create new app

    Create a new app in heroku 1

    1. We write the name of our app, and select a region, and then click on Create App.

      💬 note: Remember to save the name of the app, as you will need it later to replace the value of <app_name> with the name of the app.

    Create a new app in heroku 2

    1. Heroku gives you several options to deploy your server. You can do it with Heroku CLI by following the steps in the documentation, or you can deploy it directly from Github, which is much easier.

    Create a new app in heroku 3

    Deployment method: Heroku CLI

    Download and install the Heroku CLI.

    If you haven’t already, log in to your Heroku account and follow the prompts to create a new SSH public key.

    heroku login
    
    Create a new Git repository

    Initialize a git repository in a new or existing directory

    cd my-project/
    git init
    heroku git:remote -a <app_name>
    
    Deploy your application

    Commit your code to the repository and deploy it to Heroku using Git.

    git add .
    git commit -am "make it better"
    git push heroku master
    
    Deploy your application

    For existing repositories, simply add the heroku remote

    heroku git:remote -a <app_name>
    

    Deployment method: GitHub

    We click on the connect to GitHub button, if you’ve never connected Heroku to Github, a window will open to authorize the connection so you can continue with the step of entering the name of the repository and searching it in your GitHub account, and once you find it, we click on the Connect button.

    Create a new app in heroku 4

    Then we select the branch we want to deploy, and click on Deploy Branch, and it will start running the deployment, downloading the code from the repository, installing the dependencies, etc.

    Create a new app in heroku 5

    1. Now we have to configure the environment variables of the server, although we can do it manually from Settings > Config Vars, there is a bash script prepared that will raise the environment variables of our .env file that is located in the ./variables folder.
    npm run heroku:envs
    

    or

    bash heroku-envs.sh
    

    Create a new app in heroku 6

    📱 Setup the Facebook App

    The time has come to create and configure our app on Facebook.

    With the local server and the connection tunnel initialized, we will configure the app, and with the information that it will give us we will finish configuring the data that we are missing in the bot’s server.

    💬 Remember that the bot’s server is in watch mode, and any changes made will be re-initialized and take the changes made.

    1. Enter Facebook Developers and click on create app, it will open a modal to select the type of application, in our case we will create an application type “Manage business integrations“.

    Create a new app on facebook

    1. Now we will have to make some basic settings for the application.

      We assign a name of the app to identify it, we put a contact email, we select the purpose of the app, in this case is for us, and if we have a commercial administrator account, we select one from the list, if you do not have such an account, you can create it later.

      Once the information is completed, we click on Create App identifier

      Basic settings new app on facebook

    2. Then we look for Messenger in the app’s product list, and hit the configure button.

    Settings new app on facebook 1

    1. Now we are going to make the two necessary and essential configurations to be able to connect Facebook with our bot server.

      Settings new app on facebook 2

      Access tokens

      In this part of the configuration, we will be able to manage which page or pages of facebook will have the bot available. We click on Add or Remove pages, and select the page.

      Settings new app on facebook 3

      Once the page is linked to the app, we have to generate the token by clicking on the button Generate Token, and a window will open where you give us some instructions about the token.

      We must check accept in order to view the full hash, then copy it and place it in the configuration of our server, if it is for development it is put in the json of ./config/development.json in the key of accessToken, and if it is for a productive environment, we must put it in the envs file in ./variables.

      Settings new app on facebook 4

      {
        ...
        params: {
          ...
          accessToken: '<access_token>',
          ...
        },
       ...
      }

      Webhooks

      Now we have to configure the connection between Facebook and our server through Webhook, for this, you must have at hand the verifyToken that you configured and the bot’s server url, in this case, we will use the one provided by ngrok with ssl.

      https://<id_tunnel>.ngrok.io/api/webhook/
      

      Settings new app on facebook 5

      Then click on Verify and Save, and if everything goes well, in the server terminal you should see the successful subscription message.

      Config webhook subscription response terminal

      If the url of the webhook by ngrok changes, or you want to configure the url of the productive server, you can do it by clicking on the button Edit Callback URL and perform again the previous steps.

      Add subscriptions

      Now we have to add the subscriptions that will allow the bot to have certain permissions to perform the actions we need.

      For that we click on the button Add subscriptions

      Settings new app on facebook 6

      Select from the list the basic permissions and click on Save

      Then we add each permission to the configuration files separated by a comma.

      Settings new app on facebook 7

      {
        ...
        params: {
          ...
          subscribedFields: 'messages,messaging_postbacks,messaging_optins',
          ...
        },
        ...
      }
    2. These are the last settings to be made and are optional. It consists in executing a curl script in the terminal to implement some options, don’t forget to put the access token to make it work.

      💬 Note: You can run these scripts from Swagger, but you must adjust the files that are inside the ./templates/configs folder

      Add button Get Started

      curl -X POST -H "Content-Type: application/json" -d '{
           "get_started": {
               "payload": "GET_STARTED_PAYLOAD"
           }
      }' "https://graph.facebook.com/v8.0/me/messenger_profile?access_token=<access_token>"

      Add greeting

      curl -X POST -H "Content-Type: application/json" -d '{
      "greeting": [
           {
               "locale": "default",
               "text": "Hi {{user_first_name}}, i'm a bot!"
           }
      ]
      }' "https://graph.facebook.com/v8.0/me/messenger_profile?access_token=<access_token>"

      Add persistent menu

      curl -X POST -H "Content-Type: application/json" -d '{
         "persistent_menu":[
            {
               "locale":"default",
               "composer_input_disabled":false,
               "call_to_actions":[
                  {
                     "title":"About us",
                     "type":"postback",
                     "payload":"ABOUT_US_PAYLOAD"
                  },
                  {
                     "title":"Contact",
                     "type":"postback",
                     "payload":"CONTACT_PAYLOAD"
                  },
                  {
                     "type":"web_url",
                     "title":"💻 Visit my Website",
                     "url":"http://misite.com/",
                     "webview_height_ratio":"full"
                  }
               ]
            }
         ]
      }' "https://graph.facebook.com/v8.0/me/messenger_profile?access_token=<access_token>"

      Remove persistent menu

      curl -X DELETE -H "Content-Type: application/json" -d '{
          "fields":[
               "persistent_menu"
          ]
      }' "https://graph.facebook.com/v8.0/me/messenger_profile?access_token=<access_token>"

    🙌 End of configuration

    We have finished configuring the app so that Facebook connects to the bot’s server, now we have to test it, to do this we can enter the chat page and perform a test to verify that everything is working properly.

    📡 How to share your bot

    Add a chat button to your webpage, go here to learn how to add a chat button your page.

    🔗 Create a shortlink

    You can use page username to have someone start a chat.

    https://m.me/<PAGE_USERNAME>
    

    📱 Setup the Workplace App

    The configuration of the app for Workplace is quite similar to that of Facebook, it is required to have the Workplace paid account in order to enable custom integrations.

    1. Go to the Administrator Panel, and click on the Integrations button, and in the Custom integrations section click on the Create custom integration button.

      It will open a modal where we must write the name of the application and a description, then click on Create.

      Settings new app on workplace 1

    2. Once the application is created, it takes us to the configuration page of the application.

      Settings new app on workplace 2

      Access token

      Now we are going to generate an access token and then configure it in our config, as mentioned in the configuration of the Facebook app.

      Settings new app on workplace 3

    3. Now let’s select the permissions for our bot.

      Permissions

      In our case we are interested in the option of Sending a message to any member.

      Settings new app on workplace 4

    4. Now we are going to grant the integration access to groups, in this case it is going to be to a specific group.

    Settings new app on workplace 5

    1. And finally, we have to configure the Webhook and the verify token and select the subscriptions we need, as we did with the Facebook app.

      Settings new app on workplace 6

      💬 Note: depending on the webhook configuration you select in the tabs, the subscriptions will change.

    2. 🙌 Finally we click on the save button.

      💬 Note: there is an optional configuration which is the security one, where it is required to enter the ip of the bot’s server, the domain, etc.

      Settings new app on workplace 7

    🔐 Security Configuration

    To give more security to the application, both for Facebook and Workplace, it is important to have completed the environment variable appSecret and have set true the requireProof for the bot to work properly with these new settings.

    {
      ...
      "params": {
        "appSecret": "<app_secret_key>",
        ...    
        "requireProof": true
      }
      ...
    }

    For both cases, it is required to have the public IP of the server, since that way, it will only be limited to receive and send requests from a single authorized server.

    If you have more than one public IP, or another server to balance the bot’s requests, you can add it to the list.

    Facebook App

    In the configuration of the app, we go to the left side menu and go to Settings > Advanced, and then down to the Security section, where we will enter our public IP, and then we will activate the option Require secret key of the app.

    Settings new app on facebook 8

    Workplace App

    In the configuration of the app, we go down to the Security Settings section, where we will activate the option to require a secret key test of the app, and then we will enter our public IP.

    Settings new app on workplace 8

    🤦‍♂️Troubleshooting

    Workplace App

    ❌ (#200) To subscribe to the messages field

    (#200) To subscribe to the messages field, one of these permissions is needed: pages_messaging. To subscribe to the messaging_postbacks field, one of these permissions is needed: pages_messaging

    You can solve this problem by configuring the webhook without selecting the subscriptions, then saving the configuration, then re-entering the app configuration and re-validating the webhook with the selected subscriptions.

    💡 Contributing

    Requests are welcome. For important changes, please open a topic first to discuss what you would like to change.

    Please be sure to update the tests and documentation as appropriate.

    👨‍💻 Author

    badge

    📜 License MIT

    Visit original content creator repository https://github.com/rudemex/fb-messenger-bot