• This is Slide 1 Title

    This is slide 1 description. Go to Edit HTML and replace these sentences with your own words. This is a Blogger template by Lasantha - PremiumBloggerTemplates.com...

  • This is Slide 2 Title

    This is slide 2 description. Go to Edit HTML and replace these sentences with your own words. This is a Blogger template by Lasantha - PremiumBloggerTemplates.com...

  • This is Slide 3 Title

    This is slide 3 description. Go to Edit HTML and replace these sentences with your own words. This is a Blogger template by Lasantha - PremiumBloggerTemplates.com...

Thứ Bảy, 22 tháng 1, 2022

Gửi tin nhắn trong group Telegram thông qua Bot API

 Bài viết hướng dẫn gửi thông báo vào group Telegram thông qua Bot API. các phần của bài viết

1. Tạo Bot Telegram

2. Tạo Group Telegram , ad bot và test gửi tin nhắn

3. Tạo API resfull với .net core và test bằng postman

I. TẠO BOT TRÊN TELEGRAM

Bước 1: Tìm BotFather tại ô tìm kiếm (Chú ý cái có tic xanh nhé)

Tìm BotFather

Bước 2: CLick "Start" để bắt đầu tạo Bot

Lệnh trên Bot

 - /newbot: Chọn tên cho Bot của bạn -> Chọn username cho Bot của bạn (Chú ý phải kết thúc bằng chữ "bot"
- Sau khi tạo xong Bot sẽ gửi cho bạn một Token, nhớ lưu lại để dùng gửi tin nhắn nhé.

Token mà bot gửi về


II. TẠO GROUP TELEGRAM - ADD BOT VÀ TEST
Bước 1: Tạo Group Telegram và add bot và group, chú ý coi chừng add nhằm bot nhé =))

Tạo group chat với Bot.


Bước 2 : Test thông báo 

 1. Lấy ID Bot và các group chat: https://api.telegram.org/bot<Token>/getUpdates 
(Chạy trên trình duyệt hoặc Postman đều đc nhé)
    
ID của Bot chat
ID của group chat

 2. Kiểm tra message trên Bot: https://api.telegram.org/bot<Token>/sendMessage?chat_id=<ID Chat>&text=<Message> (Chạy trên trình duyệt hoặc Postman đều đc nhé)
Thông báo trên bot

Thông báo trên group đã add bot


III. TẠO RESFUL API TRÊN .NET CORE 
  Bước 1: Tạo mới một project: API .Net Core



Bước 2: Tạo mới 1 Controller và test trên postman xem ok ko.
Bước 3: Tạo model chưa body Json và tạo 1 hàm post như bên dưới



Bước 4: test lại trên postman.



















Chủ Nhật, 11 tháng 7, 2021

Tạo SSL cho domain

 1. Mua SSL tại muassl.com

2. Sau khi thanh toán và active 

3. tải file certificate.cert và file key về (hoặc tải hết các file về)

4. tạo file pfx: https://kb.pavietnam.vn/tao-file-pfx-de-import-vao-iis.html

5. inport file pfx vào certificate  (import bằng pfx mới ko bị mất, chọn complete request... sẽ bị mất) Hoặc một số đơn vị đã có file .pfx sẵn rồi thì các bạn chỉ cần import vào là được.


6. vào bindding domain để chỉnh lại ssl

Thứ Năm, 15 tháng 10, 2020

Restorem database vào một database khác

 Mục dịch là save một Database cũ vào một Database mới , với tên khác, tên log và mdf khác luôn.

1. Backup database muốn restore

2. Vào Restore database với 

  - Option: Overwrite the existing database (WITH REPLACE)

  - Files: Chỗ Restore As chọn tới file mdf và .ldf mới mà bạn muốn thay thế.



Error when build IOS ionic - Upload IOS to Appstore by xcrun


I. Upload IOS to App Store by xcrun
1. Generate .ipa file with signed. 
    Product -> archive

2. move to ipa folder

3. check ipa file

xcrun altool --validate-app --file "$IPA_PATH" --username "$APP_STORE_USERNAME" --password "sjjkh-asjdkh-asjkdh"


password: get from appleid.apple.com/account/manage

APP-SPECIFIC PASSWORD (one time pass)

4. Upload file
xcrun altool --upload-app --file "$IPA_PATH" --username "$APP_STORE_USERNAME" --password "sjjkh-asjdkh-asjkdh" --verbose

ex: xcrun altool --upload-app --file "Citypost2020.ipa" --username "techhub@citypost.com.vn" --password "isub-wxzt-aqvs-apav" --verbose


II. Error when build IOS ionic
1. Install cordova-res when you get error
sudo npm i -g cordova-res --unsafe-perm

2. Error when run emulate or device

sudo npm install @ionic/app-script@latest --save-dev 

3. Error node-sass

npm rebuild node-sass 

4. Error when take picture "Thread 5: signal SAGABRT" and location: Edit info plist

go to TARGET -> Info -> add (+) key -value

Privacy - Camera Usage Description : Chụp ảnh báo phát

Privacy - Location Always Usage Description : Định vị báo phát

Privacy - Location When In Use Usage Description Định vị báo phát

Info Plist

4. Error when take picture "Thread 5: signal SAGABRT" and location: Edit info plist






Thứ Tư, 14 tháng 10, 2020

No version of NDK matched the requested version

Lỗi NDK : No version of NDK matched the requested version 21.0.6113669. Versions available locally: 21.3.6528147

Cập nhật lại NDK version cho đúng:
Trên adnroid studio: -> Tool -> SDK Manager -> Chuyển qua tab SDK tooks -> check vào NDK (Side by side) để update lên bản mới nhất.

Nếu vẫn không được vào đây tải bản phù hợp: https://androidsdkoffline.blogspot.com/p/android-ndk.html

sau đỏ bỏ vào: C:\Users\"Username"\AppData\Local\Android\Sdk\ndk\

Thứ Ba, 29 tháng 9, 2020

Validator Form In Angular

Have 2 ways validate form in angular.

First Way: Use FormBuilder

HTML file

 <form [formGroup]="angForm" novalidate>

<div class="form-group"> <label class="center-block">Name: <input class="form-control" formControlName="name"> </label> </div> <div *ngIf="angForm.controls['name'].invalid && (angForm.controls['name'].dirty || angForm.controls['name'].touched)" class="alert alert-danger"> <div *ngIf="angForm.controls['name'].errors.required"> Name is required. </div> </div> </form> <p>Form value: {{ angForm.value | json }}</p> <p>Form status: {{ angForm.status | json }}</p>

TS file

import { FormGroup, FormBuilder, Validators } from '@angular/forms';
@Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'Angular Form Validation Tutorial'; angForm: FormGroup; constructor(private fb: FormBuilder) { this.createForm(); } createForm() { this.angForm = this.fb.group({ name: ['', Validators.required ] }); } }

Second Way: Use ngModel
Create model file class
    
export class ContactForm {
    constructor(
        public name: string,
        public email: string,
        public subject: string,
        public phone?: string,
        public content?: string
    ) { }
}

HTML File
<form (ngSubmit)="onSubmit()" #requestForm="ngForm" id="requestForm" name="requestForm">
    <div class="row">
        <div class="col-lg-6">
            <input class="form-control" type="text" name="name" value="" size="40" required minlength="2" appForbiddenName="admin"
            [(ngModel)]="model.name" #name="ngModel" #_name placeholder="(1) Họ tên *">
            
        </div>
        <div class="col-lg-6">
            <input class="form-control" type="email" name="email" #_email value="" size="40"
                aria-required="true" aria-invalid="false" placeholder="Email">
        </div>
        <div class="col-lg-6">
            <input class="form-control" type="text" name="subject" value="" size="40" required minlength="3" #_subject
                #subject="ngModel" [(ngModel)]="model.subject" aria-invalid="false" placeholder="(2) Tiêu đề *">
        </div>

        <div class="col-lg-6">
            <input class="form-control" type="text" name="phone" value="" size="40" required pattern="^\+?(?:[0-9]??).{5,14}[0-9]$" #_phone
                #phone="ngModel" [(ngModel)]="model.phone" aria-required="true" aria-invalid="false" placeholder="(3) Số điện thoại *">
        </div>
        <div class="col-xs-12">
            <textarea class="form-control" name="message" cols="40" rows="4" required #_message
            #message="ngModel" [(ngModel)]="model.content" aria-invalid="false" placeholder="(4) Nội dung bạn quan tâm *"></textarea>
        </div>
        <div class="col-xs-12">
            <input class="btn btn-primary" [disabled]="!requestForm.form.valid" type="submit" #submit_bt value="    Gửi    ">
        </div>
    </div>
</form>
<div>
    <p *ngIf="name.invalid && (name.dirty || name.touched)" class="alert alert-danger">
        <span *ngIf="name.errors.required">
            (1) Họ tên không được trống.
        </span>
        <span *ngIf="name.errors.minlength">
            (1) Tên ít nhất phải 2 ký tự.
        </span>
        <span *ngIf="name.errors.forbiddenName">
            (1) Tên bạn không thể là "admin".
        </span>
    </p>
    <p *ngIf="subject.invalid && (subject.dirty || subject.touched)" class="alert alert-danger">
        <span *ngIf="subject.errors.required">
            (2) Tiêu đề không được trống.
        </span>
        <span *ngIf="subject.errors.minlength">
            (2) Tiêu đề ít nhất phải 3 ký tự.
        </span>
    </p>
    <p *ngIf="phone.invalid && (phone.dirty || phone.touched)" class="alert alert-danger">
        <span *ngIf="phone.errors.required">
            (3) Số điện thoại không được trống.
        </span>
        <span *ngIf="phone.errors.pattern">
            (3) Điện thoại không đúng định dạng.
        </span>
    </p>
    <p *ngIf="message.invalid && (message.dirty || message.touched)" class="alert alert-danger">
        <span *ngIf="message.errors.required">
            (4) Nội dung không được trống.
        </span>
    </p>
</div>

TS File

import { Contact } from '../../Class/contact';
model = new Contact('','','','','');
  @ViewChild('_name', {static: true}) name: ElementRef;
  @ViewChild('_subject', {static: true}) subject: ElementRef;
  @ViewChild('_phone', {static: true}) phone: ElementRef;
  @ViewChild('_email', {static: true}) email:ElementRef;
  @ViewChild('_message', {static: true}) message: ElementRef;
  // @ViewChild('submit_bt',{static: true}) submit_bt: ElementRef;
  async onSubmit(){
    let _name = this.name.nativeElement.value;
    let _subject = this.subject.nativeElement.value;
    let _phone = this.phone.nativeElement.value;
    let _email = this.email.nativeElement.value;
    let _message = this.message.nativeElement.value;
    alert(_name + " - " + _subject + " - " + _phone + " - " + _email + " - " + _message)
  }

Không cần khai báo trong ts file, nhưng muốn lấy giá trị form cần dùng @ViewChild('Name',{static:true}) name:ElementRef;

Thứ Năm, 16 tháng 7, 2020

Upload file in node js / Upload file bẳng nodejs

Các bước để tạo một API server bằng node js thì mình không làm nữa, chỉ bắt đầu bằng việc up ảnh

Bước 1: Tạo service upload ảnh

const multer = require('multer') // import library
const moment = require('moment')
const q = require('q')
const _ = require('underscore')
var file = require('file-system');
const fs = require('fs')
const dir = './public'
let sub = moment(moment.now()).format('YYYY-MM');
/** Store file on local folder */
let storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, 'public/' + sub)
    },
    filename: function (req, file, cb) {
        let date = moment(moment.now()).format('YYYYMMDDHHMMSS')
        cb(null, date + '_' + file.originalname.replace(/-/g, '_').replace(/ /g, '_'))
    }
})

/** Upload files  */
let upload = multer({ storage: storage }).array('files')

/** Exports fileUpload function */
module.exports = {
    fileUpload: function (req, res) {
        let deferred = q.defer()
        /** Create dir if not exist */
        if (!fs.existsSync(dir + "/" +sub)) {
            fs.mkdirSync(dir + "/" + sub)
            console.log(`\n\n ${dir} dose not exist, hence created \n\n`)
            
        }

        upload(req, res, function (err) {
            if (req && (_.isEmpty(req.files))) {
                deferred.resolve({ status: 200, message: 'File not attached', data: [] })
            } else {
                if (err) {
                    deferred.reject({ status: 400, message: 'error', data: err })
                } else {
                    deferred.resolve({
                        status: 200,
                        message: 'File attached',
                        filename: _.pluck(req.files,
                            'filename'),
                        data: req.files
                    })
                }
            }
        })
        return deferred.promise
    }
}

Bước 2: Tạo route API về controller : fileUploadController.js

var fileUploadService = require('../services/fileUploadService');

function fileUploadController() {

    // var fileUploadService = _fileUploadService();
    
    async function uploadFile(req, res) {
        fileUploadService.fileUpload(req, res)
            .then(fileUploadServiceResponse => {
                res.status(200).send(fileUploadServiceResponse)
            })
            .catch(error => {
                res.status(400).send(error)
            })
    }

    // async function uploadFile(req, res, next) {
    //     console.log(req);
    //     if(req.file == null){
    //         return res.send("Không Có hình")
    //     } else {
    //         return res.send("Có hình")
    //     }
    // }

    return {
        uploadFile: uploadFile
    }
}

module.exports = fileUploadController;

Bước 3: Check lại với postman




Load css another page when you got a conflict / Load css cho admin

loadStyle() {
    this.document.getElementsByTagName('head')[0].innerHTML+='<link rel="stylesheet" 
href="../assets/admin/dist/css/adminlte.min.css">';
  }

ngOnInit() {
    // if (localStorage.getItem('unserInfo') == null){
    //   this.router.navigate(['login']);
    // }
    this.loadStyle();
  }

Thứ Ba, 4 tháng 2, 2020

Một số command line cần thiết khi sử dụng Angular CLI

- ng 
   - g : Tự động tạo
   - c : component
   - m : module
   - s : service
Các option
--save : lưu vào package.json
--flat : Không tạo thư mục
--spec false: không tạo file spect.ts
-it : Không tạo file html
-is: Không tạo file css

Các Lỗi khi build API Node JS

1. Lỗi không thể connect đến MSSQLSERVER:
onnectionError: Failed to connect to localhost\MSSQLSERVER in 15000ms
    at ConnectionError (D:\APINode\node_modules\tedious\lib\errors.js:13:12)
    at Connection.connectTimeout (D:\APINode\node_modules\tedious\lib\connection.js:1190:54)
    at Timeout._onTimeout (D:\APINode\node_modules\tedious\lib\connection.js:1152:12)

=> Chưa bật SQL Server Browser

  •   Mở Services.msc → tìm SQL Server Browser → Property → Automatic → start

Thứ Hai, 3 tháng 2, 2020

Cách xử lý khi bị đụng css, load css từ cho 1 compnent

- Khi bạn muôn apply một external css cho riêng 1 component , (load từ style.css sẽ bị đụng css), thì làm như sau:
styleUrls: ['./index.component.css','../../assets/admin/dist/css/adminlte.min.css'],
encapsulation: ViewEncapsulation.None

Thứ Hai, 20 tháng 1, 2020

Các gói npm cần thiết khi sử dụng NodeJS



  • Nodemon: tự động restart lại server nodejs 
  • Tedious: Connect với mssql (Giống mssql-npm)
  • Express: frameword cho nodeJS - Giống Hapi
  • Sails: Fulltack FrameWord cho nodejs (cái này hay nè)
  • Sequilize: ORM dùng để mapping CSDL 
  • ejs: view template 
  • date-format: định dạng ngày tháng năm (Chú ý nếu cần định dạng về UTC +7 thì cần cấu hình lại trong file config hoặc connect : timezone: '+07:00',
  • dotenv: sử dụng biên môi trường .env
  • perfect-logger: Lưu log thành file .log


Sử dụng EJS làm view cho node JS

Các bước cấu hình
1. Cài đặt các gói cần thiết
#npm install --save ejs
#npm install --save bootstrap
#npm install --save jquery
#npm install --save popper

2. Tạo 1 thư mục views
- Folder: include : chưa cái file được xử dụng lại như : header, footer. nav
- 2 file: index.ejs, about.ejs
index.ejs
<!DOCTYPE html>
<html lang="en">
    <% include ('./include/head') %>
    <body>
        <% include ('./include/nav')  %>
        <div class="container">
            <div class="row">
                <h1>Home</h1>
            </div>
            <hr>
            <div class="row">
                <p style="height:300px;">Content Here...</p>
            </div>
        </div>

        <% include ('./include/scripts') %>
        <% include ('./include/footer') %>
        
    </body>
</html>
about.ejs
<!DOCTYPE html>
<html lang="en">
    <% include ('./include/head') %>
    <body>
        <% include ('./include/nav') %>
        <div class="container">
            <div class="row">
                <h1>About</h1>
            </div>
            <hr>
            <div class="row">
                <p style="height:300px;">Content Here...</p>
            </div>
        </div>

        <% include ('./include/scripts')  %>
        <% include ('./include/footer') %>
    </body>
</html>

Cầu hình app.js , do ở đây mình sử dụng chung để viết API nên sẽ cấu hình hơi khác.
const express = require('express')
const bodyParser = require('body-parser');
const path = require('path');

const app = express()

var port = process.env.HOST_PORT || 3300;

// Require static assets from public folder--------------------------- EJS
app.use(express.static(path.join(__dirname, 'public')));

// Set 'views' directory for any views 
// being rendered res.render()
app.set('views', path.join(__dirname, 'views'));

// Set view engine as EJS
app.engine('html', require('ejs').renderFile);
app.set('view engine', 'ejs');

//-------------------------------------------------------END EJS config

app.listen(port, () => {
    console.log("This port: " + port + " is running");
});

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

var router = require('./routes')();
app.use('/', router);
 
//CORS Middleware
app.use(function (req, res, next) {
    //Enabling CORS 
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, contentType,Content-Type, Accept, Authorization");
    next();
});

Tạo 1 file route.js
- Ở đây mình có require 2 file route, 1 cái của API , 1 cái của view. (API sẽ trình bày trong bày khác
const express = require('express'); 

function eRoutes() {
    const router = express.Router();
    //var employee = require('./repository/employee/employee.routes')(router);
    //var department = require('./repository/department/department.routes')(router);
    var user = require('./routes/user.routes')(router);
    var view = require('./routes/view.routes')(router);
    return router;
}

module.exports = eRoutes;

Tạo 1 thư mục route, để chưa file route
Tạo 1 file view.route.js trong thư mục route

const express = require('express');

module.exports = function (router) {
    router.get('/', (req, res) => {
        console.log('Request for home recieved');
        res.render('index');
    });

    router.get('/about', (req, res) => {
        console.log('Request for about page recieved');
        res.render('about');
    });

    router.get('/contact', (req, res) => {
        console.log('Request for contact page recieved');
        res.render('contact');
    });
}

Ok con dê: